跳到主要內容跳到頁尾

ARRAYFORMULA 為什麼只算出一格?SUM、VLOOKUP、整欄範圍與 #REF! 的排錯

7 分鐘閱讀Lv.4 進階摘要與日期

整理 ARRAYFORMULA 常見的怪結果:SUM、SUMPRODUCT 只回一個數字、什麼時候改用 BYROW、MAP 或 FILTER、VLOOKUP 漏包只出現一格、A2:A 與固定範圍的取捨,以及被其他儲存格擋住時的 #REF!。

發布 更新

文章目錄

為什麼我包了 ARRAYFORMULA,結果還是只有最上面一格有值?多半是裡面有個函式把整欄收斂成一個數字,或是 VLOOKUP 漏包在外面。ARRAYFORMULA 的寫法、A2:A 和 IF(A2:A="", "", ...) 在 ARRAYFORMULA 入門 與 表單回覆表自動填滿 講過,這篇直接看出狀況的地方。

用 Excel 的人先知道一件事:本篇「SUM、MAX 包了 ARRAYFORMULA 還是只回一格」是 Google 試算表的情境;Excel 365/2021/2024 有動態陣列, 本來就會自動溢出,也沒有 ARRAYFORMULA 這個函式。BYROW、MAP、LAMBDA 在 Excel 365 與 Excel 2024 可用,語法相同;XLOOKUP 在 Excel 365/2021/2024 可用,Excel 2019 以前沒有。

後面都用這張訂單,放在 A1:D9,D 欄的單價先當成已經填好的數字(查價目表的那一節會改放在 I 欄)。每個範例的結果各放在 F 欄或文中指定的位置,照著試的時候,換下一個範例前先把上一個範例的結果清掉,免得互相擋住:

ABCD
1品項上午杯數下午杯數單價
2蘋果紅茶12845
3青茶71435
4烏龍奶茶9655
5蘋果綠茶51040
6青茶11335
7蘋果紅茶4945
8烏龍奶茶8255
9冬瓜檸檬6150

SUM 和 SUMPRODUCT:整欄只回一個數字

入門篇講過 AND、OR、MAX 放進去不會逐列算,SUM 和 SUMPRODUCT 也是同一類。我想在 F 欄算每一列的總杯數,直覺這樣寫,在 F2 輸入:

F2 得到 115,F3 以下全是空的。SUM 把 B2:C9 整塊加成一個數字,62 加 53 就是 115。要逐列,直接用加號:

Google 試算表公式
fx

每一列的總杯數

=ARRAYFORMULA(B2:B9+C2:C9)
F
220
321
415
515
614
713
810
97

SUMPRODUCT 也一樣。我想算每一列的金額,卻寫成:

這條回傳 5035,是所有訂單的總營收,不是每列一個。SUMPRODUCT 本來就會吃整個範圍,用在算總營收一格就夠了,不必包 ARRAYFORMULA:

一樣是 5035。要每列的金額,把乘法寫出來:

Google 試算表公式
fx

每一列的金額

=ARRAYFORMULA((B2:B9+C2:C9)*D2:D9)
F
2900
3735
4825
5600
6490
7585
8550
9350

這八個數字加起來就是 5035。

每列要用函式時:BYROW、MAP 還是 FILTER

但有些事不能用加號乘號改寫。我想知道每一列上午和下午哪個比較多,手看是 12、14、9、10、11、9、8、6。MAX 放進 ARRAYFORMULA 會得到整塊的最大值 14,這時候我改用 BYROW,它會把範圍一列一列交給 LAMBDA:

Google 試算表公式
fx

每一列取上午、下午的較大值

=BYROW(B2:C9, LAMBDA(r, MAX(r)))

結果就是 12、14、9、10、11、9、8、6。兩欄各取一個值比較的話,MAP 也行,兩個寫法答案一樣:

BYROW、MAP 的觀念在 LAMBDA 自訂函式 有講,這邊只談怎麼選。我個人的順序是這樣:

  • 加減乘除、IF、比較這類單格就能寫的,用 ARRAYFORMULA,一眼看得懂。
  • 每列要做「彙總」(MAX、SUM、TEXTJOIN)的,用 BYROW。
  • 要「留下某些列」、不要每列補一格的,用 FILTER。

最後一種舉例:上午加下午至少 15 杯的訂單。結果放在 J2,會展開成 J2:L5,避開 G、H 欄的價目表:

Google 試算表公式
fx

總杯數大於等於 15 的列

=FILTER(A2:C9, B2:B9+C2:C9 >= 15)
JKL
2蘋果紅茶128
3青茶714
4烏龍奶茶96
5蘋果綠茶510

BYROW 配開放式範圍要小心。BYROW(B2:C, ...) 連下面的空白列都會處理,空白列的 MAX 會是 0,整欄後面會拖出一堆 0。我會先用 FILTER 把有資料的列挑出來再交給它:

