今天我們來談談搜尋,傳統學習C的方式,在搜尋的程式寫法中,所的比對都必須用程式實現,也因此在以前學習的過程中有學過一些搜尋演算法,目的當然就是希望能增加搜尋的效能,不過在一些物件導向的程式語言中,其實,現在都有內建一些搜尋的函數,至於效能如何,由於現在的電腦的運算能力都很強,所以,效能也不至於太差。
所以,在VBA的語法中也提供Find/FindNext/FindPrevious的函數,就字面解釋,就類似excel或文字編輯軟體的搜尋功能,所以有往後找(FindNext)跟往前找(FindPrevious)的功能。
語法如下:
expression.Find (What, After, LookIn, LookAt, SearchOrder, SearchDirection, MatchCase, MatchByte, SearchFormat)
expression 代表 Range 物件的變數
What [必要] - 要搜尋的資料。 可以為字串或任何 Microsoft Excel 資料類型。
LookIn [選用] - 可以是下列其中一個 XlFindLookIn 常數︰xlFormulas、xlValues、xlComments 或 xlCommentsThreaded。
常用的是xlFormulas(公式)、xlValues(值),其他詳細的說明可以參考下面連結
https://docs.microsoft.com/zh-tw/office/vba/api/excel.xlfindlookin
LookAt [選用] - 可以為下列其中一個 xlLookAt 常數:xlWhole(與全部搜尋文字相符) 或 xlPart(與部分搜尋文字相符),其他詳細的說明可以參考下面連結。
https://docs.microsoft.com/zh-tw/office/vba/api/excel.xllookat
SearchOrder [選用] - 可以為下列其中一個 XlSearchOrder 常數:xlByRows(跨越列搜尋,然後移至下一列) 或 xlByColumns(向下通過欄搜尋,然後移至下一欄),
其他詳細的說明可以參考下面連結。
https://docs.microsoft.com/zh-tw/office/vba/api/excel.xlsearchorder
SearchDirection [選用] - 搜尋方向,可以為下列其中一個 XlSearchDirection 常數:xlNext(搜尋範圍中的下一個符合值) 或 xlPrevious(搜尋範圍中的上一個符合值),
其他詳細的說明可以參考下面連結。
https://docs.microsoft.com/zh-tw/office/vba/api/excel.xlsearchdirection
MatchCase [選用] - True 表示搜尋會區分大小寫。 預設值為 False。
MatchByte [選用] - 只有當您已選取或安裝雙位元組語言支援時,才能使用。 若為 True,則雙位元組字元只能符合雙位元組字元。
若為 False,則雙位元組字元可符合其對等的單位元組字元。
以下,月光俠分享一下我自己常用的一些寫法。
一般而言,通常我們都只會使用到What這個變數,但是這樣就要確保相同的字串沒有被重複使用。
為了確保這件事情,我們可以使用限制範圍的做法,例如下面的寫法,我們就是把搜尋的範圍限制在第二列
ActiveSheet.Range("2:2").Cells.Find("Type").Column
如果要把範圍限制在第A行,我們可以這樣寫
ActiveSheet.Range("A:A").Cells.Find("Type")
如果把範圍限制在A3到E8,則可以這樣寫
ActiveSheet.Range("A3:E8").Cells.Find("Type")
如果是下面這個寫法,則會在Register_Index這個sheet中,做全域的搜尋
Sheets("Register_Index").Cells.Find("PAGE")
也可以在當下這個sheet中做全域的搜尋,寫法如下:
ActiveSheet.Cells.Find("PAGE")
把"ActiveSheet."省略掉,寫成下面的寫法,效果也是一樣喔!!
Cells.Find("PAGE")
Find這個函數的回傳值是一個物件,我們也可以直接取出這個回傳物件的相關屬性出來使用,例如第幾列(row)或第幾行(Column)來使用,寫法可參考下面的範例。
Dim R_PAGE, L_CRC_IDX As Integer
R_PAGE = Sheets("Register_Index").Cells.Find("PAGE").row
L_CRC_IDX = Sheets("Register_Index").Cells.Find("CRC").Column
也許有人會問row的第一個字母是小寫,但是Column的第一個字母卻是大寫,這我也不是很清楚,因為編輯器就會自動做這樣的修正,如果有朋友知道原因的,也歡迎留言跟我說。
再來看一下這個範例:
If Cells.Find(Sheets("RX_Digital_TOP").Cells(j, 9).Value, LookAt:=xlWhole) Is Nothing Then
Cells(i, L_BS_NAME).Value = Sheets("RX_Digital_TOP").Cells(j, 9).Value
Cells(i, L_BS_NAME).Font.ColorIndex = 3
i = i + 1
End If
上面這個範例,我們來探討兩件事情:
第一,如果搜尋不到要如何處理?這個範例就是在處理這件事情,如果沒有找到符合的儲存格,則此方法會傳回 Nothing。
第二,這個範例中除了What這個參數外,我們使用到了LookAt。LookAt:=xlWhole代表儲存格裡的文字必須與全部搜尋文字相符,才算是符合搜尋條件(大小寫視為相同)。
其實為了減少重覆搜尋到類似的字串,精確的使用LookAt與MatchCase這兩個參數,以及搭配搜尋範圍的明確指定,可以達到很好的效果。
https://docs.microsoft.com/zh-tw/office/vba/api/excel.range.find
