VBA裏的文本函數 find() search() substitute() replace() match() large() 在EXCEL工作表使用和VBA中使用差別的對比

 

1 find()

1.1 worksheetfunction.find()

  • 工作表函數
  • FIND(find_text, within_text, [start_num])
  • FINDB(find_text, within_text, [start_num])    中文字符等會識別爲2位
  • 返回的是 要查找的內容在字符串內的位數。

 

  • 侷限性
  • 區分大小寫,不允許通配符 
  • 如果在VBA中使用,記得字符串,是需要"" 表達的
  • 也是模糊查詢
Sub test501()

Debug.Print WorksheetFunction.Find(a, Range("B3").Value)
Debug.Print WorksheetFunction.Find(Range("d5").Value, Range("B3").Value)
Debug.Print WorksheetFunction.Find("a", Range("B3").Value)
Debug.Print WorksheetFunction.Find(3, Range("B3").Value)

End Sub

 

 

1.2  worksheetfunction.find()  使用注意點

  • 如果在EXCEL內使用
  • 如果查找的內容找不到,find() 不會報錯,而是返回第1個字符串的位置,一般會返回1,其實已經是算報錯了!
  • 另外,引用單元格的值,就相當於使用了變量,不需要特別加 字符串也不需要特別加 ""
  • 但如果是在公式裏寫字符串,也需要加""  

 

  • 如果在VBA中使用
  • 首先儘量不要再VBA中用工作表函數,因爲一旦健壯性差,一旦查不到會報錯,如下圖
  • 字符串要加"",除非是引用單元格range的值。

 

1.3 application.find()     返回的是range

  • 在VBA中用工作表函數,儘量用 application.find() 而儘量不用 worksheetfunction.find(),這兩者語法和功能類似。
  • application.find()  雖然有些情況只會返回 錯誤,但有些情況再VBA裏也會 彈出報錯
  • application.worksheetfunction.find() 更適合工作表
  • application.find() 更適合VBA
  • 雖然VBA可能自帶一些函數,比如VBA.find() 就沒有,但即使有,和application的功能一般都是不同的。
Sub test503()

Debug.Print Application.Find(a, Range("B3").Value)
Debug.Print Application.Find(Range("d5").Value, Range("B3").Value)
Debug.Print Application.Find("a", Range("B3").Value)
Debug.Print Application.Find(3, Range("B3").Value)

Debug.Print Application.Find("aaaa", Range("B3").Value)  '找不到會返回錯誤值,但不會跳出錯誤提示


End Sub

 

1.4  application.find() 的問題----主要適合在一個字符串內查找!而且類型不匹配的話也會 跳出報錯。

  • 首先,先弄清楚
  • application.find 和 application.worksheetfunction.find 都源於 工作表
  • 而在工作表中,多少情況下,都是查找一個單元格的內容----一般都是字符串
  • 而 application.find() 就是查找一個單元格里的元素 ,只能查找一個字符串的內容

 

  • 實測只適合字符串,不適合多個單元格的range,數組等
  • 如果,查找的範圍是數組,或多個單元格的range,會報錯,類型不匹配

 

  • application.find() 雖然可以有些情況下,可以返回 error 2015 
  • 但是一旦查找的內容,找不到,也可能會彈出報錯,VBE編輯器好像不穩定,多次運行的結果不同

 

Sub test505()

Debug.Print Application.Find(2, "a12345")
Debug.Print Application.Find(3, Range("b10"))
Debug.Print Application.Find("aaaa", Range("b10").Value)  '實測VBE不穩定,有時候也會彈出報錯

'查不到的內容也會報類型不匹配
'Debug.Print "Application.Find(9, ""a12345"") " & Application.Find(9, "a12345")
'Debug.Print "Application.Find(""aaa"", ""a12345"") " & Application.Find("aaa", "a12345")