這個資料上結果跟前面一樣,也是 12、14、9、10、11、9、8、6。FILTER 一列都沒找到會是 #N/A,所以全空的表會顯示錯誤,真的要擋再包 IFERROR。

混用 VLOOKUP

價目表放在 G1:H6,單價從這裡查:

GH
1品項單價
2蘋果紅茶45
3青茶35
4烏龍奶茶55
5蘋果綠茶40
6冬瓜檸檬50

在 I2 輸入 VLOOKUP,查詢值給整欄品項,忘了包 ARRAYFORMULA:

I2 只會得到 45,I3 以下是空的,它只查了第一個品項。外面包上 ARRAYFORMULA 才會逐列查:

Google 試算表公式
fx

每一列查價目表的單價

=ARRAYFORMULA(VLOOKUP(A2:A9, G2:H6, 2, 0))
I
245
335
455
540
635
745
855
950

另一個要提的是 VLOOKUP 第三個參數的 2 是寫死的欄序。價目表的 G、H 中間若被人插了一欄,2 就會指到新欄,不報錯但單價是錯的。我自己查價目表改用 XLOOKUP,查詢欄和結果欄各自指定,插欄不受影響:

結果同樣是 45、35、55、40、35、45、55、50。XLOOKUP 的寫法在 XLOOKUP 入門。兩個範圍高度要一致,XLOOKUP(A2, G2:G6, H2:H5) 這種差一列的寫法在 Google 試算表會是 #N/A。

資料下面還有空白列的時候,開放式的 A2:A 去查會在空白列得到 #N/A,外面包 IF(A2:A="", "", ...) 就好,寫法在實戰篇。

整欄範圍:算到哪一列

開放式範圍 B2:B 方便,代價是公式的範圍包含工作表下面所有的列。試算表效能基礎 提到,公式實際要算的列數取決於工作表目前用到的列數。這節不給速度的數字,只講三種寫法的差別。

  • 開放式 B2:B:新增資料自動跟上,下面空白列也會被算,要靠 IF(A2:A="", "", ...) 擋掉。
  • 固定上限 B2:B500:範圍小,但是超過第 500 列的資料不會被算,而且各個範圍的大小要一致。把其中一個寫成 C2:C499 並不會整個失敗:兩邊長度對不起來時,短的那邊在多出的那一列補 #N/A,其他列照常相乘。錯誤只落在最後一列,反而更容易漏看。
  • 用 INDEX 動態決定尾端:B2:INDEX(B:B, COUNTA(A:A))。

第三種的例子,A 欄有標題加 8 筆,COUNTA(A:A) 是 9,範圍就是 B2:B9:

Google 試算表公式
fx

範圍尾端跟著 A 欄筆數走

=ARRAYFORMULA(B2:INDEX(B:B, COUNTA(A:A)) + C2:INDEX(C:C, COUNTA(A:A)))

結果跟前面的 B2:B9+C2:C9 一樣,20、21、15、15、14、13、10、7。INDEX 不屬於官方列出的會定時重新計算的函式(官方列的是 NOW、TODAY、RAND、RANDBETWEEN 等)。條件是 A 欄中間不能有空格、下面不能放別的東西,不然 COUNTA 就數歪了。

我的習慣是資料量小就用開放式,加上 IF 擋空白;公式多了開始覺得慢,再改成有上限的範圍。

被擋住的 #REF!

入門篇提過結果的那一欄要留空。實際上最難找的是「看起來是空的」的格子。

假設 F5 裡面有一個以前留下來的 ="",公式的結果是空字串,看起來沒東西,但它不是真正的空白。這時在 F2 輸入:

F2 會顯示 #REF!,把滑鼠移上去,提示是「系統未展開陣列結果,以免覆蓋 F5 中的資料。」提示裡的儲存格就是擋路的那一格。把 F5 清掉,結果就整欄展開了。

排查時我看三件事:提示裡的儲存格、那格是不是有舊公式(="" 這類)、有沒有同事在結果範圍裡手動打了數字。

練習

1

找出錯在哪

同事想在 F 欄算「上午、下午取較大值,乘以單價」,寫了:

每一列都是用 14 去乘單價。請說明原因並改正,答案要是每列各自取較大值。

遇到只出現一格的時候,先找整欄被收斂的函式,再檢查有沒有漏包的 ARRAYFORMULA。我是喜特先生,Mr. Sheet,我們下個教學見!

分享:
喜特先生 Mr. Sheet

喜特先生 Mr. Sheet

數據分析師/商業分析師

八年工作經驗,跨不同業界解決數據需求。做過的案例都整理在作品集。

接下來可以

相關文章

查看所有文章

留言討論

共 0 則留言

訂閱電子報,新文章上線就通知你

免費,隨時可取消。

送出即表示同意服務條款與隱私權政策。