[한셀/엑셀] N번째 VLOOKUP하기

본 글에서 사용한 코드는 오빠두엑셀님의 글을 참고해 작성했습니다. + 본 글은 개발자 시점에서 작성된 글입니다.

요약


배열 함수 설명

배열 함수는 일반 함수와 달리 배열 안에 있는 값을 연산한다. 배열 함수는 Ctrl + Shift + Enter를 통해 입력하며, { }로 감싸진 형태로 표시된다.

가격 보유 개수
3000 5
2000 4
7000 6

만약 위 표에서 총가격을 구하는 문제를 풀어보자. 일반 함수는 아래와 같이 문제를 해결한다.

3000 5 = A1 * B1
2000 4 = A2 * B2
7000 6 = A3 * B3
    = SUM(C1:C3)

가격과 개수를 곱한 후 모두 더한다. 그런데 배열 함수를 사용하면 아래와 같이 표현할 수 있다.

3000 5
2000 4
7000 6
{ = SUM(A1:A3 * B1:B3) }

배열 함수 안에서 "A1:A3 * B1:B3"는 { A1*B1, A2*B2, A3*B3 }라는 배열이 된다. 따라서 SUM을 이용해 배열 값을 모두 더하면 총가격을 구할 수 있다. 이를 이용해 N번째를 VLOOKUP 하는 문제를 풀어보자.


문제 정의

  • 문제: 아래 표에서 3번째 301을 찾으시오.
  • 답: D
key value
301 A
302 B
301 C
301 D
303 E

301을 key로 가지는 값은 A, C, D가 있다. 이 중 3번째 301은 D이다.


문제 해결

아이디어의 핵심은 인덱스를 찾는 것이다. 과정을 코드로 정리해보면 아래와 같다.

'0. 문제 조건
keys = {301, 302, 301, 301, 303}
values = {"A", "B", "C", "D", "E"}
targetKey = 301 '찾는 값
n = 3 'N번째

'1. 1부터 시작해 모든 key-value에 대해 index 배열을 생성한다.
indexArray = {1, 2, 3, 4, 5} 

'2. key가 조건에 만족하는 경우만 필터링한다.
'filteredArray: {1, FALSE, 3, 4, FALSE}
filteredArray = IF(targetKey=keys, indexArray)

'3. 필터링된 index 중 N번째 값을 가져온다.
'targetIndex: 4
targetIndex = SMALL(filteredArray, n)

'4. 전체 value에서 index를 이용해 값을 가져온다.
targetValue = INDEX(values, targetIndex)

index 배열 생성

ROW를 이용해 1부터 배열을 생성한다. 이는 value 인덱스를 의미한다.

'ROW(셀) -> 행 번호
{ =ROW("value 범위") - ROW("첫 value 셀") + 1 }

ROW는 행 번호를 반환하기 때문에 값이 1부터 시작하지 않을 수 있다. 따라서 배열 첫 값으로 빼주면 0부터 시작하는 배열이 생성된다. 여기서 모든 값에 1을 더해주면 1부터 시작하는 배열을 만들 수 있다. 계산 과정을 자세히 살펴보면 아래 표와 같다.

{ = ROW(B2:B6) } { 2, 3, 4, 5, 6 }
= ROW(B2) 2
{ = ROW(B2:B6) - ROW(B2) } { 0, 1, 2, 3, 4 }
{ = ROW(B2:B6) - ROW(B2) + 1 } { 1, 2, 3, 4, 5 }

조건 필터링하기

배열을 입력 받아 조건을 만족하는 값만 남겨둔다. Python이나 Js의 filter과 비슷하다.

'IF(조건절, 필터링할 배열)
{ =IF("찾는 key" = "key 전체", "index 배열") }
key 전체 301 302 301 301 303
조건절 결과 TRUE FALSE TRUE TRUE FALSE
index 배열 1 2 3 4 5
함수 결과 1 FALSE 3 4 FALSE

이렇게 하면 조건에 맞는 값의 index만 남게 된다.

N번째 index 찾기

조건을 만족하는 값의 index만 남았다. 여기서 n번째 작은 값을 찾으면 n번째에 있는 값의 index를 얻을 수 있다.

'SMALL(배열, n) -> 배열에서 n번째 작은 값
{ =SMALL("필터링된 배열", N) }
배열 { 1, 3, 4 }
= SMALL(배열, 2) 3
= SMALL(배열, 3) 4

드디어 결과 값의 index를 찾았다.

결과 값 불러오기

INDEX 함수는 범위에서 N번째 값을 가져온다.

'INDEX(찾을 범위, N) -> N번째 값
{ =INDEX("value 범위", "찾는 값 index") }