'下面會報錯類型不匹配
'Debug.Print "Application.Find(1, Array(1, 2, 3))  " & Application.Find(1, Array(1, 2, 3))
'Debug.Print "Application.Find(2, Range(""B1: B2 "")) " & Application.Find(2, Range("B1:B2"))
End Sub

 

1.5 VBA.find()  和 find()  ,這兩個函數並沒有,不存在

 

1.6 object.find()

  • 語法
  • Find(What, After, LookIn, LookAt, SearchOrder, SearchDirection, MatchCase, MatchByte, SearchFormat)
  • find()一般是爲了查詢結果,返回的是找到的對象 range

 

  • 侷限性
  • 是模糊查詢
  • 只會返回查找到的第一個range()--單元格
Sub test502()
Dim a As Object   'find返回的應該是 range對象
Set a = ActiveWorkbook.ActiveSheet.UsedRange.Find(what:=2, LookIn:=xlValues)
Debug.Print a.Address


'這句話語法上OK,但因爲find() 本身的目的,不返回find()的值,這麼寫顯得很奇怪
ActiveSheet.UsedRange.Find what:=2, LookIn:=xlValues
'ActiveSheet.UsedRange.Find(what:=2, LookIn:=xlValues) '這樣會報錯

End Sub

詳細了find()函數的說明,以後再學習

 

1.7   Application.find() 和 obejct.find() 的區別,語法和返回值都不同。

  • 這兩者的語法差別很大
  • application.find() 是工作表相關的,返回的是找到的字符串的位置
  • obejct.find() 是VBA相關的,返回的是range

 

 

2  search()  ----不區分大小寫,可以加通配符,其他類似find()

2.1  worksheetfunction.search()

  • 語法
  • search(find_text, within_text, [start_num])
  • =SEARCH("n","printer")
  • =SEARCH("base","database")    會返回字符串首字母的位置
  • search()
  • searchB()  

 

  • 侷限性
  • search() 是不區分大小寫的
  • 也是模糊查詢

 

2.2 application.search()

Sub test503()

Debug.Print Application.Search(a, Range("B3").Value)
Debug.Print Application.Search(Range("d5").Value, Range("B3").Value)
Debug.Print Application.Search("a", Range("B3").Value)
Debug.Print Application.Search(3, Range("B3").Value)

Debug.Print Application.Search("aaaa", Range("B3").Value)  '找不到會返回錯誤值,但不會跳出錯誤提示

End Sub

 

2.3 object.search() 沒有

 

2.4 search() 沒有

 

2.5 VBA中取代search() 和 find() 的是  vba.instr()

 

2.6 VBA.instr() 語法,但是並沒有object.instr()

  • InStr([start,]string1,string2[,compare])
  • Start - 一個可選參數。指定搜索的起始位置。搜索從第一個位置開始,從左到右。
  • String1 - 必需的參數。要搜索的字符串。
  • String2 - 必需的參數。要在String1中搜索的字符串。
  • Compare - 一個可選參數。指定要使用的字符串比較。它可以採取以下提到的值:
  • 0 = vbBinaryCompare - 執行二進制比較(默認)
  • 1 = vbTextCompare - 執行文本比較/
Sub test504()

Debug.Print InStr(1, Range("B3").Value, Range("d5").Value)


Dim a
a = InStr(1, Range("B3").Value, Range("d5").Value)
Debug.Print a

End Sub

 

3 substitute

3.1 worksheetfunction.substitute() 基本語法

  • SUBSTITUTE(text,old_text,new_text,instance_num)
  • 可以實現
  • 可以實現替換第幾個,這個比  worksheetfunction.find()好用
  • 侷限性,不支持通配符

 

3.2  worksheetfunction.substitute()  和application.substitute()

  • worksheetfunction.substitute()  和application.substitute() 即使找不到合適的替換內容也不會報錯
  • substitute 不一定需要返回值,所以可以採用 不加括號的單獨句子寫法
Sub test505()

