大家好,我們今日繼續講解VBA數組與字典解決方案第22講:在VBA中如何使用動態數組,以及利用動態數組去除重複值的方法。如果文本中含有大量的重複值,此時,如果我們要剔除重複值,該怎麼辦?用VBA的方法該如何做到呢?我在這講和下一講中將解答這個問題,並提供給讀者一個可以測試的實例。今日先講這個內容要用到的知識點。
一 :Filter函數:這個函數返回一個下標從零開始的數組,該數組包含基於指定篩選條件的一個字符串數組的子集,語法如下:Filter(sourcesrray, match[, include[, compare]])
參數
a) sourcesrray是必須的,要執行搜索的一維字符串數組。
b) match是必須的,要搜索的字符串。
c) include是可選的,Boolean值,表示返回子串是否包含match字符串。如果參數include是True,Filter函數返回的是包含match參數子字符串的數組子集。如果參數include是False,Filter函數返回的是不包含match參數子字符串的數組子集。
d) compare是可選的,所使用的字符串比較類型。
二:ReDim語句,這個語句在過程級別中使用,用於為動態數組變量重新分配存儲空間,語法如下:
ReDim [Preserve] varname(subscripts) [As type] [, varname(subscripts) [As type]]
參數
a) Preserve是可選的,關鍵字,當改變原有數組最末維的大小時,使用此關鍵字可以保持數組中原來的數據。
b) varname是必須的,變量的名稱。
c) subscripts是必須的,數組變量的維數,最多可以定義 60 維的多維數組,使用下面的語法;[lower To] upper [,[lower To] upper]
使用動態數組去除文本中的重複值,如下面的代碼所示。
Sub MyNZsz_5() '第22講 利用數組排重的方法
Dim Splarr() As String
Dim Arr() As String
Dim Temp() As String
Dim r As Integer
Dim i As Integer
On Error Resume Next
Splarr = Split(Sheets("22").Range("a1"), " ")
For i = 0 To UBound(Splarr)
Temp = Filter(Arr, Splarr(i))
If UBound(Temp) < 0 Then
r = r + 1
ReDim Preserve Arr(1 To r)
Arr(r) = Splarr(i)
End If
Next
Sheets("22").Range("a5").Resize(r, 1) = Application.Transpose(Arr)
End Sub
代碼解析:
MySplitarr過程將工作表Sheets("22")中A1單元格的文本去除重複值後寫入到工作表Sheets("22")中的A列單元格。
第2行代碼聲明數組Splarr用來保存Sheets("22")中A1單元格的文本。
第3行代碼聲明數組Arr用來保存去除重複值後的文本。
第4行代碼聲明數組Temp用來判斷文本是否重複。
第5行代碼聲明變量r用來保存去除重複值後的文本數量。
第7行代碼啟動錯誤處理程序來忽略錯誤,因為在程序運行到第11行代碼會發生下標越界錯誤。
第8行代碼使用Split 函數以Sheets("22")中A1單元格的文本創建一個下標從零開始的一維數組。
第9行代碼使用For...Next語句遍歷數組Splarr的所有元素。
第10行代碼使用Filter函數創建一個數組Temp用來保存以當前Splarr數組的值在Arr數組中的搜索結果。
第11行代碼根據返回的數組Temp的最大下標來判斷當前Splarr數組的值是否重複。在使用使用Filter函數時如果沒有相匹配的值,將返回一個空數組,最大下標小於0。如果沒有找到,返回的結果是-1.
第12行代碼如果當前Splarr數組的值不重複則將變量r的值加1。
第13行代碼重新定義動態數組大小。
第14行代碼將不重複值添加到數組Arr中。
第15行代碼使用工作表Transpose函數將去除重複值的的文本轉置後寫入到工作表單元格中。
代碼的截圖:
運行前的截圖:很顯然有很多的重複數值:
運行後的截圖:
今日內容回向:
1 上述代碼是否清楚了它的運行過程呢?
2 第7行代碼啟動錯誤處理程序來忽略錯誤,這是為什麼呢?