跳到主要內容跳到頁尾

巢狀 IF 與 AND / OR 的陷阱:順序、ARRAYFORMULA 與空白儲存格

8 分鐘閱讀Lv.1 初學者摘要與日期

整理巢狀 IF 和 AND / OR 常踩的坑:條件順序與邊界值寫反、AND / OR 放進 ARRAYFORMULA 不會逐列判斷、文字和數字比較、空白儲存格被當成 0,並簡單比較 IFS 與 SWITCH。

發布 更新

文章目錄

為什麼我的成績分級公式,明明每個括號都配對了,93 分卻拿到 D?這篇整理我寫 IF、AND、OR 時踩過的坑。IF 的基本寫法在 IF 函式入門 講過了,這邊直接從會出事的地方開始。

前半段用這份成績,放在 A1:B8,B 欄是分數:

AB
1座號分數
2193
3285
4372
5466
6559
7690
8780

分級的標準是 90 分以上 A、80 分以上 B、70 分以上 C、60 分以上 D,其他 F。

條件順序寫反

巢狀 IF 是由上往下檢查,第一個成立的條件就直接回傳,後面不會再看。所以條件的順序就是邏輯本身。

我把順序寫成由低到高:

Google 試算表公式
fx

條件由低到高排列的錯誤寫法

=IF(B2>=60, "D", IF(B2>=70, "C", IF(B2>=80, "B", "A")))

來看看結果:

分數結果
93D
85D
72D
66D
59A
90D
80D

93 分大於等於 60,第一關就成立,直接回傳 D,後面的條件永遠沒機會執行。更好笑的是 59 分,三個條件全部不成立,掉到最後的「A」。這種錯誤不會報錯,公式看起來又很整齊,所以特別難發現。

改法是把最嚴格的條件放最前面:

Google 試算表公式
fx

由高到低檢查的正確寫法

=IF(B2>=90, "A", IF(B2>=80, "B", IF(B2>=70, "C", IF(B2>=60, "D", "F"))))

結果依序是 A、B、C、D、F、A、B。

另一個做法是反過來,由低到高,但條件要跟著換成「小於」:

Google 試算表公式
fx

由低到高檢查,條件改成小於

=IF(B2<60, "F", IF(B2<70, "D", IF(B2<80, "C", IF(B2<90, "B", "A"))))

結果和上面完全一樣。重點是方向要一致,大於配由高到低,小於配由低到高。

邊界值:> 還是 >=

這個題目裡我故意放了 90 和 80 分,就是為了測邊界。如果一不小心把 >= 都寫成 >:

Google 試算表公式
fx

邊界值寫成大於

=IF(B2>90, "A", IF(B2>80, "B", IF(B2>70, "C", IF(B2>60, "D", "F"))))

90 分會變成 B、80 分變成 C,其他列維持 A、B、C、D、F 不變。只有剛好踩在門檻上的人會被降一級,很容易漏掉,所以我寫完分級公式,都會特地塞一筆剛好等於門檻的資料去測。

AND 和 OR 放進 ARRAYFORMULA

AND 和 OR 在單一儲存格裡好好的,一包進 ARRAYFORMULA 就會出事。先看資料,這是五張訂單,放在 A1:C6:

ABC
1訂單金額出貨天數
2138502
32124006
437809
5452903
659601

我想標出「金額大於等於 3000,而且出貨天數 3 天以內」的急件。平常會寫 ,往下複製五列,結果是急件、一般、一般、急件、一般,沒問題。

但我想要一條公式搞定,不用往下複製,於是包上 ARRAYFORMULA,放在 D2:

Google 試算表公式
fx

AND 放進 ARRAYFORMULA 的錯誤寫法

=ARRAYFORMULA(IF(AND(B2:B6>=3000, C2:C6<=3), "急件", "一般"))

結果只有 D2 一格出現「一般」,下面四格都是空的,沒有逐列判斷。AND 的工作是把所有條件收攏成「一個」TRUE 或 FALSE,丟給它一整排的比較結果,它也只會吐回一個答案,那五列不是全部都成立,所以是 FALSE,IF 就只拿到一個值。OR 也是一樣的狀況。

修法是用乘法代替 AND、加法代替 OR。乘法的意思是兩邊都要成立,TRUE 在運算時當成 1、FALSE 當成 0,1 乘 1 才是 1,其他都是 0:

Google 試算表公式
fx

用乘號代替 AND,逐列判斷

=ARRAYFORMULA(IF((B2:B6>=3000)*(C2:C6<=3), "急件", "一般"))

每個比較都要自己用括號包起來。來看看結果,從 D2 溢出到 D6:

訂單結果
1急件
2一般
3一般
4急件
5一般

IF 看到 0 會當成 FALSE,看到 1 或其他非 0 的數字,就當成 TRUE。

OR 的對應寫法是加號,只要有一個成立,加起來就大於 0。這個留給文末的練習。

如果你的資料不多,我個人其實比較常用最樸素的做法:不用 ARRAYFORMULA,每列各寫一條 IF(AND(...)),往下複製就好。公式短、好讀,要用 ARRAYFORMULA 的理由通常是「新增資料時公式要自動延伸」,這個場合再換成乘號寫法。延伸的細節可以看 ARRAYFORMULA 自動延伸。

文字和數字比較

這個坑比較陰險:比較結果不報錯,只是答案不是你想的。

我拿成績欄的「59 分」,用 LEFT 切出前兩個字當分數:

切出來是 59,看起來是數字,其實是文字。假設有另一張表,把這個結果放在 B2,再問它及不及格:

Google 試算表公式
fx

文字的 59 和數字 60 比較

