Menu

Excel INDIRECT 函数:把文本变成单元格引用

=INDIRECT("C"&E2) 读取地址以文本形式拼出的单元格:C 列,第 E2 行。用它按单元格中的名称选择工作表、用数字构造区域,以及制作二级联动下拉列表。

本页的每张表格都是实时的:修改数字或公式,就会重新计算。

=INDIRECT(E2) 读取的单元格,其地址以文本形式写在 E2 中。如果 E2 中是 C4,公式就返回 C4 中的值。地址也可以由几部分拼成:=INDIRECT("C"&E3) 读取 C 列中行号为 E3 的单元格。

以文本形式写出的引用
F2
ABCDEF
1ProductCategoryPriceAddressValue
2AppleFruit$1.20C4$0.80
3PearFruit$1.506$1.10
4CarrotVegetable$0.80
5BreadBakery$2.40
6MilkDairy$1.10
点击单元格查看它的公式。修改数字或公式,表格会重新计算。

F2 读取 C4,也就是 Carrot 的价格 0.80。把E2改成‘C3‘或‘B5‘,F2会跟着变。F3把“C”和E3中的6拼成地址‘C6‘,返回0.80。把 E2 改成 `C3` 或 `B5`,F2 会跟着变。F3 把“C”和 E3 中的 6 拼成地址 `C6`,返回 1.10。把 E3 改成 2,就会得到 Apple 的价格。

INDIRECT 语法

=INDIRECT(ref_text, [a1])
  • ref_text:表示一个引用的文本,例如 "C4"、"B2:B6"、"Prices!A2"、"'Price list'!A2:B9"。
  • a1:TRUE 或省略时按 A1 样式读取地址。FALSE 按 R1C1 样式读取,"R4C3" 表示第 4 行第 3 列,适合行和列都是数字的情况。

如果文本不是有效的地址,结果就是 #REF!。INDIRECT 返回的是真正的引用,所以它可以用在 SUM、COUNTIF、VLOOKUP 以及任何接受区域的函数中。

用数字构造区域

地址可以是一整个区域。把一个数字拼进地址,就能得到大小由某个单元格决定的区域。

前 N 行的合计
F2
ABCDEF
1MonthSalesRowsTotal
2Jan4,200312,900
3Feb3,900
4Mar4,800
5Apr5,100
6May4,600
7Jun5,300
点击单元格查看它的公式。修改数字或公式,表格会重新计算。

E2 中为 3 时,文本变成 B2:B4,F2 把 Jan 到 Mar 相加:12,900。把 E2 设为 6 就得到上半年的合计 27,900。之所以写 1+E2,是因为数据从第 2 行开始。同样的合计也可以不用 INDIRECT 写成 =SUM(B2:INDEX(B2:B7,E2)),它不是易失性的;OFFSET 页面对几种写法做了比较。

引用名称写在单元格中的工作表

工作表名称也可以来自单元格。这样一个汇总公式就变成了跨工作表的查找:每一行读取 A 列中所写名称的那张工作表。名称两边的单引号让带空格的名称也能正常工作。

每张月份工作表一个合计
B2
AB
1MonthTotal
2Jan12,500
3Feb12,200
4Mar13,700
点击单元格查看它的公式。修改数字或公式,表格会重新计算。

B2 拼出文本 'Jan'!B2:B4 并求和:12,500。B3 和 B4 是向下填充的同一个公式,所以它们读取 Feb(12,200)和 Mar(13,700)。打开 Feb 标签页改一个数字,汇总会随之更新。在 A2 中把 Jan 改成 Feb,B2 就变成 Feb 的合计。引号里的 B2:B4 是文本,向下填充时不会变化,变化的只有对 A2 的引用。

二级联动下拉列表

第二个下拉列表的选项取决于第一个,这是 INDIRECT 的经典用法。在 Excel 中通常这样设置:

  1. 把每个类别的选项放在一列中,并用类别名为每个区域命名:选中这些列及其标题,使用“公式 > 根据所选内容创建 > 首行”。这样就创建了名称 Fruit、Vegetable 和 Dairy。
  2. 为 A2 设置类别列表:“数据 > 数据验证”,“允许”选“序列”,“来源”填 Fruit,Vegetable,Dairy。
  3. 为 B2 设置一个来源为 =INDIRECT(A2) 的列表。A2 中是 Fruit 时,列表读取名为 Fruit 的区域。

