=VLOOKUP(F2,A2:D6,3,FALSE) 在 A2:D6 的第一列中查找 F2 的值,并返回同一行第三列的值。末尾的 FALSE 表示“只要精确匹配”。在 F2 中选择另一个产品,价格就会随之变化。
| A | B | C | D | E | F | G | |
|---|---|---|---|---|---|---|---|
| 1 | Product | Category | Price | Stock | Look for | Price | |
| 2 | Apple | Fruit | $1.20 | 40 | Pear | $1.50 | |
| 3 | Pear | Fruit | $1.50 | 25 | |||
| 4 | Carrot | Vegetable | $0.80 | 60 | |||
| 5 | Bread | Bakery | $2.40 | 15 | |||
| 6 | Milk | Dairy | $1.10 | 30 |
单击 G2,可以看到表格 A2:D6 被框了出来。把公式中的 3 改成 2,G2 返回的就是类别而不是价格,因为 Category 是表格的第二列。匹配时不区分大小写:pear 也能找到 Pear。
VLOOKUP 语法
=VLOOKUP(lookup_value, table_array, col_index_num, [range_lookup])
| 参数 | 含义 | 示例中的值 |
|---|---|---|
lookup_value | 要查找的值。 | F2(Pear) |
table_array | 要查找的表格。VLOOKUP 只在它的第一列中查找。 | A2:D6 |
col_index_num | 要返回表格中的哪一列,从表格的第一列(1)开始数。 | 3(Price) |
range_lookup | FALSE 或 0 表示精确匹配。TRUE、1 或省略表示近似匹配。 | FALSE |
列号是从表格的起始列开始数的,而不是从工作表的 A 列开始。在一个从 C 列开始的表格中,col_index_num 为 2 表示 D 列。列号大于表格宽度时返回 #REF!,为 0 时返回 #VALUE!。
如果 Excel 设置的语言使用逗号作为小数点,参数之间要用分号分隔:=VLOOKUP(F2;A2:D6;3;FALSE)。
用 MATCH 确定返回列
写死的 3 在有人往表格中间插入一列时会悄无声息地出错:公式仍然返回第三列,而那一列现在放的是别的内容。改为让 MATCH 根据标题找出列号。这里的 G1 是一个下拉列表:选择 Stock 或 Category,G2 会随之变化。
| A | B | C | D | E | F | G | |
|---|---|---|---|---|---|---|---|
| 1 | Product | Category | Price | Stock | Look for | Price | |
| 2 | Apple | Fruit | $1.20 | 40 | Carrot | 0.8 | |
| 3 | Pear | Fruit | $1.50 | 25 | |||
| 4 | Carrot | Vegetable | $0.80 | 60 | |||
| 5 | Bread | Bakery | $2.40 | 15 | |||
| 6 | Milk | Dairy | $1.10 | 30 |
MATCH(G1,A1:D1,0) 返回“Price”在标题行中的位置 3,VLOOKUP 把它用作列号:Carrot 的结果是 0.8。这是一个双向查找:行由产品决定,列由标题决定。用 INDEX 代替 VLOOKUP 实现同样思路的写法,请看 INDEX 和 MATCH 一文。
近似匹配:使用 TRUE 的 VLOOKUP
最后一个参数为 TRUE 时,VLOOKUP 不再查找相等的值,而是找出小于或等于查找值的最大值。这正是分段查找所需要的:税率档位、成绩等级、运费标准、提成档次。第一列必须按从小到大排序。
| A | B | C | D | E | F | |
|---|---|---|---|---|---|---|
| 1 | Sales from | Rate | Rep | Sales | Rate | |
| 2 | 0 | 0% | Ana | 750 | 0% | |
| 3 | 1000 | 3% | Ben | 4,200 | 3% | |
| 4 | 5000 | 5% | Cara | 5,000 | 5% | |
| 5 | 10000 | 8% | Dev | 12,500 | 8% |
Ben 的 4,200 不在 A 列中。不超过它的最大值是 1,000,所以他得到 3%。Cara 的 5,000 正好匹配 5,000 那一行,得到 5%。Dev 的 12,500 超过了最后一档,得到最后的比例 8%。低于第一档的值(这里是负的销售额)会返回 #N/A,所以表格从 0 开始。
$A$2:$B$5 中的 $ 符号让表格在 F2 向下填充到 F5 时保持不动。如果没有它们,F3 会在 A3:B6 中查找,从而跳过第一档。
省略第四个参数等同于 TRUE。在未排序的产品列表上,这是一个不会报错的 bug:Excel 按列表已排序的方式查找,可能返回错误行的价格,或者对确实存在的值返回 #N/A。查找姓名、代码或 ID 时,最后一个参数一定要写 FALSE。
为什么 VLOOKUP 返回 #N/A
#N/A 表示“找不到”。下面的表格展示了三种常见原因,G 列把每个查找都用 IFNA 和 TRIM 包起来重新算了一遍。
| A | B | C | D | E | F | G | |
|---|---|---|---|---|---|---|---|
| 1 | Product | Category | Price | Stock | Look for | Price | Fixed |
| 2 | Apple | Fruit | $1.20 | 40 | Kiwi | #N/A | Not found |
| 3 | Pear | Fruit | $1.50 | 25 | Milk | #N/A | $1.10 |
| 4 | Carrot | Vegetable | $0.80 | 60 | Fruit | #N/A | Not found |
| 5 | Bread | Bakery | $2.40 | 15 | |||
| 6 | Milk | Dairy | $1.10 | 30 |
#N/A 要查找的值不在查找范围内。- 表格中没有这个值。 Kiwi 不在 A2:A6 中。这是真正的“找不到”,
IFNA(...,"Not found")会把它变成可读的文本。把 E2 改成 Apple,两列都会显示价格。 - 多余的空格。 E3 中是结尾带空格的
"Milk ",所以它不等于Milk。TRIM(E3)去掉了空格,G3 就找到了价格。如果空格在表格里,就用 TRIM 把 A 列清理一次,而不是在每个查找中处理。 - 这个值在另一列中。 Fruit 确实存在,但在 B 列中。VLOOKUP 只在表格的第一列中查找,所以 E4 在两列中都失败了。让表格从你要查找的那一列开始,或者使用 XLOOKUP,它分别指定查找列和返回列。
在查找外面要用 IFNA 而不是 IFERROR。IFNA 只捕获 #N/A,所以列号写错导致的 #REF! 仍然会显示出来,而不会被隐藏成“Not found”。
还有两个原因:
- 以文本存储的数字。 如果 A 列中的产品代码是以文本形式输入的(通常是导入后出现,单元格角上有一个绿色小三角),而 F2 中是数字 101,那么即使列表中有 101,
=VLOOKUP(F2,A2:B6,2,FALSE)也会返回 #N/A。转换其中一边:=VLOOKUP(F2&"",A2:B6,2,FALSE)查找文本“101”;F2 是文本时,=VLOOKUP(VALUE(F2),A2:B6,2,FALSE)查找数字。 - 在未排序的数据上使用近似匹配,上一节已经讲过。
VLOOKUP 返回 0 而不是空白
当 VLOOKUP 找到的单元格是空的时,Excel 显示 0,而不是空单元格。这样一来,Stock 列中的 0 看起来就像“缺货”,而实际上库存从来没有填写过。在公式后面加上 &"",或者检查结果的长度:
=VLOOKUP(F2,A2:D6,4,FALSE)&""
=IF(LEN(VLOOKUP(F2,A2:D6,4,FALSE))=0,"",VLOOKUP(F2,A2:D6,4,FALSE))
第一种写法更短,但会把返回的每个数字都变成文本,之后的 SUM 会跳过它们。第二种写法让数字保持为数字。
跨工作表使用 VLOOKUP
在表格前面写上工作表名和 !。在 Excel 中编写公式时,单击另一个工作表的标签并选择区域,Excel 会自动帮你写成 Prices!A2:B6。下面 Orders 工作表从 Prices 工作表中查找价格。
| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | Order | Product | Qty | Price | Total |
| 2 | 1001 | Pear | 3 | $1.50 | $4.50 |
| 3 | 1002 | Milk | 2 | $1.10 | $2.20 |
| 4 | 1003 | Apple | 5 | $1.20 | $6.00 |
| 5 | 1004 | Bread | 1 | $2.40 | $2.40 |
打开 Prices 工作表,修改 Apple 的价格:订单合计会随之更新。有两个细节:
- 工作表名中有空格时需要加单引号:
=VLOOKUP(B2,'Price list'!$A$2:$B$6,2,FALSE)。 - 如果表格在另一个工作簿中,还要在方括号中加上文件名:
[Prices.xlsx]Prices!$A$2:$B$6。那个文件关闭后,Excel 会在公式中显示它的完整路径,查找仍然会从已保存的文件中取值。
VLOOKUP 使用通配符(部分匹配)
使用 FALSE 时,查找值可以包含通配符:* 代表任意数量的字符,? 代表恰好一个字符。"*"&E2&"*" 会找到名称中包含 E2 文本的第一个产品。
| A | B | C | D | E | F | |
|---|---|---|---|---|---|---|
| 1 | Product | Category | Price | Contains | Price | |
| 2 | Green tea | Drinks | $3.20 | coffee | $2.90 | |
| 3 | Iced coffee | Drinks | $2.90 | |||
| 4 | Coffee beans | Pantry | $8.50 | |||
| 5 | Black tea | Drinks | $2.70 | |||
| 6 | Orange juice | Drinks | $3.40 |
“coffee”同时匹配 Iced coffee 和 Coffee beans;VLOOKUP 返回从上往下的第一个,即 8.50,也可以试试 juice。要查找真正的星号或问号,就在它前面加一个波浪号:"~*"。
VLOOKUP 向左查找
VLOOKUP 无法返回查找列左侧的列:col_index_num 只能向右数,负数会出错。要根据价格查找产品,就用 XLOOKUP 或 INDEX 和 MATCH,在 C 列中查找并返回 A 列:
=XLOOKUP(2.4, C2:C6, A2:A6) Excel 2021 and Microsoft 365
=INDEX(A2:A6, MATCH(2.4, C2:C6, 0)) every version
用第一个表格的数据,两个公式都返回 Bread。完整讲解请看 XLOOKUP。
练习:按重量计算运费
| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | Weight from (kg) | Cost | Weight (kg) | Cost | |
| 2 | 0 | $4.50 | 7 | ||
| 3 | 2 | $6.00 | |||
| 4 | 5 | $9.50 | |||
| 5 | 10 | $14.00 | |||
| 6 | 20 | $22.00 |
轮到你了: 每档运费从它的重量开始,一直适用到列表中的下一个重量。在 E2 中用 VLOOKUP 返回 D2 中包裹重量对应的运费。
VLOOKUP 双条件查找
VLOOKUP 只接受一个查找值。要按两列匹配,就建一个把它们连起来的辅助列,放在表格的第一列,再查找同样连接起来的文本。下面的 A 列是向下填充的 =B2&"-"&C2,所以其中是 Coffee-Small、Coffee-Large 等值。
| A | B | C | D | E | F | G | |
|---|---|---|---|---|---|---|---|
| 1 | Key | Product | Size | Price | Product | Size | Price |
| 2 | Coffee-Small | Coffee | Small | $2.50 | Tea | Large | |
| 3 | Coffee-Large | Coffee | Large | $3.50 | |||
| 4 | Tea-Small | Tea | Small | $2.00 | |||
| 5 | Tea-Large | Tea | Large | $3.00 | |||
| 6 | Juice-Small | Juice | Small | $3.00 |
轮到你了: A 列用短横线把产品和规格连接起来。在 G2 中返回 E2 中的产品、F2 中的规格所对应的价格。
分隔符很重要:"Tea"&"Large" 得到 TeaLarge,在 A 列中什么也匹配不到。在 Excel 2021 和 Microsoft 365 中,可以不用辅助列,直接写 =XLOOKUP(1,(B2:B6=E2)*(C2:C6=F2),D2:D6);多条件查找一文介绍了这种写法以及 INDEX/MATCH 的写法。
常见问题
Excel 中 VLOOKUP 怎么用?
输入 =VLOOKUP( 并给出四个参数:要查找的值、表格(它的第一列必须包含这个值)、要返回的列号,以及表示精确匹配的 FALSE。=VLOOKUP("Pear",A2:D6,3,FALSE) 在 A 列中找到 Pear,并返回这一行 C 列的值。
VLOOKUP 最后的 TRUE 或 FALSE 是什么意思?
FALSE(或 0)表示精确匹配,找不到值时返回 #N/A。TRUE(或 1,或者省略这个参数)表示近似匹配:返回小于或等于查找值的最大值,只有第一列按升序排序时才能正确工作。
为什么我的 VLOOKUP 返回 #N/A?
在表格的第一列中没有找到这个值。常见原因有:拼写错误、多余的空格("Milk " 不等于 "Milk")、只有一边的数字是以文本存储的,或者这个值在另一列中。用 IFNA 把公式包起来可以显示你自己的文本:=IFNA(VLOOKUP(F2,A2:D6,3,FALSE),"Not found")。
VLOOKUP 能向左查找吗?
不能。VLOOKUP 只能返回表格第一列右侧的列。在 Excel 2021 或 Microsoft 365 中用 =XLOOKUP(F2,C2:C6,A2:A6),在任何版本中都可以用 =INDEX(A2:A6,MATCH(F2,C2:C6,0))。
VLOOKUP 怎么跨工作表查找?
在区域前面加上工作表名和一个感叹号:=VLOOKUP(B2,Prices!$A$2:$B$6,2,FALSE)。如果工作表名中有空格,就用单引号把它括起来:'Price list'!$A$2:$B$6。