Application.WorksheetFunction.Substitute "abc123abc123abc", "abc", "AAA", 2
Debug.Print Application.WorksheetFunction.Substitute("abc123abc123abc", "abc", "AAA", 2)
Debug.Print Application.WorksheetFunction.Substitute("abc123abc123abc", "abcd", "AAA", 2)
Debug.Print

Application.Substitute "abc123abc123abc", "abc", "AAA", 2
Debug.Print Application.Substitute("abc123abc123abc", "abc", "AAA", 2)
Debug.Print Application.Substitute("abc123abc123abc", "abcd", "AAA", 2)


End Sub

 

3.3 VBA裏好像沒有 subsitute() 相關的函數

 

 

4 replace()  

4.1 worksheetfunction.replace()

  • 語法
  • REPLACE(old_text, start_num, num_chars, new_text)
  • 支持通配符
  • 和substitute() 完全不同,是按位數替換,而不是查找關鍵字式替換。

 

 

4.2 object.replace() 可以算是VBA中 replace()  和 substitute() 的替代功能

  • 語法
  • Selection.Replace What:="¥", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ReplaceFormat:=False
  • replace() 返回的是 bool,除了做if判斷等,一般很少調用,做替換操作纔行。
Sub test302()
 
'ActiveSheet.UsedRange.Replace what:=6, replacemeent:=666
Range("a1:d10").Replace what:=6, replacement:=666
'這個是模糊查找,不是精確查找,所以替換可能不是想要的,比如66會變成666666
 
'replace()也有返回值,是布爾值,除了做判斷可能調用其返還值,一般執行操作就可以
a = Range("a1:d10").Replace(what:=6, replacement:=666)
Debug.Print a

End Sub

 

4.3 支持通配符,但是其操作的對象,返回的缺不是對象,而返回bool

所以一般情況下, object.replace() 函數不用來返回值,只用來操作。

  • 操作成功,修改了單元格的值
  • 但是返回的只是bool,而沒能返回結果
Sub test507()

'ActiveSheet.UsedRange.Replace what:=6, replacemeent:=666
Range("b3").Replace what:=1 * 3, replacement:=666
'這個是模糊查找,不是精確查找,所以替換可能不是想要的,比如66會變成666666
'repalce()支持通配符
Debug.Print



a = Range("b3").Replace(what:=1 * 3, replacement:=666)
Debug.Print a
'replace()也有返回值,是布爾值,除了做判斷可能調用其返還值,一般執行操作就可以
'replace雖然是操作的對象,但其返回值卻不是對象...,而是是否替換成功
'可能replace() 函數設計的目的主要還是爲了操作,不是爲了返回值吧


End Sub

 

5 large()  和 small()

5.1 worksheetfunction.large()  和  worksheetfunction.small()

  • 好像沒有對應的VBA函數
  • worksheetfunction.large()  如果指定不合適和報錯
  • 在VBA中儘量使用 application.large()
Sub test508()

Debug.Print WorksheetFunction.Large(Range("H1:H5"), 2)
a = Application.Large(Range("H1:H5"), 2)
Debug.Print a
Debug.Print

'Debug.Print WorksheetFunction.Large(Range("H1:H5"), 10)  '這樣會報錯
a = Application.Large(Range("H1:H5"), 10)
Debug.Print a
Debug.Print

'b = Large(Range("H1:H5"), 2)
'Debug.Print b

End Sub

 

6 application.match()

  • worksheetfunction.match()
  • application.match()  隨便有些情況只會返回錯誤,不會跳出報錯,但有些情況下在VBA裏也會跳出報錯的

 

6.1 錯誤舉例

  • 錯誤的思路:沒有先考慮出錯處理
  • application.match() 查不到會報錯,無法取得 match 屬性

 

6.2 正確代碼

Sub aa31()
On Error Resume Next
in1 = Int(InputBox("請輸入1個要查的數字"))
a = WorksheetFunction.Match(in1, Array(1, 2, 3, 4, 5), 0)

If Err = 0 Then
   Debug.Print a
Else
   Debug.Print "沒找到!"
End If
End Sub

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章