各位好,想請問關於Excel篩選功能配合VBA使用,有沒有辦法達成「跳到下一個項目」

misser wrote:
剛看了一下訊息,下載(恕刪)

忘了說
我的需求看起來確實是功能A沒錯
原本我是想將功能A完成後再慢慢研究M大堤到的功能B
因為把資料複製到另一個檔案貼上的過程用的並非新檔案,而是既有檔案延續貼上
所以感覺應該會麻煩一些
稻草人到處草人 wrote:
忘了說我的需求看起來(恕刪)


先處理A也是OK的。上面貼的程式碼的按鈕檔案,我也已經做好。晚上(或明晚)找時間來做成執行影片,再放上來(已經和原po確認,內容沒有機密性....)。

屆時檔案我也會傳一份(有做好按鈕)給原po(稻草人)參考(因為沒在手邊,抱歉)。

雖然只是「小小」功能的嘗試與討論,但還是希望大家都能多多利用手邊這個「簡單」的Excel,讓工作更有效率囉~~互相加油吧。
Der,misser1
misser wrote:
先處理A也是OK的。(恕刪)

感謝M大,分享寶貴的專業技術資訊在網路上
上面的VBA,實際的操作示範影片來了:



實際檔案下載(版主,我就不另寄囉):
https://drive.google.com/file/d/1j0i9RMZSwvFIJPhSnISSm6_PH_jeFLpD/view?usp=sharing

以上。

稻草人到處草人 wrote:
感謝M大,分享寶貴的...(恕刪)


不客氣,其實也只是個人臨時完成的一點點小程式,真談不上什麼「寶貴的專業知識」。也祝版主稻草人工作順心囉。
Der,misser1
misser wrote:
上面的VBA,實際的操作示範影片來了


如果配合樞紐分析表使用,可不使用迴圈,增加效能
另一種寫法請參考


'需建立樞紐分析表,詳細請看附件
Dim List_Index As Integer


Sub test()
Dim LastRow As Integer

LastRow = Sheets("工作表2").Cells(Sheets("工作表2").Rows.Count, "A").End(xlUp).Row - 2
If List_Index = LastRow Or List_Index = 0 Then List_Index = 2 Else List_Index = List_Index + 1
Sheets("sheet1").Range("A:I").AutoFilter Field:=2, Criteria1:=Sheets("工作表2").Cells(List_Index, 1).Value
'debug
Sheets("sheet1").Range("m1") = Sheets("工作表2").Cells(List_Index, 1).Value & "=" & Sheets("工作表2").Cells(List_Index, 2).Value

End Sub



[點擊下載]
misser wrote:
上面的VBA,實際的(恕刪)

再次感謝M大清楚優秀的範例 :D

相信我,這知識絕對很寶貴

我很明白為什麼市場上這麼多教授課程,各種程式都有,可是永遠都有解決不完的問題

就是因為「程式類」的東西都是用來「解決問題」的,因此真正「被需要」的技術幾乎都是「問題出現」的時候,但普通的教室根本沒辦法把會出現的問題全部舉例完畢

因此可以在教室外的地方遇到問題,還能夠找到協助解決問題的人,是非常難得且可貴的

真心不騙
snare wrote:
如果配合樞紐分析表使(恕刪)

Snare大的檔案好像也很有意思,晚點來研究看看,感謝S大分享
misser wrote:
上面的VBA,實際的(恕刪)

snare wrote:
如果配合樞紐分析表使(恕刪)


有幾個問題想問M大和S大

M大:因為有這種需求的表格「種類」高達十種,原本我該做的事情就是不斷重複的把資料「手動」分類之後分別存到各個不同的表格,當然現在這樣已經非常方便了,不過我想請問M大,如果我想把「篩選欄位」換成別的欄位的話,我需要修改程式內的那些地方呢?
我才發現我的能力真的太淺,對於那些寫好註解的內容還是不容易詳細了解
想知道他是屬於只要修改幾個地方就可以更換篩選的目標欄位,還是說要改動的部分有點多?

S大:請問你的那個表格按鈕功能,純粹是靠樞紐分析表就可以做到分析該欄位該內容的數量並且依此建立切換條件嗎?
snare wrote:
如果配合樞紐分析表使(恕刪)


的確,當資料多時,效能的追求就很重要。

我上面做的VBA代碼,只是很單純的,回應版主的需求,屬於「傻瓜式」的操作(使用者也不須會操作樞紐分析表,只要會按下按鈕即可。).......尤其是版主有不少表格(10種?)要處理,如果還要為每個表格手動操作樞紐分析表(以得到依序排的不重複名字),恐怕最後花的時間反而是........。

然而snare大提供的方式,不僅是提供了一種不同的解決方案思考,也是版主將來進階學習不能迴避的:如何透過精簡程式代碼,在「大量」資料處理上提升效能。這時雖然是要先手動做出樞紐分析表(當然,這部分應該也可以由程式來代為處理),但後續節省的反而會更多。(......另外說一下,樞紐分析表確實可以做到:分析該欄位該內容的數量,也依序不重複的排好名字....等各欄位)


稻草人到處草人 wrote:
...真正「被需要」的技術幾乎都是「問題出現」的時候...


