AI 해결 노트 · 2026-09-18 · 실측 2026-09-18

VLOOKUP 조회가 어긋나는 자리 여섯 군데 — #N/A·#REF!·조용히 틀린 값

한 줄로

품목코드가 표에 분명히 있는데 #N/A가 뜹니다. 더미 단가표 6줄로 흔한 원인 여섯 가지를 따로 내 봤더니 값 끝의 공백·숫자와 글자 불일치·찾는 열의 위치·복사하면서 밀린 범위에서 #N/A가, 열 번호를 잘못 넣은 자리에서 #REF!가, 네 번째 인수를 뺀 자리에서는 오류 없이 엉뚱한 단가 900원이 나왔습니다. 오류가 안 뜬 이 마지막 하나가 제일 위험합니다.

증상

실측 환경

항목
OSWindows 11 Home (10.0.26200)
Excel16.0 (빌드 20326.0)
조작 방법Excel COM (Excel.Application, Visible=false) — 셀에 수식 문자열을 넣고 화면 값(.Text)을 읽음. 복사는 Range.Copy + PasteSpecial
시험 파일직접 만든 더미 X1_41_단가조회.xlsx, X1_41_보탬.xlsx, X1_41_보탬2.xlsx
로그원자료\excel-vlookup-na\01_vlookup_실행로그.txt, 02_png_렌더로그.txt, 03_보탬시험.txt, 04_보탬시험2.txt

더미 표

단가표 시트에 여섯 줄을 넣었습니다. 품목코드가 A열, 품명이 B열, 단가가 C열입니다.

품목코드품명단가
A-101볼펜1200
A-102노트3500
B-201파일2800
B-202집게900
C-301토너68000
C-302용지25000

사번 사례를 위해 사번표 시트도 만들었습니다. A열을 텍스트 서식으로 지정한 뒤 1001·1002·1003을 넣었으니, 엑셀은 이 사번들을 글자로 들고 있습니다.

여섯 가지를 한 화면에

①~⑤ 사례의 찾는 값·원래 결과·고친 결과·수식 원문
①~⑤ 사례의 찾는 값·원래 결과·고친 결과·수식 원문
사례찾는 값원래 수식화면 값고친 수식고친 값
① 뒤 공백A-102 =VLOOKUP(B2,단가표!$A$2:$C$7,3,FALSE)#N/A=VLOOKUP(TRIM(B2),단가표!$A$2:$C$7,3,FALSE)3500
② 숫자 vs 글자1002 (숫자)=VLOOKUP(B3,사번표!$A$2:$B$4,2,FALSE)#N/A=VLOOKUP(TEXT(B3,"0"),사번표!$A$2:$B$4,2,FALSE)김영수
③ 찾는 열이 첫 열 아님A-102=VLOOKUP(B4,단가표!$B$2:$C$7,2,FALSE)#N/A=VLOOKUP(B4,단가표!$A$2:$C$7,3,FALSE)3500
④ 열 번호가 범위 밖A-102=VLOOKUP(B5,단가표!$A$2:$C$7,4,FALSE)#REF!=VLOOKUP(B5,단가표!$A$2:$C$7,3,FALSE)3500
⑤ 네 번째 인수 생략B-203=VLOOKUP(B6,단가표!$A$2:$C$7,3)900=VLOOKUP(B6,단가표!$A$2:$C$7,3,FALSE)#N/A

⑥은 수식을 복사해야 나오는 것이라 아래에 따로 뒀습니다.

① 찾는 값 뒤에 공백 한 칸

A-102 를 찾으면 #N/A입니다. 화면으로는 A-102와 구별되지 않습니다. 공백을 어디에 붙였는지에 따라 고치는 방법도 달라져, 네 가지를 따로 넣어 봤습니다.

넣은 값그대로 VLOOKUPTRIM()TRIM(CLEAN())LENLEN(TRIM(CLEAN))COUNTIF
뒤 공백 ('A-102 ')#N/A35003500650
앞 공백 (' A-102')#N/A35003500650
가운데 공백 ('A- 102')#N/A#N/A#N/A660
줄바꿈이 붙음 ('A-102\n')#N/A#N/A3500650
깨끗한 값 ('A-102')350035003500551

앞뒤 공백은 TRIM으로 해결됩니다. 가운데 공백은 다릅니다. TRIM이 가운데를 어떻게 다루는지 네 가지를 더 넣어 봤습니다.

