여러분은 이 변수의 이름을 여러분이 사용하고 있는 워크시트의 이름으로 변경할 수 있습니다.
다음 데이터를 살펴 보도록 하겠습니다.
' 이 Sub를 사용하여 데이터를 생성합니다.Sub GenerateData()' Change the sheet name as requiredWith ThisWorkbook.Worksheets("Sheet1").Range("A1").CurrentRegion.ClearContents.Range("A1:A7").Value = WorksheetFunction.Transpose(Array("과일", "사과", "살구", "오렌지", "복숭아", "배", "자두")).Range("B1:B7").Value = WorksheetFunction.Transpose(Array("가격", 1500, 2300, 1450, 2200, 1600, 1200))End WithEnd Sub
아래 예제 코드는 배의 가격 1600을 반환합니다.
Sub SimpleVLookup()Dim sRes As String' sRes = Application.VLookup("배",shData.Range("A2:B7"),2)sRes = Application.VLookup("배", shData.Range("A2:B7"), 2, False)' This will print 1600 to the Immediate Window(Ctrl + G)Debug.Print sResEnd Sub
NOTE : 원문에서는 맨 마지막 선택인자를 지정하지 않았지만 실제 예제를 실행했을 때
네 번째 선택인자에 False를 지정하지 않는 경우
'13' 런타임 오류가 발생하였습니다: 형식이 일치하지 않습니다. 오류가 발생한다.
이유는 네 번째 인자를 명시적으로 지정하지 않으면 True. 즉, '유사 일치;로써 가장 가까운
일치항목을 검색하는데, 이는 첫번째 열이 알파벳 또는 숫자순 오름차순으로 정렬된다고 가정한다.
하지만 예제에서는 한글을 사용하고 오름차순이 아니었기 때문에 이와 같은 오류를 발생 시켰다.
알파벳의 경우 오름차순 정렬이 아니더라도 오류는 발생시키지 않았다.
위 코드는 A2:B7 범위에서 텍스트 "배"를 찾습니다. 지정된 텍스트를 찾으면
VLookup함수의 세번째 인자로 지정된 열(위 예에서는 2)에서 텍스트와 동일한 행의 값을 반환합니다.
몇가지 예와 결과를 좀더 살펴 보겠습니다.
' 1450 반환sRes = Application.VLookup("오렌지", shData.Range("A2:B7"), 2, False)Debug.Print sRes' 1500 반환sRes = Application.VLookup("사과", shData.Range("A2:B7"), 2, False)Debug.Print sRes' 1200 반환sRes = Application.VLookup("자두", shData.Range("A2:B7"), 2, False)Debug.Print sRes' 열이 1일 때 오렌지를 반환sRes = Application.VLookup("오렌지", shData.Range("A2:B7"), 1, False)Debug.Print sRes' 열이 1일 때 사과를 반환sRes = Application.VLookup("사과", shData.Range("A2:B7"), 1, False)Debug.Print sRes' 열이 1일 때 자두를 반환sRes = Application.VLookup("자두", shData.Range("A2:B7"), 1, False)Debug.Print sRes
lookup_value : 조회하려는 값으로서, 조회 값이라고도 합니다. 범위의 첫번째 열에 있어야 합니다.
table_array : 조회 값이 있는 범위입니다.
조회 값은 항상 조회 범위에서 첫 번째 열에 있어야 한다는 것을 주의하십시오.
예를 들어, 조회 값이 A2 셀에 있다면 범위는 A로 시작해야 합니다.
col_index_num : 반환 값이 포함된 범위에 있는 열 번호입니다.
예를 들어 A2:B7 을 범위로 지정하는 경우 A를 첫 번째 열로, B를 두 번째 열로 계산해야 합니다.
range_lookup(선택 사항) : 유사 일치가 필요하면 TRUE를 지정하고,
반환 값의 정확한 일치가 필요하면 FALSE를 지정할 수 있습니다. 항목을 지정하지 않으면,
기본값은 항상 TRUE, 즉 유사 일치 입니다. True를 사용하면 첫 번째 열이 알파벳 또는 숫자순으로 정렬된다고 가정하므로
한글을 사용하는 경우 FALSE를 명시적으로 지정해주어야 한다.
매개변수 1 : lookup_value
이것은 여러분이 찾고 있는 값입니다. 이 값을 지정해줄때 명심해야 하는 것은,
항상 조회 범위의 첫번째 열에 있는 값이어야 한다는 것입니다.
예를 들어 C4:X10 범위를 사용하는 경우 조회 값은 C열에 있는 값이어야만 합니다.
Z1:AB5의 경우 Z열에 있어야 합니다.
Sub StringVLookup()Dim sFruit As StringsFruit = "자두"Dim sRes As VariantsRes = Application.VLookup(sFruit, shData.Range("A2:B7"), 2, False)End Sub
일반적으로 검색하는 값의 타입은 문자열을 많이 사용합니다.
물론 번호를 이용하여 검색할 수도 있지만 주의해야 할 사항이 있습니다.
숫자가 텍스트로 저장된 경우 검색 값은 문자열이어야 합니다.
숫자가 숫자로 저장된 경우 검색값은 숫자여야 합니다.
예를 들어 아래의 데이터에는 조회열의 타입이 숫자로 되어 있습니다.
이 경우 조회 값은 long이어야 하며 그렇지 않으면 오류가 발생합니다.
Sub NumberVLookup()Dim num As Longnum = 7Dim sRes As VariantsRes = Application.VLookup(num, shData.Range("F2:G7"), 2, True)Debug.Print sResEnd Sub
이와 같이 날짜를 Long 타입으로 변경한 후에 그것을 이용해 VLookup함수에서 정상적으로 사용할 수 있습니다.
Sub DateVLookup()
Dim theDate As LongtheDate = CLng(#1/14/2017#)Dim sRes As VariantsRes = Application.VLookup( _theDate, shData.Range("I2:J7"), 2, False)Debug.Print sResEnd Sub
매개변수 2 : table_array
이 매개변수는 찾고있는 데이터의 범위를 나타냅니다.
지금까지 예에서 본것처럼 일반적으로 Range를 사용합니다.
만일 워크시트 테이블을 사용하는 경우 테이블의 범위를 사용할 수 있습니다.
Sub SimpleVLookupTable()Dim sRes As Variant' Get the tableDim table As ListObjectSet table = shData.ListObjects("Table1")' Use the table for the table_array parametersRes = Application.VLookup("자두", table.Range, 2, False)Debug.Print sResEnd Sub
만일 일치 옵션이 True(유사 일치)이고 참조 범위 첫번째 열에서 정확히 일치하는 값이 없는 경우,
찾을 값보다 작거나 같은 값 중 최대값을 반환 합니다. 만일 찾을 값이 참조 범위의 최소값 보다도 작아 반활할 값이 없는 경우
VLookup함수는 #N/A 오류를 반환 합니다.
테스트의 편의를 위해 앞에서 다루었던 샘플데이터를 영어로 변경해서 다시 살펴 보도록하겠습니다.
Sub SimpleVLookup()Dim rg As RangeSet rg = shData.Range("A2:B7")Dim sRes As Variant' 일치하는 값이 없으므로 찾을 값 'P' 보다 작은 값중 가장 큰 Orange를 리턴한다.sRes = Application.VLookup("P", rg, 2, True)Debug.Print sRes' 일치하는 값이 없으므로 찾을 값 'Pea' 보다 작은 값중 가장 큰 Orange를 리턴한다.sRes = Application.VLookup("Pea", rg, 2, True)Debug.Print sRes' 유사 일치를 찾지 못했으므로 'Pea'까지 성공하고 가장 큰 값인 Peach를 리턴한다.sRes = Application.VLookup("Pead", rg, 2, True)Debug.Print sRes' 유사일치를 사용하지 않으므로 찾지 못함 에러를 리턴한다(오류 2042)sRes = Application.VLookup("Pea", rg, 2, False)Debug.Print sResEnd Sub
Sub UseWorksheetFunction()Dim sRes As Variant' Turn on error trappingOn Error Resume NextErr.ClearsRes = Application.WorksheetFunction.VLookup("Plum", shData.Range("A2:B7"), 2, False)' 값이 있는지 확인If Err.Number = 0 ThenDebug.Print "찾은 아이템 값은 " & sResElseDebug.Print "값을 찾을 수 없음 " & "Plum"End IfEnd Sub
Application 사용하기
Application.VLookup은 간단하게 반환값을 확인함으로써 오류를 체크할 수 있습니다.
ub UsingApplication()Dim sRes As VariantsRes = Application.VLookup("Plum", shData.Range("A2:B7"), 2, False)' Check if value foundIf IsError(sRes) = False ThenDebug.Print "Found item. The value is " & sResElseDebug.Print "Could not find value: " & "Plum"End IfEnd Sub
VLookup 에러 타입
아래 표는 Application.VLookup을 사용할 때 발생 할 수 있는 오류 코드입니다.
Constant
에러 코드
에러 값
xlErrDiv0
2007
#DIV/0
xlErrNA
2042
#N/A
xlErrName
2029
#NAME?
xlErrNull
2000
#NULL!
xlErrNum
2036
#NUM!
xlErrRef
2023
#REF!
xlErrValue
2015
#VALUE!
오류와 원인
다음 표는 VLookup에서 발생할 수 있는 몇가지 일반적인 오류를 보여 줍니다.
특정 VLookup오류에 문제가 있는 경우 먼저 엑셀에서 테스트 해보는것이 좋습니다.
Error
Cell
이유
Error 2015
#VALUE!
열 번호가 1보다 작음
Error 2015
#VALUE!
table_array의 인자로 범위 대신 문자열을 사용했음.
Error 2023
#REF!
열 번호가 열 수보다 큼
Error 2042
#N/A
값을 찾을 수 없음
만일 값을 찾을 수 없다는 오류가 발생하는 경우 다음을 확인해 보세요.
테이블 또는 참조범위가 올바른지 확인하세요.
테이블 또는 참조범위에 헤더가 포함되어있는지 확인하세요(VBA는 이것을 정렬되지 않은 데이터라고 간주합니다)
테이블 또는 참조범위가 올바를 워크시트인지 확인하세요.
숫자를 검색하는 경우 lookup_value매개 변수에서 long 또는 double 데이터 유형을 사용하십시오.
텍스트로 저장된 숫자를 검색하는 경우 lookup_value 매개변수에 문자열 데이터 타입을 사용하십시오.
날짜를 검색하는 경우 lookup_value 매개변수에서 long(앞의 날짜 타입 참조)으로 변환해야 합니다.
만일 값을 찾기는 하는데 잘못된 값을 얻고 있다면 네번째 range_lookup 인자가 True이거나 사용되지 않은 경우
첫 번째 열이 알파벳순 또는 숫자순으로 오름차순 정렬되어 있는지 확인합니다.
VLookup 속도 향상
큰 범위에 대해 VLookup를 사용해야 하는 경우 너무 느려 성능 문제가 발생할 수 있습니다.
이 경우 VBA Dictionary를 사용하는 것은 유용한 대안이 될 수 있습니다.
Sub UseDictionary()' Get the range of valuesDim rg As RangeSet rg = shData.Range("M1:N20000")' Create the dictionaryDim dict AsObjectSet dict = CreateObject("Scripting.Dictionary")' Fill the dictionaryDim cell As RangeForEach cell In rgdict(cell.Value) = cell.Offset(0, 1).ValueNext' Perform the LookupsForEach cell In rgDebug.Print dict(cell.Value)NextEndSub