下面的表格用每个类别一张工作表代替命名区域,实现同样的效果。D2 用 INDIRECT 把 A2 中所写工作表的选项溢出显示出来,B2 的列表读取 D2:D4。

随类别变化的选项列表
D2
ABCD
1CategoryItemItems for the category
2FruitAppleApple
3Pear
4Plum
点击单元格查看它的公式。修改数字或公式,表格会重新计算。

在 A2 中选择 Dairy:D2:D4 会换成 Milk、Butter、Cheese,B2 中的选项也一样。B2 会保留原来的值,直到你选择新的值;Excel 也是这样,所以表单常常在选项旁边加一个检查,例如 =COUNTIF(D2:D4,B2)>0。在 Excel 365 中可以不用命名区域,而让第二个列表指向一个溢出公式,例如在辅助单元格中写 =INDIRECT("'"&A2&"'!A2:A4"),再用 =D2# 作为“来源”。其余设置见 下拉列表 页面。

INDIRECT 是易失性函数,而且不理会插入的行

INDIRECT 读取的是文本而不是引用,由此带来两个副作用:

  • 每次有改动都会重新计算。 Excel 无法知道一段文本会指向哪些单元格,所以工作簿中任何地方被编辑后,它都会重新计算每一个 INDIRECT。几十个没有影响,几万个会让每次按键都变慢。带行号的 INDEX(=INDEX(C:C,E3))与 =INDIRECT("C"&E3) 结果相同,而且只在其输入变化时才重新计算。
  • 地址不会移动。 在第 4 行上方插入一行,=C4 会变成 =C5,但 =INDIRECT("C4") 仍然读取 C4,而它现在已经是另一行了。有时这正是想要的效果:无论工作表怎么变,引用都固定在某个单元格上。但更多时候,这是一个等着有人插入行时才会暴露的 bug。

INDIRECT 引用另一个工作簿时,只有在那个工作簿打开时才有效;关闭后会返回 #REF!。

练习:根据行号取价格

价格表
F2
ABCDEF
1ProductCategoryPriceRowPrice
2AppleFruit$1.205
3PearFruit$1.50
4CarrotVegetable$0.80
5BreadBakery$2.40
6MilkDairy$1.10
点击单元格查看它的公式。修改数字或公式,表格会重新计算。

轮到你了: 在 F2 中用 INDIRECT 返回 C 列中行号为 E2 所写数字的价格。

常见问题

Excel 中的 INDIRECT 函数有什么用?

它把文本变成引用。=INDIRECT("C4") 返回 C4 的值,=INDIRECT(E2) 返回 E2 中所写地址对应单元格的值。地址可以用 & 拼接,所以 =INDIRECT("C"&E2) 读取 C 列中行号为 E2 的那个单元格。

工作表名称写在单元格里,怎样引用这张工作表?

拼接地址时把工作表名称放在单引号里:=INDIRECT("'"&A2&"'!B2")。有了单引号,名称中带空格也能正常工作。=SUM(INDIRECT("'"&A2&"'!B2:B4")) 会对那张工作表上的一个区域求和。

INDIRECT 为什么返回 #REF!?

文本不是有效的地址,或者它指向一张不存在的工作表,或者指向一个已关闭的工作簿。把同样的表达式单独放在一个单元格里(不加 INDIRECT),就能看到公式拼出的文本是什么。

INDIRECT 是易失性函数吗?

是的。工作簿中任何地方发生变化,Excel 都会重新计算每一个 INDIRECT,因为它无法提前知道文本会指向哪些单元格。少量使用没有问题,成千上万个就会拖慢工作簿。INDEX 往往能完成同样的工作,而且不是易失性的。

Coddy 编程语言插图

和 Coddy 一起学编程

开始