넣은 값LENLEN(TRIM)TRIM 결과TRIM 후 VLOOKUP공백을 전부 지운 뒤
'A- 102' (가운데 1칸)66A- 102#N/A3500
'A- 102' (가운데 2칸)76A- 102#N/A3500
'A- 102' (가운데 3칸)86A- 102#N/A3500
' A-102 ' (앞뒤 2칸씩)95A-10235003500

TRIM은 앞뒤 공백을 없애고 가운데 연속 공백은 한 칸으로 줄입니다. 한 칸짜리 가운데 공백은 그대로 남기 때문에 TRIM으로는 #N/A가 풀리지 않습니다. 가운데 공백까지 없애려면 SUBSTITUTE로 공백을 전부 지워야 합니다.

=VLOOKUP(SUBSTITUTE(A2," ",""),단가표!$A$2:$C$7,3,FALSE)

줄바꿈이 붙은 경우도 넣어 봤습니다. A-102 뒤에 줄바꿈(CHAR 10)을 붙였더니 TRIM으로는 지워지지 않았고, TRIM(CLEAN(…))을 씌워야 5글자가 됐습니다. 웹 화면이나 다른 시스템에서 복사해 온 값에서 볼 수 있는 모양입니다.

찾는 값이 A2에 있다면 이 세 줄로 진단합니다.

=LEN(A2)                    → 6
=LEN(TRIM(CLEAN(A2)))       → 5
=CODE(RIGHT(A2,1))          → 32

LEN이 다르면 TRIM이나 CLEAN이 걷어 내거나 줄여 놓은 글자가 있다는 뜻입니다. 위 표의 「가운데 2칸」처럼 글자가 지워진 게 아니라 줄어든 경우도 여기 걸립니다. CODE가 32면 맨 끝 글자가 공백, 10이면 줄바꿈입니다.

② 한쪽은 숫자, 한쪽은 글자

사번표의 1002는 텍스트 서식으로 넣은 글자이고, 주문표에 친 1002는 숫자입니다. 눈으로는 같은 1002인데 #N/A입니다. 반대 방향도 돌려 봤습니다.

표의 사번찾는 값ISTEXT그대로형을 맞춘 뒤
글자숫자 1002FALSE#N/ATEXT(…,"0")으로 글자로 → 김영수
숫자글자 1002TRUE#N/AVALUE(…)로 숫자로 → 김영수
숫자숫자 1002FALSE김영수

어느 쪽이 글자인지 보려면 찾는 값과 표의 값 양쪽에 ISNUMBERISTEXT를 넣어 자료형을 확인합니다. 방향에 따라 고치는 함수가 갈립니다. 표가 글자면 찾는 값을 TEXT(…,"0")으로, 표가 숫자면 찾는 값을 VALUE(…)로 맞춥니다.

앞자리 0이 있는 사번은 형만 맞춘다고 되지 않습니다. 표에 0123·0456·1002를 글자로 넣고, 앞의 0이 없는 숫자 123으로 찾아 봤습니다.

찾은 방법만들어진 값결과
숫자 123 그대로#N/A
TEXT(…,"0")123#N/A
TEXT(…,"0000")0123홍길동

TEXT(…,"0")은 이미 사라진 앞자리 0을 되살려 주지 않습니다. 자릿수가 정해져 있는 코드라면 "0000"처럼 자릿수를 적어 줘야 맞습니다. 애초에 이런 코드는 입력하는 칸을 텍스트 서식으로 잡아 두는 편이 낫습니다.

③ 찾는 열이 범위의 첫 열이 아님

VLOOKUP은 지정한 범위의 맨 왼쪽 열에서만 찾습니다. 범위를 단가표!$B$2:$C$7로 잡으면 맨 왼쪽은 품명(B열)이라, A-102라는 코드를 품명 목록에서 찾다가 #N/A를 냅니다. 범위를 A열부터 잡고 열 번호를 3으로 고치면 3500이 나옵니다.

표에서 코드가 오른쪽에, 찾아올 값이 왼쪽에 있는 배치라면, 그 범위를 그대로 지정한 VLOOKUP으로는 왼쪽 값을 가져올 수 없습니다. INDEX·MATCH를 쓰거나, 아래 XLOOKUP 쪽을 보십시오.

④ 열 번호가 범위 밖 — #N/A가 아니라 다른 오류

여기서만 #REF!가 나왔습니다. 오류 문구가 다르므로 원인을 가릴 때 쓸 수 있습니다. 같은 범위(2열짜리)에 열 번호만 바꿔 일곱 번 넣어 봤습니다.

