Categories: Excel

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

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

問題

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

重複的原始資料

解法

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

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

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

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 陣列重複元素

執行之後,就會得到這樣的結果:

執行結果

參考資料:StackOverflowwellsr.comStackOverflow

Share
Published by
Office Guide
Tags: VBA

Recent Posts

Python 使用 PyAutoGUI 自動操作滑鼠與鍵盤

本篇介紹如何在 Python ...

9 個月 ago

Ubuntu Linux 以 WireGuard 架設 VPN 伺服器教學與範例

本篇介紹如何在 Ubuntu ...

9 個月 ago

Linux 網路設定 ip 指令用法教學與範例

本篇介紹如何在 Linux 系...

9 個月 ago

Windows 使用 TPM 虛擬智慧卡保護 SSH 金鑰教學與範例

本篇介紹如何在 Windows...

10 個月 ago

Linux 以 Shamir’s Secret Sharing 分割保存金鑰教學與範例

介紹如何在 Linux 中使用...

11 個月 ago

Linux 以 Cryptsetup、LUKS 加密 USB 隨身碟教學與範例

介紹如何在 Linux 系統中...

11 個月 ago