[筆記] Excel VBA-3:如何使用VBA定義功能進行各項條件的篩選

這篇文比前兩篇稍嫌生硬一些,請參酌使用。


VBA筆記系列的最後一篇,拖這麼久才把這三篇發完也是始料未及的。最後一篇要來提及,在我完成了多項條件格式化篩選程式後,還可以如何將它設定為一個Excel內建的功能,以後就可以更快速地使用並且將它應用在不同的條件篩選上。

> 前情提要:目標是撰寫一個可自動檢查直行中有哪些不符合的值,並自動把它標示為紅色。而除了基本檢查單行的功能之外,在上一篇我也做了一些小小的變化,在直排檢查完後也橫向地檢查其他排是否有不合條件的值。

範例如下,我們嘗試先在欄位的第一列中從左到右去篩選是否有符合水果的欄位,然後找到符合結果後在該直行由上到下的方式來檢查哪些不是橘子與蘋果(或其他條件)。

如果真的忘記的話,可以再回去重看第一篇與第二篇:

順著上一篇的脈絡,最後我聽從了強者室友的建議把條件為蘋果與橘子的部分定義為變數,這樣就可以把下面這行很長的句子改寫成更易維護的方式。

原先

改寫後

作為零程式技術能力的我,充滿了疑問。(希望大家也跟我一樣困惑)

為什麼改寫完的程式看起來更複雜呢?以前我頂多只要在Formula1 中的內容 "=IF(OR(" & condition1 & "," & condition2 ... 不斷往下加 condition3, condition4 就好,但改寫後的結果卻得多上更多變數定義。

重新回顧上一次最後寫的東西,究竟什麼變簡單了?

實際上是為了避免 Formula1 的內容會太長,我們得不斷地往下加 [[ condition 3 & "," ]] 的格式,便先說formula1實際上就是下面的Formula。然後在下方更進一步解釋Formula就是最原始的公式:

  • formula = “=IF($F_CONDITION, $TRUE_VALUE, “”$FALSE_VALUE””)”
  • formula = 如果F_CONDITION 條件符合的話,就顯示 TRUE_VALUE ,若不符合就顯示 FALSE_VALUE

只不過,根據想篩選的是蘋果、橘子或其他水果而把當中的 F_CONDITION 換成condition1, condition2 等不同的東西。為此避開了需要在If(Or)公式中不斷延長的條件,而僅需要用Replace的方式把 F_CONDITION 換成Apple, Orange以及其他東西。

不過若重新回顧上述的句子,會發現同樣的情況也發生在改寫後的formula定義上。最後一句的fcondition似乎也面對到的一樣的問題。

所以同理,強者工程師自然不會放過這可以整理程式句子的機會。

他建議我使用Array陣列的方式來排列出上方所有需要的條件,然後用Join公式把條件合併在一起,放入Formula中。如果不懂得Array是什麼意思的,實際上也沒關係,可以將它設想爲數學的「數列」。我們在定義Formula前先把會用到的所有條件寫出來,然後把conditio1, condition2...列出來放進「條件數列」中。

於是上述定義出來的數列就等同於:Apple, Oragne, Peach... 的一個由不同條件的值所組成的數列。

再者,將剛剛Formula定義中的最後一行 fCondition 透過Join的公式改寫如下,而這裡的conditionArray就是剛剛所提到的數列了:
fCondition = "OR(" & Join(conditionArray, ",") & ")"


使用Array定義條件後的完成版:

接下來是我覺得很重要的一個功能,也是我終於把寫完的程式變為能普遍使用的功能的重要一步。

在我們完成這些句子後,設想接下來或許同理會想要找Color欄位中的不同顏色、Fruit欄位中的不同水果、Finance中的不同條件,但能如何應用與擴充現在的功能呢?答案是,把寫好的這個條件格式化自建為一個Excel的功能
做法很簡單,基本上就是完成兩項Sub,一個是把寫好的程式定義為功能,第二個則是在這excel試算表中運作剛剛定義好的功能。

為了要讓它變成可以自由擴充與應用的功能,把剛剛句子內專屬於搜尋水果相關的關鍵字拿掉。把剛剛conditionArray設定為一個未知變數,在此不知道有幾項條件所以用逗點自動分隔關鍵字,而把條件設定為keywords(其實就是剛剛的Condition的意思);另外用迴圈的方式來檢查,用我有限理解的能力來簡單解釋就是:

「這個條件我不知道有幾項,可能是i項,但從i=0開始檢查到跑完為止,把關鍵字都填入conditionArray中」。

其他的句子保持不變,那麼這個「功能」就被我們定義為 findInvalidColumn 了。接者第二個Sub再用程式把這功能叫出來,並且跟Excel說我要找的是水果還是顏色就好。在下面的例子裡,我要Excel幫我多跑一個程式,叫做find_No_Apple,而內容是幫我叫出剛剛以定義好的功能 findInvalidColumn。

根據剛剛的設定,這個公式的寫法如下:

findInvalidColumn(“你要找的欄位”, “你要找的值1,你要找的值2”)

請注意要找的值是用逗點做為分隔的,這點在剛剛的Split中被定義好了。

用自建的功能進行各項條件的篩選的完整版

寫完了!

這個系列文章被我寫了三個月,導致我在寫最後這篇文章時都忘記前面寫到哪裡了…不過這功能真是非常實用,我現在幾乎一開Excel就先讓它自動幫我檢查我報表中錯誤的值,而且這功能後面被應用的範圍無限廣泛,省下的時間與精力總是讓自動化變得有價值的原因所在。

雖然中間一度室友懷疑我是否要富堅停刊,但想到當時自己嘗試要做這件事情時在網路上都找不到相關的資源,有許多問題、卡在許多難關但卻都求助無門,就覺得不管怎樣都一定要把這系列完成,讓下一個想要做這件事情的人(或拿這個東西做更偉大應用的人)可以省一點精力、少踩一點地雷就好了。

希望有幫助到有需要的人。