열 번호화면 값
1A-102
23500
3#REF!
4#REF!
10#REF!
0#VALUE!
-1#VALUE!

#REF!를 봤다면 범위 안의 열 개수부터 세십시오. 열 번호는 1 이상이고 범위의 열 개수 이하여야 합니다. 0이나 음수를 넣으면 #VALUE!로 갈립니다.

처음 만들 때 맞던 수식이 나중에 #REF!로 바뀌는 일도 있습니다. 코드·품명·규격·단가 4열짜리 표에 =VLOOKUP("A-102",A2:D4,4,FALSE)를 넣어 3500을 받은 뒤, 규격 열(C열)을 지워 봤습니다.

지우기 전: =VLOOKUP("A-102",A2:D4,4,FALSE)  → 3500
C열 지운 뒤: =VLOOKUP("A-102",A2:C4,4,FALSE) → #REF!

범위는 3열로 줄었는데 열 번호 4는 그대로 남아 있습니다. 표에서 열을 지울 때는 그 표를 참조하는 수식의 열 번호도 같이 보셔야 합니다.

⑤ 네 번째 인수를 빼면 오류 없이 다른 품목 단가가 들어옵니다

=VLOOKUP(B6,단가표!$A$2:$C$7,3) 처럼 마지막 FALSE를 빼면 근사 일치로 동작합니다. 표에 없는 B-203을 찾았는데 오류 없이 900이 나왔습니다. B-202(집게) 단가입니다. 없는 코드를 조회했는데 앞 줄 품목의 단가가 조용히 들어앉은 셈입니다.

근사 일치는 표가 오름차순으로 정렬돼 있다는 전제 위에서 돕니다. 같은 값 여덟 개를 정렬된 표와 뒤죽박죽 표에 각각 넣어 비교해 봤습니다.

정렬된 표와 뒤죽박죽 표에서 근사 일치·정확 일치 결과 비교
정렬된 표와 뒤죽박죽 표에서 근사 일치·정확 일치 결과 비교
찾는 값정렬된 표·근사정렬된 표·정확뒤죽박죽 표·근사뒤죽박죽 표·정확
A-10112001200#N/A1200
A-10235003500#N/A3500
B-20128002800#N/A2800
B-202900900900900
C-3016800068000350068000
C-30225000250002500025000
B-203 (없는 코드)900#N/A3500#N/A
A-100 (없는 코드)#N/A#N/A#N/A#N/A

뒤죽박죽 표에서는 여덟 줄 가운데 다섯 줄이 틀렸습니다. 그중 C-301은 표에 멀쩡히 있는 코드인데 68000 대신 3500(노트 단가)이 들어왔습니다. 오류 표시가 없으니 검산하지 않으면 그대로 나갑니다. 정확히 맞는 것만 찾는 일이라면 네 번째 인수에 FALSE0을 반드시 적으십시오.

⑥ 범위를 $로 고정하지 않고 복사

첫 줄에 =VLOOKUP(A11,단가표!A2:C7,3,FALSE)를 넣고 아래 네 줄로 복사했습니다. 붙여넣은 줄마다 범위가 한 칸씩 내려가, 다섯 줄 중 두 줄이 #N/A가 됐습니다.

범위를 안 고정한 열과 $로 고정한 열의 결과 차이
범위를 안 고정한 열과 $로 고정한 열의 결과 차이
주문코드안 고정$ 고정복사된 뒤 실제 범위
C-3022500025000단가표!A2:C7
A-101#N/A1200단가표!A3:C8
B-20128002800단가표!A4:C9
C-3016800068000단가표!A5:C10
A-102#N/A3500단가표!A6:C11

밀려난 범위에서 우연히 찾는 값이 아직 안에 남아 있으면 정답이 나오고, 범위 위쪽으로 빠져나간 값은 #N/A가 됩니다. 세 줄이 멀쩡하니 표를 대충 훑으면 넘어가기 쉽습니다. #N/A 난 칸을 눌러 수식 줄의 범위가 첫 줄과 같은지 보는 것이 제일 빠른 확인입니다.

같은 잘못된 수식인데 아무 일도 안 일어나는 경우도 확인해 뒀습니다. 주문 순서를 단가표 순서와 똑같이 A-101부터 놓고 범위를 고정하지 않은 채 복사했더니, 다섯 줄 모두 정답이 나왔습니다.

