返回列表 上一主題 發帖

[發問] 排除儲存格內的重複資料

[發問] 排除儲存格內的重複資料



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

尋求大家幫忙,謝謝

排除重複.rar (1.54 KB)

本帖最後由 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
複製代碼

TOP

謝謝,可解決
可是看不太懂程式內容
可否麻煩大概說明

TOP

本帖最後由 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
複製代碼

TOP

回復 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
複製代碼
感恩的心......(在麻辣家族討論區.用心學習會有進步的)
但資源無限,後援有限,  一天1元的贊助,人人有能力.

TOP

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

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

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

感謝

TOP

回復 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
複製代碼

TOP

感謝 stillfish00 詳細說明
藉此可以更了解dictionary及學習應用

TOP

回復 7# stillfish00
同樣感謝 stillfish00 對字典的詳細說明,
一個對 字典 很陌生的我, 真的很感謝

TOP

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

執行前:


執行結果:



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
用行動裝置瀏覽論壇學習很方便,謝謝論壇經營團隊
請大家一起上論壇來交流

TOP

        靜思自在 : 能幹不幹,不如苦幹實幹。
返回列表 上一主題