1. 程式人生 > 電腦技巧 >Excel VBA 移除重複的陣列元素教學與範例

Excel VBA 移除重複的陣列元素教學與範例

使用 Dictionary 或 Collection 自動刪除陣列中所有重複的元素,只留下不重複的項目。


問題

假設我們有類似以下這樣的 Excel 表格,原始資料包含許多的項目,各個項目以逗號分隔,其中可能會包含重複的項目,我們想要刪除重複出現的項目,只留下不重複的部分,該怎麼處理?

重複的原始資料

解法

若要處理像這樣的重複性資料,可以先用 VBA 的 Split 將每個項目切成陣列,再使用一些去除重複性元素的 VBA 程式設計技巧,把重複的項目刪除,最後再將結果填回 Excel 表格中即可。

在開始撰寫 VBA 程式之前,請先啟用 Excel 內建的開發人員工具,接著建立一個新的 VBA 巨集程式,準備好 VBA 程式的開發環境之後,就可以開始撰寫 VBA 的程式了。

要刪除 VBA 陣列中重複的元素,有很多種方式,以下分別介紹使用 Dictionary 與 Collection 的方法。

Dictionary 方法

Dictionary 是一種儲存「鍵」(key)與「值」(value)對應的資料結構,一個「鍵」只會對應到一個「值」。

我們可以將陣列的所有元素都作為「鍵」(「值」使用固定值),放入 Dictionary 之中,然後再取出所有的「鍵」,這樣重複的陣列元素就會自然被刪除了,以下是實作的程式碼:

' 使用 Dictionary 刪除陣列重複元素

Function RemoveDupDict(rawArray As Variant) As Variant

Dim i As Long

Dim dict As Scripting.Dictionary

' 建立一個 Dictionary

Set dict = CreateObject("Scripting.Dictionary")

' 將陣列的每個元素取出來,放入 Dictionary 中

For i = LBound(rawArray) To UBound(rawArray)

dict.Item(rawArray(i)) = 1

Next i

' 傳回 Dictionary 的「鍵」

RemoveDupDict = dict.Keys

End Function在執行含有 Dictionary 的程式碼時,若出現「使用者自訂型態尚未定義」的編譯錯誤,請啟用 VBA 的「Microsoft Scripting Runtime」引用項目即可解決。

Collection 方法

Collection 儲存的資料是不重複的元素,若將重複的元素放入 Collection 的時候,會產生錯誤。

我們可以將所有的陣列元素放入 Collection 時,忽略重複元素所產生的錯誤,這樣就可以去除重複的元素了,以下是實作的程式碼:

' 使用 Collection 刪除陣列重複元素

Function RemoveDupColl(rawArray As Variant) As Variant

Dim i As Long

Dim coll As New Collection

Dim arr() As Variant

' 忽略重複的錯誤

On Error Resume Next

' 將陣列元素放入 Collection 中

For i = LBound(rawArray) To UBound(rawArray)

coll.Add CStr(rawArray(i)), CStr(rawArray(i))

Next i

' 清除錯誤

Err.Clear

' 設定結果陣列大小

ReDim arr(LBound(rawArray) To coll.Count - LBound(rawArray) - 1)

' 取出 Collection 的元素,放入結果陣列中

i = LBound(arr)

For Each item In coll

arr(i) = item

i = i + 1

Next

RemoveDupColl = arr

End Function

刪除 VBA 陣列重複元素

有了以上刪除陣列重複元素的函數之後,就可以直接應用在我們的問題上面了,接下來只要把 Excel 表格中的資料取出來,使用上面的函數刪除重複元素,再把結果寫回 Excel 表格中即可。

For i = 2 To 6

' 取出原始資料

rawData = Cells(i, 1).Value

' 檢查原始資料(除錯用)

Debug.Print ("原始資料:" & rawData)

' 以逗點分割資料

fruitArray = Split(rawData, ",")

' 檢查分割的資料(除錯用)

Debug.Print ("分割後的資料:")

For Each f In fruitArray

Debug.Print (f)

Next f

' 刪除重複元素

fruitArray = RemoveDupDict(fruitArray)

'fruitArray = RemoveDupColl(fruitArray)

' 檢查結果(除錯用)

Debug.Print ("刪除重複的資料:")

For Each f In fruitArray

Debug.Print (f)

Next f

' 將結果輸出至 Excel 表格中

Cells(i, 2).Value = Join(fruitArray, ",")

Next i這裡我放了很多的 Debug.Print 輸出除錯用的訊息,這在開發階段是很好用的技巧,程式寫好之後,可以把這些除錯用的部分刪掉。

刪除 VBA 陣列重複元素執行之後,就會得到這樣的結果:

執行結果參考資料:StackOverflow、wellsr.com、StackOverflow