=IF(B2>=60, "及格", "不及格")

結果是「及格」。Sheets 比大小時,文字會被當成比任何數字都大,所以文字的「59」大於等於 60 成立。而且 會得到 FALSE,文字的 85 和數字的 85 不是同一個東西。

懷疑是這個問題時,先用 看一眼。確認之後把它轉成數字再比:

Google 試算表公式
fx

先用 VALUE 轉成數字

=IF(VALUE(B2)>=60, "及格", "不及格")

這次是「不及格」。VALUE 就是把看起來像數字的文字轉成真的數字,英文的 value 就是「值」。

文字之間的比較也有兩個小細節。 會是 TRUE,大小寫不影響;但 是 FALSE,尾巴多一個空格就不一樣了。從別的系統貼來的資料特別容易有,整理方式在 文字清理函式。

空白儲存格會被當成 0

同一份成績表再往下一列,第 9 列的人還沒考,B9 是空的。我寫:

Google 試算表公式
fx

B9 是空白儲存格

=IF(B9<60, "不及格", "及格")

結果是「不及格」。空白在比較時被當成 0,0 小於 60,所以成立。連 都是 TRUE,同時 也是 TRUE,空白儲存格同時等於 0 和空字串。

還沒考試的人被標成不及格,應該不是你要的。解法是先判斷是不是空白:

Google 試算表公式
fx

空白時什麼都不顯示

=IF(B9="", "", IF(B9<60, "不及格", "及格"))

這次 B9 顯示空白。另外還有 ISBLANK 函式,語意更貼近「這格真的是空的」。差別在於,如果 A1 裡放的是公式 ="",它回傳的是空字串, 是 TRUE,ISBLANK(A1) 卻是 FALSE。我自己日常用 ="" 比較多,因為不管是真空白還是公式吐出的空字串,都能一次擋下來。

層數多了怎麼辦:IFS 與 SWITCH

巢狀超過三四層,我就會開始想換寫法。這邊先簡單看一下 IFS 與 SWITCH 的語法。

IFS 把巢狀拆成一組一組的「條件, 值」,語法是 。成績分級可以寫成:

Google 試算表公式
fx

IFS 版本的成績分級

=IFS(B2>=90, "A", B2>=80, "B", B2>=70, "C", B2>=60, "D", TRUE, "F")

結果一樣是 A、B、C、D、F、A、B。最後的 TRUE, "F" 是兜底,因為 IFS 如果所有條件都不成立,官方說明寫的是回傳 #N/A。把它拿掉,59 分那一列就會變成 #N/A。順序的問題也還在,IFS 一樣是由上往下,第一個成立的就回傳。

SWITCH 是另一種情況,判斷「某個值等於什麼,就對應什麼」,語法是 。假設 A2 是門市「左營」:

Google 試算表公式
fx

依門市名稱對應區域,沒列到的給預設值

=SWITCH(A2, "信義", "北區", "板橋", "北區", "左營", "南區", "未分區")

得到「南區」。如果門市換成「竹北」,沒有任何一個比對值符合,就回傳最後的預設值「未分區」。SWITCH 只能比「等於」,要比大於小於,還是得靠 IFS。如果沒有任何符合、又沒給預設值,會得到 #N/A(Excel 一樣),所以我習慣都先補一個預設值。

兩張會員卡的四種狀態,先列真值表

方格子 AND/OR 實作舊文的雙卡折扣,可以用四列測資檢查順序。規則是雙卡 8 折、單卡 9 折、無卡原價,不是把兩個 9 折相乘。

另開空白表,A1:B5 放以下布林值,C2 輸入下式後填到 C5;表中第三欄的預期折扣率請放在 D2:D5,不要放進 C 欄,才不會被公式蓋掉。若換成核取方塊,先維持預設 TRUE/FALSE,不混用文字「有」。

卡甲卡乙預期折扣率
FALSEFALSE1
TRUEFALSE0.9
FALSETRUE0.9
TRUETRUE0.8
Google 試算表公式
fx

先判兩張都有,再判任一張有,最後明確兜底原價

=IFS( AND(A2, B2), 0.8, OR(A2, B2), 0.9, TRUE, 1 )

四列結果與上表一致。AND 是兩張都要有,OR 是其中一張有即可;雙卡那列兩個條件其實都成立,所以 AND 分支必須先寫。最後 TRUE,1 明確處理無卡。換活動規則時,先更新四列預期,再改公式並逐列比對。

練習

1

找出錯在哪

同一份訂單(A1:C6),這次想標出「金額大於等於 3000,或出貨天數 3 天以內」的急件,同一條公式放在 D2 就好:。它只會在 D2 出現一個值,請用加號改寫,讓 D2:D6 依序顯示急件、急件、一般、急件、急件。

想看 IFS、SWITCH 在會員分級和代碼對照的實際用法,以及什麼時候該改用對照表,可以接著看 會員分級與代碼對照:IFS、SWITCH 還是查表?。

把成績表的分級公式改寫成 IFS,再故意塞一筆剛好 90 分的資料測看看吧!

我是喜特先生,Mr. Sheet,我們下個教學見!

分享:
#巢狀 IF#AND#OR#IFS#SWITCH
喜特先生 Mr. Sheet

喜特先生 Mr. Sheet

數據分析師/商業分析師

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

接下來可以

這篇在技能樹的 Lv.1「基礎操作」,模組「做簡單的判斷」(第 2/2 篇)。讀完這篇,路線上的下一個模組是「認識日期與時間」。

回到技能樹

相關文章

查看所有文章

留言討論

共 0 則留言

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

免費,隨時可取消。

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