주문코드결과복사된 뒤 실제 범위
A-1011200F2:G7
A-1023500F3:G8
B-2012800F4:G9
B-202900F5:G10
C-30168000F6:G11

범위가 줄마다 밀렸는데도 찾는 값이 그때마다 범위 첫 줄에 있어 다 맞았습니다. 값이 맞게 나왔다고 수식이 맞는 것은 아니라는 뜻입니다. 주문 순서가 바뀌어 찾는 코드가 밀려난 범위 밖으로 빠지면 그때 #N/A가 납니다.

두 번째 인수는 $A$2:$C$7처럼 행·열을 모두 고정합니다. $가 어디에 붙느냐에 따라 무엇이 고정되는지는 수식을 복사해도 기준 셀이 안 바뀌게에 값으로 비교해 두었습니다.

#N/A가 났을 때 무엇부터 보나

찾는 값이 A33에 있다고 할 때, 여덟 줄을 옆 칸에 넣어 봤습니다. A-102 (뒤 공백)를 넣은 결과입니다.

=COUNTIF(표!$A$2:$A$7,A33)              → 0
=COUNTIF(표!$A$2:$A$7,"*"&TRIM(A33)&"*") → 1
=LEN(A33)                                → 6
=LEN(TRIM(CLEAN(A33)))                   → 5
=CODE(RIGHT(A33,1))                      → 32
=EXACT(A33,표!$A$3)                      → FALSE
=ISNUMBER(A33)                           → FALSE
=IFNA(VLOOKUP(A33,표!$A$2:$B$7,2,FALSE),"코드없음") → 코드없음

뒤 공백 사례에서는 정확히 센 COUNTIF가 0, *로 감싼 부분 일치가 1이었습니다. 두 값이 이렇게 갈리면 표에 비슷한 값이 있다는 신호는 되지만, 부분 일치는 표 안의 더 긴 다른 코드에도 걸리므로 이것만으로 원인을 확정할 수는 없습니다. 순서로 정리하면 이렇습니다.

  1. COUNTIF로 표 안에 몇 개 있는지 센다. 0이면 찾는 값 쪽을 먼저 의심한다.
  2. LENLEN(TRIM(CLEAN(…)))을 비교해 눈에 안 보이는 글자를 확인한다.
  3. 찾는 값과 표의 값 양쪽에 ISNUMBER·ISTEXT를 넣어 자료형이 같은지 본다. 1번 결과와 상관없이 이 단계는 거칩니다.
  4. 수식 줄에서 범위의 맨 왼쪽 열이 찾는 값의 열인지, 열 번호가 1 이상이고 범위의 열 개수 이하인지 본다.

보고서에 #N/A를 그대로 내보내지 않으려면 IFNA로 감쌉니다. 다만 원인을 고치기 전에 감싸면 틀린 줄이 「코드없음」으로 바뀔 뿐이라, 감싸는 것은 원인을 다 본 뒤에 하십시오.

XLOOKUP이 이 버전에 있었습니다

=XLOOKUP("A-102",단가표!$A$2:$A$7,단가표!$C$2:$C$7,"없음")을 넣었더니 3500이 나왔습니다. 이 Excel 16.0 빌드 20326.0에는 XLOOKUP이 있습니다. 이 수식은 찾는 열($A$2:$A$7)과 가져올 열($C$2:$C$7)을 따로 적습니다. 열 번호 인수가 아예 없고, 일치 방식도 따로 지정하지 않았습니다. ③④⑤가 생기던 인수 두 개가 이 모양에는 없습니다.

일치 방식을 적지 않은 채 없는 코드 B-203을 넣었더니 「없음」이 나왔습니다. 같은 값을 VLOOKUP에 네 번째 인수 없이 넣었을 때 900이 나온 것과 다릅니다. 네 번째 자리에 적어 둔 「없음」이 그대로 나오므로 IFNA를 따로 씌우지 않아도 됩니다.

고쳐 주지 않는 것도 있습니다. ①②를 XLOOKUP으로 다시 돌려 봤습니다.

넣은 것XLOOKUP 결과
뒤 공백이 붙은 A-102 없음
사번표(글자)에 숫자 1002로없음
사번표(글자)에 TEXT(…,"0")으로 맞춰서이하늘
사번표(글자)에 글자 1002이하늘

값 자체가 어긋나 있는 ①②는 함수를 바꿔도 그대로 남습니다. 값 쪽을 손봐야 합니다.

실패한 것

확인하지 않은 것

함께 보기