所以,能夠做出最符合版主(稻草人)需求的程式,莫過於版主自己........當板主進階到一定水準後,相信在工作上就能更得心應手,前述的A變成B也就指日可待。(
~~~~~~~~~~~~
老闆:你還有時間在喝咖啡?為什麼還不動手整理幾十個人的檔案?你到現在到底做了什麼?
版主(稻草人):喔,到現在我就只按了一個按鈕啊。
老闆:只按了一個按鈕?...........好,那你現在把這幾十個人的檔案立馬交出來.......,沒有,你滾;有,我滾。..........你還不滾?
版主指著電腦上已經自動整理好的幾十人檔案,說:呃,不好意思,Excel幫我完成了......那你滾吧。
~~~~~~~~~~~~
(以上純屬虛構,若有雷同............)

稻草人到處草人 wrote:
只要修改幾個地方就可以更換篩選的目標欄位,還是說要改動的部分有點多?

沒問題的,改變很少即可。(容我晚點或明天小修一下再丟上來).......
Der,misser1
稻草人到處草人 wrote:
如果我想把「篩選欄位」換成別的欄位的話

呃,我想,如果你的篩選欄位是「不固定」的(名稱上也不固定).....那你在後續處理上會有一定的麻煩(要修改程式碼,為不同資料表格手動變更--輸入--篩選欄位)。.......甚至你每個表格資料,處理欄位都一樣是A:I嗎?會不會某個表格有少一欄或多一欄?

那麼,何不乾脆把程式碼變得更有「彈性」(通用)一點,不必為了不同資料表格就要修改一次,你認為呢?

在「盡量少變動」的前提下,我想:是不是改成由你「要求」你自己,在為新表格進行篩選時,每次篩選,就是先把游標放到該表格資料的標題列?(比如範例檔是要篩選第2欄「人名」,那你就把游標先放到B1...下個表若是要篩選欄要變第3欄,那你就先把游標放到C1.......),再去按按鈕執行,由程式自動判斷資料欄數(是A:I,或A:K.....),篩選欄是B或C....自動進行篩選。

修改好的程式如下:

'程式 by misser 109.9.4
Sub auto_next() '自動篩選下一位

col_f = ActiveCell.Column '游標所在欄=要進行篩選的欄位
row_f = ActiveCell.Row '游標所在列
col_s = Cells(1, Columns.Count).End(xlToLeft).Column '資料最後一欄欄位(最右)

If row_f > 1 Or col_f > col_s Then '提醒使用者
MsgBox "請先將游標放到要篩選的標題上,再執行本功能喔!"
Exit Sub '離開本程序
End If


On Error GoTo err_hand '以下程式執行若發生錯誤,就跳到 errhand:位置 (最底下)
err_f = 0 ' 執行錯誤判斷旗標
r_f = ActiveSheet.AutoFilter.Range.Offset(1).SpecialCells(xlVisible).Rows(1).Row
'取得目前篩選得到的第一筆資料真實列數(若目前未執行篩選,會發生錯誤,程式跳到 errhand:)

If err_f = 1 Then r_f = 2 Else r_f = r_f + 1
'如果上一步驟發生錯誤,就從第2列開始檢查
'如果沒錯,就從目前篩選的列數,往下一列,準備檢查

Do
If Cells(r_f, 1) = "" Then '改由A欄判斷資料是否結束
MsgBox "已勾選結束囉!"
Exit Do '跳出迴圈
ElseIf Excel.Application.WorksheetFunction.CountIf(Range(Cells(2, col_f), Cells(r_f, col_f)), "=" & Cells(r_f, col_f)) = 1 Then
'檢查該列的姓名,若是第一次出現(由2~目前列),就執行篩選該人員 '篩選從B欄改成目前游標所在欄

ActiveSheet.Range(Columns(1), Columns(col_s)).AutoFilter Field:=col_f, Criteria1:=Cells(r_f, col_f) '在篩選中勾選這位
''篩選從B欄改成目前游標所在欄

ActiveSheet.AutoFilter.Range.SpecialCells(12).Copy '將篩選結果放到剪貼簿,方便使用者下一步處理

'Exit Sub
Exit Do '跳出迴圈
End If
r_f = r_f + 1
Loop

Exit Sub '離開本程序

err_hand: '錯誤(無篩選狀態)處理
err_f = 1 '將錯誤旗標設為1
Resume Next '程式回到錯誤點的下一步繼續執行
End Sub


另外,我把snare大的test按鈕程式的最後一行註解起來:

'Sheets("sheet1").Range("M1") = Sheets("工作表2").Cells(List_Index, 1).Value & "=" & Sheets("工作表2").Cells(List_Index, 2).Value

也就是不用這個debug顯示,這樣一來既不會影響snare的程式結果,同時也是避免我那程式「誤判」了資料要篩選的欄位是從A到xx,xx的正確性。

然後我把按鈕(包含snare的[test])往右邊移動,盡量空出空間,以應付萬一你其他某個表格資料的欄位數多了幾欄。

程式一樣盡量做了註解,方便你研究。

[點擊下載]


以上,希望能符合你的需求。

加油。
Der,misser1
文章分享
評分
評分
複製連結

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