標題:
[發問]
excel VBA 從大量資料中裡找出共同重複的資料
[打印本頁]
作者:
Duck
時間:
2014-3-20 10:43
標題:
excel VBA 從大量資料中裡找出共同重複的資料
我想要從1.2.3 找出他們三個相同的資料出來,如圖所示三個共同相同的地方是B C D,
請問我要怎樣寫VBA的語法?
圖上的例子我只用1.2.3這三個而已,實際上是有n筆資料的,所以寫請問大大們,要如何從n筆資料找出共同的地方出來?
作者:
Hsieh
時間:
2014-3-20 12:09
回復
1#
Duck
同一群組內有重複的話算嗎?
作者:
Duck
時間:
2014-3-20 14:06
因為已經篩選過,所以基本上同一個群組不會有重複
作者:
Hsieh
時間:
2014-3-20 14:41
本帖最後由 Hsieh 於 2014-3-20 14:47 編輯
回復
3#
Duck
Sub ex()
Dim Rng As Range
Set d = CreateObject("Scripting.Dictionary")
Set Rng = Range([B1], [B1].End(xlDown))
For Each a In Rng
If Application.CountIf(Rng, a) > 1 Then d(a.Value) = ""
Next
If d.Count > 1 Then [D2].Resize(d.Count, 1) = Application.Transpose(d.keys)
End Sub
複製代碼
用進階篩選也可以辦到
[attach]17830[/attach]
作者:
Duck
時間:
2014-3-20 15:46
回復
4#
Hsieh
成功了! 十分感謝高手的幫忙
作者:
Duck
時間:
2014-4-10 11:16
回復
4#
Hsieh
不好意思您好,另外想在更進階的問您,上次找的是全部同時出現再篩選出來的結果,但現在我要換成用百分比去篩選出結果要如何改VBA?[attach]17971[/attach]
假設有三個如圖片上這樣的工作表單,我們如何要寫VBA篩選出來80%出現的英文字母?
接著再來,那三個工作表單都篩選出出現80%的字母後,把三個表單的篩選結果結合在一起後,我們要如何計算出他們各自出現的百分比例是多少?[attach]17972[/attach][attach]17972[/attach]
想問您這些要如何用VBA去撰寫??? 可以幫幫我嗎??:'(
作者:
Duck
時間:
2014-4-11 20:11
回復
4#
Hsieh
真的不好意思~請問Hsieh先生,我對於VBA真的還不是很熟悉,所以想請問您有辦法幫幫我昨日的那個問題嗎??
還是我應該再重新發貼問呢?
作者:
Hsieh
時間:
2014-4-11 21:27
回復
7#
Duck
問題是並不清楚你的需求
是要每個工作表各別篩選還是3個工作表合計後篩選?
佔80%是以上還是剛好?
做個簡單範例檔壓縮上傳說明應該比較容易了解你的需求
作者:
Duck
時間:
2014-4-11 22:04
回復
8#
Hsieh
[attach]17985[/attach]
不好意思,您好~前三個工作表是要"各自"篩選出現80%以上的字母出來,再來,工作表4是假設前三個工作表篩選出來後結果的整合起來的資料(附件上工作表4的結果不是正確結果),接著我們如何顯示出工作表4裡面B欄位上每個英文字母在工作表4上出現的比率為多少?例如:字母A在工作表4上出現的百分比為1/14(約為7%)
請問這些該如何用VBA撰寫?
作者:
Duck
時間:
2014-4-14 10:57
回復
8#
Hsieh
想請問一下,不知您是否了解我的問題了嗎? 這有辦法用vba執行嗎?
作者:
Hsieh
時間:
2014-4-17 22:38
回復
10#
Duck
計算各自母的出現率不難,但實在不解前3個工作表的字母要求出現率在80%以上
幾乎不可能啊!
假設有,那就是要顯示到工作表4的B欄嗎?
那跟A欄的資料又有甚麼關聯?
上傳的範例最好是能顯示想要的結果,否則很難看出你的需求
作者:
yen956
時間:
2015-12-31 20:10
本帖最後由 yen956 於 2015-12-31 20:12 編輯
回復
4#
Hsieh
超版你好!!
請問: If Application.CountIf(Rng, a) > 1 Then d(a.Value) = ""
中的 d(a.Value) = "" 是什麼意思?
猜想是將 a 的 Key 丟到字典中, 或是將 a 的 Item 丟到字典中,
但為什麼是 d(a.Value) = "" 呢? 作用是什麼?
謝謝!!
作者:
c_c_lai
時間:
2016-1-1 08:06
回復
12#
yen956
[attach]23025[/attach]
作者:
hcm19522
時間:
2016-1-1 09:39
http://blog.xuite.net/hcm19522/twblog/369872449
函數 參考即可
作者:
GBKEE
時間:
2016-1-1 10:15
本帖最後由 GBKEE 於 2016-1-1 10:16 編輯
回復
12#
yen956
vba的說明
Dictionary 物件
物件,用於儲存資料關鍵字和項目對。
語法
Scripting.Dictionary
請注意
Dictionary 物件與 PERL 相關陣列全等。可以是任何型式的資料的項目被儲存在陣列中。每個項目都與一個唯一的關鍵字相關。該關鍵字用來取出單個項目,通常是整數或字串,可以是除陣列外的任何型態。
下面的程式碼舉例說明了如何建立一個 Dictionary 物件:
Dim d '建立一個變數
Set d = CreateObject(Scripting.Dictionary)
d.Add "a", "Athens" '加入一些關鍵字和項目
d.Add "b", "Belgrade"
d.Add "c", "Cairo"
複製代碼
9#附檔的程式碼試試看
Option Explicit
Sub Ex()
Dim d As Object, E As Variant, AR(1 To 3), i As Integer
Dim Rng As Range, AX(), M As Variant
Set d = CreateObject("SCRIPTING.DICTIONARY")
'工作表1-> 工作表3 '出現機率為80%的字母*****
For i = 1 To 3 '"工作表1"->"工作表3" 在活頁簿上的 Index
MsgBox Sheets(i).Name '可註解掉
With Sheets(i).Range("B:B").SpecialCells(xlCellTypeConstants).Offset(, 1)
.Cells = "=COUNTIF(C2,RC[-1])/COUNTA(C1)" '儲存格寫上公式
AR(i) = Application.WorksheetFunction.Transpose(.Offset(, -1).Resize(, 2).Value)
'AR(i) 導入英文字母出現百分比機率
For Each E In .Cells
If E >= 0.8 Then d(E.Offset(, -1).Value) = ""
Next
.Cells = .Value '公式轉為值
.NumberFormatLocal = "0%" '數字格式化
.Cells.Offset(, 1) = ""
If d.Count >= 1 Then
.Cells(1).Range("B1").Resize(d.Count) = Application.WorksheetFunction.Transpose(d.keys)
End If
End With
d.RemoveAll
Next
'***工作表4 上B欄位中,每個英文字母出現在指定工作表的比率***
Set Rng = Sheets("工作表4").Range("A1")
i = 0
Do Until Rng Is Nothing
AX = AR(Sheets(Rng.Value).Index) '"工作表1"->"工作表3" 在活頁簿上的 Index
'AR(Sheets(Rng.Value).Index) 導出各個工作表上英文字母的機率
M = Application.Match(Rng.Offset(i, 1), Application.Index(AX, 1), 0)
'Application.Match 工作表函數
With Rng.Offset(i, 2) 'C欄
If Not IsError(M) Then
.Cells = AX(2, M)
Else
.Cells = 0
End If
.NumberFormatLocal = "0%"
End With
i = i + 1
If Rng.Offset(i) <> "" Then '下一個工作表
Set Rng = Rng.Offset(i)
i = 0
ElseIf Rng.Offset(i, 1) = "" Then '沒有字串
Set Rng = Nothing '離開迴圈的條件
End If
Loop
End Sub
複製代碼
作者:
准提部林
時間:
2016-1-1 11:13
本帖最後由 准提部林 於 2016-1-1 11:16 編輯
回復
12#
yen956
d(a.Value) = ""
__key 為 a.value , item 為 空字符
key者,可稱其為〔索引值〕,具〔唯一不重覆〕性,
若只想取出不重覆項目,item 就不須處理,所以給個任意資料,一般給空字符即可!
要注意:1.文字格式與數值格式的純數字,或英文的大.小寫,放在 key 中是視為不同的!
2.key 的來源若為〔儲存格參照〕,必須使用 rng.value 或 rng.text 或 rng & "" 方式,
這時就涉及〔數值〕與〔文字〕格式的問題,依需求去決定其格式!
例如:A1為〔日期〕2016/01/01,自訂格式為〔YYYY/MM/DD],亦即其值為〔數值〕42370,只是格式看起來為日期,
那麼,[A1].Value 為 2016/1/1 等同 42370
[A1].Text 則為〔文字〕2016/01/01
[A1] & "" 又為〔文字〕2016/1/1
Sub 測試()
Set xD = CreateObject("Scripting.Dictionary")
xD([A1].Value) = ""
xD([A1].Text) = ""
xD([A1] & "") = ""
xD(42370) = ""
MsgBox xD.Count '只有3而非4個,因第1及第4〔值〕相同
End Sub
=====================================
至放 item 因各種需求,可做很多的變化,一時說不清,可多找找更多實際範例看看∼∼
作者:
yen956
時間:
2016-1-1 13:01
感謝c_c_lai, GBKEE, 准提部林 等大大的說明,
因為一般文件只提到 d.Add "a", "Athens" 的方法,
現在總算知道 d(a.Value) = "" 這個方法的真正函義,
d(a.Value) = "" __key 為 a.value , item 為 空字符
謝謝大大們詳細的說明, 謝謝!!
作者:
yen956
時間:
2016-1-4 17:51
花了不少時間, 總算對 Ditionary 有一點點了解,
d(a.Value) = "" 與
If Not exists(a.Value) Then d.Add a.Value, "" 同義.
下列修改自 15# GBKEE版大的VBA(版大的執行結果完全正確),
請指教!!
'修改自 15# GBKEE版大的VBA
Sub Test()
Dim d As Object, d2 As Object, AR(1 To 3), ArC()
Dim M As Variant, E As Variant
Dim LstA As Integer, LstB As Integer, Cnt As Integer, Cnt2 As Integer
Dim i As Integer, J As Integer
Set d = CreateObject("SCRIPTING.DICTIONARY")
Set d2 = CreateObject("SCRIPTING.DICTIONARY")
Range("C:G").ClearContents '清除工作表4 C欄-->G欄
Range("E:E").Interior.ColorIndex = xlNone
LstB = [B65536].End(xlUp).Row
Cnt = 1
Cnt2 = 1
ArC = Array(35, 36, 37, 38)
'以下計算 工作表1-> 工作表3 出現機率為80%的字母*****
For i = 1 To 3 '從 "工作表1" 到 "工作表3"
Sheets(i).Range("C:E").ClearContents '清除每一頁的 C欄-->E欄
With Sheets(i).[C1].Resize(Sheets(i).[B65536].End(xlUp).Row) '即[C1:Cxx]
.Cells = "=COUNTIF(C2,RC[-1])/COUNTA(C1)"
'[C1]公式 = COUNTIF(B:B,B1)/COUNTA(A:A), 即計算每個字母出現的機率
AR(i) = Application.Transpose(.Offset(, -1).Resize(, 2).Value)
'將 B欄,C欄 轉置為 AR(1 to 2, 1 to 21)
'將英文字母出現百分比機率導入 AR(i)
For Each E In .Cells '歷遍每一頁的 [C1:Cxx]
d2.Item(E.Offset(, -1).Value) = E.Value
'將字母(Key)及機率(Item)全部存入 字典d2 中(不論機率大小)
If E >= 0.8 Then d(E.Offset(, -1).Value) = E.Value
'將機率 >=80% 的字母及機率, 放到 字典d 中
Next
.Cells = .Value '公式轉為值
If d.Count >= 1 Then
.Cells(1).Range("B1").Resize(d.Count) = Application.Transpose(d.keys) '傾倒字母到每頁的 [D1:Dxx]
.Cells(1).Range("C1").Resize(d.Count) = Application.Transpose(d.Items) '傾倒機率到每頁的 [E1:Exx]
'★這裡若將 .Range("B1") 改為 .[B1]
' 則會出現 "物件不支援屬性或方法" 的錯誤!!
End If
If d2.Count >= 1 Then
'固定式(工作表4的A欄及B欄的表格事先填好)
'***工作表4上 B欄位中,每個英文字母出現在指定工作表的比率***
M = Application.Match(Sheets(i).Name, [A:A])
If IsNumeric(M) Then
If i = 3 Then
LstA = LstB
Else
LstA = Cells(M, 1).End(xlDown).Row - 1
End If
For J = M To LstA
If d2.Exists(Cells(J, 2).Value) Then
Cells(J, 3) = d2(Cells(J, 2).Value)
End If
Next
Cnt = LstA + 1
End If
'機動式(E欄(工作表名稱)及F欄(字母)的表格由VBA填入)
'***工作表4上 F欄位中,每個英文字母出現在指定工作表的比率***
Cells(Cnt2, 5) = Sheets(i).Name '工作表名稱
Cells(1).Range("E" & Cnt2).Resize(d2.Count).Interior.ColorIndex = ArC(i)
Cells(1).Range("F" & Cnt2).Resize(d2.Count) = Application.Transpose(d2.keys) '傾倒字母
Cells(1).Range("G" & Cnt2).Resize(d2.Count) = Application.Transpose(d2.Items) '傾倒機率
Cnt2 = d2.Count + 1
End If
End With
d.RemoveAll
d2.RemoveAll
Sheets(i).Range("C:C", "E:E").NumberFormatLocal = "0%" '數字格式化
Next
Range("C:C", "G:G").NumberFormatLocal = "0%" '數字格式化
End Sub
複製代碼
歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)