2016-12-06 93 views
0

好吧,這個很難解釋 - 我有一個非常大的表格,它有客戶,零件號碼,價格和收入。我需要退回所有使用零件號列表的客戶;例如,如果他們使用ABC和DEF部分,那麼它會返回使用這些部分的客戶,以及這些客戶的收入(我想我會將整行復制到另一個表或其他東西)。Excel VBA - 嘗試返回僅包含所有條件的值

我不想看到使用一個部件但不使用其他部件的客戶。我試過做自動過濾器和高級過濾器,但沒有運氣,但如果可能的話,我寧願在VBA中執行此操作。我不知道哪一種方式是最簡單的...

一個想法是擺動表和按客戶排序,但這是非常手動的,我需要將這些結果拉到另一個表,所以我可以看到數據分開。任何幫助深表感謝!

編輯:實施例表

Example Table

+0

你可以發佈你的模式圖嗎? –

+0

不幸的是,我不能 - 電子表格非常簡單:客戶,零件號碼,成本,收入以及其他一些我不需要的錯誤數據。這是一張巨大的桌子,但這些是我的目的重要的專欄。我在工作簿中有另一個工作表,我有一個我想要用作過濾器的部分列表,但在擴展它之前我需要先了解基本概念 –

回答

0

編輯 OP的澄清後。請參閱附加代碼

您可以使用「Range」對象的「AutoFilter()」方法的「xlFilterValues」運算符。

假設第一行標題,這裏的「基本概念」的代碼,你問:

Dim partListArr As Variant 

With Worksheets("MyListSheetName") 
    partListArr = Application.Transpose(.Range("A1", .Cells(.Rows.Count,1).End(xlUp)).Value)'<--| retrieve the content of its column A cells from row 1 down to its last not empty cell 
End With 

With Worksheets("MyDataSheetName") 
    With .Range("Z1", .Cells(.Rows.Count,1).End(xlUp)) '<--| reference its A to Z columns cells from row 1 down to column A last not empty cell 
     .Autofilter field:=2, Criteria1:=partListArray, operator:=xlFilterValues '<--| filter referenced range on its 2nd field with list of parts 
     With .Resize(.Rows.Count - 1).Offset(1).SpecialCells(xlCellTypeVisible) '<--| reference filtered cells, skipping headers 

      ' here your code to handle filtered cells 

     End With 
    End With 
End With 

既然你澄清,你仍然可以使用嵌套AutoFilter() s到趕上合適的客戶分享所有列出的部分,但將此工作留給詞典更有效,並使用AutoFilter()作爲最終的複製/粘貼部分。如下所示:

Option Explicit 

Sub main() 
    Dim custDict As Scripting.Dictionary, partDict As Scripting.Dictionary 
    Dim cust As Variant, part As Variant 
    Dim parts As String 
    Dim okCust As Boolean 

    With Worksheets("MyListSheetName") 
     Set partDict = GetList(.Range("A1", .Cells(.Rows.count, 1).End(xlUp))) 
    End With 

    With Worksheets("MyDataSheetName") 
     With .Range("Z1", .Cells(.Rows.count, 1).End(xlUp)) '<--| reference its A to Z columns cells from row 1 down to column A last not empty cell 
      Set custDict = GetList(.Resize(.Rows.count, 1).Offset(1)) 

      For Each cust In custDict.Keys 
       parts = custDict(cust) & "|" 
       For Each part In partDict.Keys 
        okCust = InStr(parts, "|" & part & "|") > 0 
        If Not okCust Then Exit For 
       Next part 
       If okCust Then 
        .AutoFilter field:=1, Criteria1:=cust 
        With .Resize(.Rows.count - 1).Offset(1).SpecialCells(xlCellTypeVisible) '<--| reference filtered cells, skipping headers 
         .Copy Destination:=GetSheet(CStr(cust)).Range("A1") 
        End With 
       End If 
      Next cust 

     End With 
     .AutoFilterMode = False 
     .Activate 
    End With 
End Sub 

Function GetList(rng As Range) As Scripting.Dictionary 
    Dim dict As New Scripting.Dictionary 
    Dim cell As Range 

    For Each cell In rng.Cells 
     dict(cell.Value) = dict(cell.Value) & "|" & cell.Offset(, 1) 
    Next cell 

    Set GetList = dict 
End Function 

Function GetSheet(shtName As String) As Worksheet 
    On Error Resume Next 
    Set GetSheet = Worksheets(shtName) 

    If GetSheet Is Nothing Then 
     Set GetSheet = Worksheets.Add 
     GetSheet.Name = shtName 
    Else 
     GetSheet.UsedRange.ClearContents 
    End If 
End Function 
+0

我想我沒有很好地解釋它(這就是爲什麼我似乎無法找到任何解決方案) - 一旦我獲得了過濾的數據,我想將擁有列表中所有零件的客戶複製到新表中,但只有擁有所有零件的客戶才能複製。因此,例如,客戶A正在使用123部分,而客戶B正在使用123和234部分,而我正在尋找使用123和234的客戶,因此它只會返回客戶B.這是否合理?對不起,如果它不是100%清楚......感謝您的幫助到目前爲止,此腳本確實工作來過濾數據。一個錯字是標準是partListArr –

+0

太棒了!我還沒有能夠測試,但是一旦我有時間執行,我會明天更新。我只是看字典,這似乎是一個非常優雅的解決方案;我還沒有聽說過字典功能,因爲我的VBA經驗有限......先謝謝了 - 很快就會更新。 –

+0

使用具有早期綁定的'Dictionary'對象(按照我的代碼),您必須將其庫引用添加到您的項目中:在您的VBA中,單擊工具 - >引用,滾動列表直到「Microsoft Scripting Runtime」,單擊複選標記在它旁邊並單擊「確定」 – user3598756

相關問題