excel vba 有條件的提取不重覆值 求救!!

CK豬 wrote:
有找到適合的程式


這個vba只是列出不重複值的公式(不含條件),跟公式的差別只在一個自動、一個手動
而且您進貨難到都不用管數量的嗎?只列出名稱不是很奇怪嗎??

資料量這麼多,如果不會用access,建議可用excel樞紐分析表
幾萬筆的資料,移除重複、加總、分類…都是瞬間算好





[點擊下載]
snare wrote:
這個vba只是列出不...(恕刪)

數量部份,會在總表用sumifs加總
品項是因為用陣列太慢了,所以只要解決可以用條件帶品項即可^^
試試,直接在樞紐分析表用vba取值,剩下的請自己加油




[點擊下載]
snare wrote:
試試,直接在樞紐分析(恕刪)


這個試過了,會有其它問題要解決,例如
1. 用陣列抓樞紐,只要新增品項更新樞杻,陣列範圍即抓不到了
2. 更新方式為單月更新,非一次性製作更新,所以陣列使用仍會偏多,托慢速度

以上問題,目前無解中
nsps5606 wrote:

我主要是每個月更新,非一次性更新,
可否直接把條件寫到程式裡,例如2020-01,依此條件回傳品項即可
我打算複製12個程式,條件手動改1~12個月,每到該月才按一次該月份的程式做更新
※如果能新增有第二個條件保留使用更好

麻煩nsps5606大大有空再幫我看一下


Sub GetDistinctFruit(month As String)

Dim myList As New Collection, cell As Range, itm, i As Integer
Dim str As String

str = ""
For Each cell In Sheets("001").Range("B2:B999")
If cell <> "" And str <> cell.Value And cell.Offset(0, -1).Value = month Then
myList.Add cell.Value, CStr(cell.Value)
str = cell.Value
End If
Next

i = 3
For Each itm In myList
Sheets("003").Cells(i, "D") = Format(itm, "@")
i = i + 1
Next
End Sub
nsps5606 wrote:
芒果好像都供不應求?(恕刪)


我主要是每個月更新,非一次性更新,
可否直接把條件寫到程式裡,例如2020-01,依此條件回傳品項即可
我打算複製12個程式,條件手動改1~12個月,每到該月才按一次該月份的程式做更新
※如果能新增有第二個條件保留使用更好

麻煩nsps5606大大有空再幫我看一下



再看要怎麼帶入條件和處理輸出

Sub Btn2_Click()
GetDistinctFruit "2020-02"
End Sub

Sub Btn3_Click()
Dim str As String
str = InputBox("輸入年月(格式yyyy-mm):")
If str <> "" Then
GetDistinctFruit str
End If
End Sub

Sub GetDistinctFruit(month As String)

Dim myList As New Collection, cell As Range, itm, i As Integer
Dim str As String

str = ""
For Each cell In Sheets("001").Range("B2:B999")
If cell <> "" And str <> cell.Value And cell.Offset(0, -1).Value = month Then
myList.Add cell.Value, CStr(cell.Value)
str = cell.Value
End If
Next

i = 3
For Each itm In myList
Sheets("003").Cells(i, "D") = Format(itm, "@")
i = i + 1
Next
End Sub
上面樞紐分析也很好耶,就算每個月都把之前幾個月都算一次也是瞬間就出來了

CK豬 wrote:
我主要是每個月更新,非一次性更新,
可否直接把條件寫到程式裡,例如2020-01,依此條件回傳品項即可
我打算複製12個程式,條件手動改1~12個月,每到該月才按一次該月份的程式做更新
※如果能新增有第二個條件保留使用更好
 
但程式最好是可以重複使用,且不須隨時間更動程式碼
我附個檔你參考看看~
語法如果不太熟悉的話可以先找Visual Basic(VB6)的書或教學熟悉一下

[點擊下載]
CK豬 wrote:
這個試過了,會有其它問題要解決,例如
1. 用陣列抓樞紐,只要新增品項更新樞杻,陣列範圍即抓不到了
2. 更新方式為單月更新,非一次性製作更新,所以陣列使用仍會偏多,托慢速度


一、您確定?有手動輸入試過嗎?(範例中產生隨機資料,是用來測試數萬筆資料用的)
13樓的範例沒有用到任何公式
只是利用樞杻分析表的速度,先處理複雜資料,再用vba處理少量單純資料

範例中的樞杻分析表
有加上自動更新資料範圍、自動更新分析表的功能,就算只有一筆也能算


二、1樓的圖片說明,每月都混在一起
範例都是照著您的排版、說明做的,如果不是您想要的,那我也沒辦法


如果用陣列公式去取p欄~aa欄的極少量資料,還會慢,那是您公式的問題


(1+2)、我可沒有看到您發文後,再回去偷改程式碼
這是一開始就加上的功能,沒發現樞杻分析表會自動更新資料(範圍)

您該不會沒試就跟我說不行吧?

單月更新、非一次性製作更新,不是問題,我知道資料是累積的,會愈來愈多
所以資料範圍的問題,早就注意到了
新增品項,也不是問題,強大的樞杻分析表會自動分類、移除重複











發現一個小bug,請自行輸入修改(13樓範例)

