Board logo

標題: [發問] 排除儲存格內的重複資料 [打印本頁]

作者: 巴克斯    時間: 2013-10-22 17:29     標題: 排除儲存格內的重複資料

[attach]16447[/attach]

如上表,希望將"原資料"欄內,把後面有重複字串的部分移除
產出"排除重複" 的結果
並計算原資料筆數及新資料筆數

尋求大家幫忙,謝謝

[attach]16448[/attach]
作者: stillfish00    時間: 2013-10-22 19:59

本帖最後由 stillfish00 於 2013-10-22 20:05 編輯

回復 1# 巴克斯
  1. Sub Test()
  2.   Dim ar, d, i As Long, s
  3.   
  4.   Set d = CreateObject("scripting.dictionary")
  5.   With Sheets(1)
  6.   With .Range(.[A2], .[A2].End(xlDown)).Resize(, 2)
  7.     ar = .Value
  8.     For i = 1 To UBound(ar)
  9.         d.RemoveAll
  10.         For Each s In Split(ar(i, 1), ",")
  11.           d(s) = ""
  12.         Next
  13.         ar(i, 1) = Join(d.keys, ",")
  14.         ar(i, 2) = d.Count
  15.     Next
  16.     .Offset(, 2).Value = ar
  17.   End With
  18.   End With
  19. End Sub
複製代碼

作者: 巴克斯    時間: 2013-10-23 12:10

謝謝,可解決
可是看不太懂程式內容
可否麻煩大概說明
作者: stillfish00    時間: 2013-10-23 14:35

本帖最後由 stillfish00 於 2013-10-23 14:39 編輯

回復 3# 巴克斯
字典物件說明可參考 http://forum.twbts.com/thread-20-1-1.html
其餘函式請查閱說明。

主要流程為:
對儲存格文字以逗號分解成陣列 (Split函式),
然後存入字典時順便利用字典物件  鍵值必定唯一  來進行篩選 (d(s) = ""),
取回篩選過的所有值 (d.keys),再用逗號合成單一字串 (Join函式),然後寫回儲存格。
  1. Sub Test()
  2.   Dim ar, d, i As Long, s
  3.   
  4.   Set d = CreateObject("scripting.dictionary")  '建立字典物件
  5.   With Sheets(1)
  6.   With .Range(.[A2], .[A2].End(xlDown)).Resize(, 2)  '相當於[A2:B8]
  7.     ar = .Value  '一次性從excel取出
  8.     For i = 1 To UBound(ar)
  9.         d.RemoveAll  '移除所有值
  10.         For Each s In Split(ar(i, 1), ",")  '以逗號分解為陣列
  11.           d(s) = ""
  12.         Next
  13.         ar(i, 1) = Join(d.keys, ",")  '結合陣列為單一字串
  14.         ar(i, 2) = d.Count '元素個數
  15.     Next
  16.     .Offset(, 2).Value = ar  '一次性寫回excel
  17.   End With
  18.   End With
  19. End Sub
複製代碼

作者: GBKEE    時間: 2013-10-23 15:15

回復 1# 巴克斯
  1. InStr 函數
  2. 傳回在某字串中一字串的最先出現位置,此位置為 Variant (Long)。
複製代碼
  1. Option Explicit
  2. Sub Ex()
  3.     Dim i As Integer, e As Variant, Ar As String
  4.     i = 2
  5.     Do While Cells(i, "a") <> ""
  6.         Ar = ","
  7.         For Each e In Split(Cells(i, "a"), ",")
  8.             If InStr(Ar, "," & e & ",") = 0 Then Ar = Ar & e & ","
  9.         Next
  10.         Cells(i, "C") = Mid(Ar, 2, Len(Ar) - 2)
  11.         Cells(i, "D") = UBound(Split(Mid(Ar, 2), ","))
  12.         i = i + 1
  13.     Loop
  14. End Sub
複製代碼

作者: 巴克斯    時間: 2013-10-24 12:35

謝謝stillfish00 及 GBKEE
兩位簡潔的程式及解說,又學了新的想法跟做法

不過對dictionary比較陌生
stillfish00 的解說大致了解,但是部份說明還是不懂

然後存入字典時順便利用字典物件  鍵值必定唯一  來進行篩選 (d(s) = "")
d(s)="" 來進行篩選可以再解釋細部的設定意義嗎?

感謝
作者: stillfish00    時間: 2013-10-24 14:28

回復 6# 巴克斯
字典如同陣列或Collection,可以想成是存放多筆資料的容器,
其存放的每一筆資料都會包含兩部分:索引值(或稱鍵值、Key)和資料內容
像陣列一樣,索引值必須唯一
但和陣列比較起來,使用字典的好處很多,如:
        索引值不必為數字,可以是有意義的名稱。
        容易隨時新增和移除,不必事先宣告陣列大小。
        有Exists方法容易查找是否包含有某個元素,不必使用迴圈逐一檢查。

前面用的 d(s) 意思就是取得字典d中,對應到s的那筆資料的內容。
d(s) = "" 就是修改對應到s的該筆資料的內容為""

又因為字典的一個特性:
當對字典用索引取回時,若字典不包含該索引值時會自動加入該索引值到字典內
所以用 d(s) = "" 修改內容時,也會把字典中不存在的s加入。

或者,你也可以用這樣的方法寫:
  1.   For Each s In Split(ar(i, 1), ",")
  2.     If Not d.exists(s) Then
  3.       d.Add s, ""
  4.     End If
  5.   Next
複製代碼

作者: 巴克斯    時間: 2013-10-25 12:10

感謝 stillfish00 詳細說明
藉此可以更了解dictionary及學習應用
作者: yen956    時間: 2014-4-19 04:54

回復 7# stillfish00
同樣感謝 stillfish00 對字典的詳細說明,
一個對 字典 很陌生的我, 真的很感謝
作者: Andy2483    時間: 2023-4-18 11:15

謝謝論壇,謝謝各位前輩
後學藉此帖練習陣列與字典,在同一陣列裡將新值覆蓋舊值,之後寫入目標格,
學習方案如下,請各位前輩指教

執行前:
[attach]36171[/attach]

執行結果:
[attach]36172[/attach]


Option Explicit
Sub TEST_2()
Dim Brr, Y, Z, i&, j&, T$, xR As Range
Set Y = CreateObject("Scripting.Dictionary")
Set xR = Range([B1], Cells(Rows.Count, 1).End(3)): Brr = xR
For i = 2 To UBound(Brr)
   If i = 2 Then Brr(1, 1) = "排除重複": Brr(1, 2) = "新筆數"
   Z = Split(Brr(i, 1), ",")
   For j = 0 To UBound(Z)
      If Y(i & "|" & Z(j)) = "" Then
         T = Y(i)
         If T = "" Then T = Z(j) Else: T = T & "," & Z(j)
         Brr(i, 1) = T: Y(i) = T: Y(i & "|" & Z(j)) = 1
         Y(i & "|c") = Y(i & "|c") + 1: Brr(i, 2) = Y(i & "|c")
      End If
   Next
Next
With xR.Offset(0, 2)
   .EntireColumn.ClearContents
   .Value = Brr
End With
Set Y = Nothing: Set xR = Nothing: Erase Brr, Z
End Sub




歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)