For i = 2 To 13
k = 2
當資料只有一個月時,程式碼要多加下面這一行
If Sheets("工作表2").Cells(2, i) = "總計" Then Exit For
snare wrote:
(1+2)、我可沒有看到您發文後,再回去偷改程式碼
這是一開始就加上的功能,沒發現樞杻分析表會自動更新資料(範圍)
您該不會沒試就跟我說不行吧?



snare大,可能我的回覆讓你誤解了,非常抱歉
1. 因公司的資料,不方便提供出來,總表格式,並非我提供的範例裡的總表。
2. 我給的範例,是要求相同功能,我可以再另外複製回去修改條件跟輸出的欄位。

以上,非常感謝各位大大的回覆與程式提供^^"

最後,可能會先用非專業的寫法來做,不知可否請snare大給我些意見呢

1. 指定欄位輸入函數帶入,再複製貼上值,以避免欄位掛著函數影響excel速度,
目前有以下兩種函數(陣列跟非陣列),不知是否有推薦哪種寫法,vba執行會比較快呢?
A. LOOKUP+FREQUENCY(這個可不用C+S開啟陣列)
B. INDEX+MATCH+COUNTIF(這個要開陣列)

2. 用錄製,開新sheets,篩完條件+移除重覆,再貼回要的欄位,最後刪除新sheets

以上,如果方便提供經驗,再感謝了^^
CK豬 wrote:
excel明細如下:(恕刪)


不好意思,您的問題解決了嗎?(看最後的發言,好像不是很滿意?)

要取不重複的值,也可用單純函數countif ,countifs 來處理(無須陣列),可以分2步驟:
1.先用countif 取出不重複的值
2.將不重複的值帶入countifs,判斷是否有符合月分的紀錄

~~因您的需求是要用VBA,所以可以把以上countif ,countifs 2個函數,轉成VBA語法來執行。.....這樣不就完全符合您提的需求?

以下做了一個VBA程序,你可試試~~(注意有些列字數稍多,畫面顯示可能為2行,但實際是1行~~千萬不要隨意斷行,否則執行會出錯~)

Sub not_same()

'假設[資料明細表]、[總表]均在同一個活頁簿(本活頁簿)

s1_name = "資料明細表"
s2_name = "總表"

r_f = 2 '資料紀錄從第2列開始處理比對
s_f = 3 '寫到總表時,從第3列開始寫入

yy = "2020" '要比對的年份~~暫時「寫死」,有需要的話也可以自行改成使用者輸入,或抓今天日期的年份。
dd = "" '要比對的日期-月份

c_f = InputBox("請輸入月份(1-12):", "日期篩選") '接收使用者輸入月份 ~~也是代表總表該月份的欄位(4=2020-04=D欄)。

Select Case c_f
Case 1
dd = yy & "-01"
Case 2
dd = yy & "-02"
Case 3
dd = yy & "-03"
Case 4
dd = yy & "-04"
Case 5
dd = yy & "-05"
Case 6
dd = yy & "-06"
Case 7
dd = yy & "-07"
Case 8
dd = yy & "-08"
Case 9
dd = yy & "-09"
Case 10
dd = yy & "-10"
Case 11
dd = yy & "-11"
Case 12
dd = yy & "-12"
Case Else
dd = ""
End Select

If dd = "" Then '如果亂輸,就離開程序
MsgBox "抱歉,輸入月份選擇有誤,請檢查確認再執行本功能。"
Exit Sub
End If

Sheets(s1_name).Select '畫面切到資料工作表

'開始對資料紀錄進行迴圈處理
Do
If Sheets(s1_name).Cells(r_f, 1) = "" Then Exit Do '如果該列A欄無資料,視同資料紀錄已結束,跳出迴圈

a = Excel.Application.WorksheetFunction.CountIf(Range("B2:" & "B" & r_f), "=" & Cells(r_f, 2)) '函數轉VBA的寫法

If a = 1 Then 'a=1,代表該列的B欄,品項名稱出現第1次,......這時就抓取該名稱,進行後續處理

b = Excel.Application.WorksheetFunction.CountIfs(Range("A:A"), "=" & dd, Range("B:B"), "=" & Cells(r_f, 2))
'用該不重複的名稱,比對符合日期月份的紀錄,總共在資料表中出現幾次。如果b>0,代表就是要的資料。

If b > 0 Then

Sheets(s2_name).Cells(s_f, Val(c_f)) = Sheets(s1_name).Cells(r_f, 2) '將符合日期條件的不重複品項名稱,寫到總表的日期對應欄位:c_f。
s_f = s_f + 1 's_f 往下一格,準備接收下一個名稱
End If
End If
r_f = r_f + 1 '準備處理下一筆資料紀錄
Loop
Sheets(s2_name).Select '畫面轉到總表
Cells(3, Val(c_f)).Select '作用格放到第3列,方便檢視

MsgBox "比對篩選完成。(共寫入 " & s_f - 3 & " 筆紀錄!)" '簡單的訊息回饋

End Sub


~~~~~~~~
ok,完成。你可以試試。(我盡量加註解了,希望對您學習有幫助!)
Der,misser1
關閉廣告
文章分享
評分
評分
複製連結

今日熱門文章 網友點擊推薦!