2012-08-08 113 views
1

我目前正在使用大型機的數據,而不是unlike the data presented here。在這種情況下,我所有的都是類似於我的標準和我的目標數據集的100-AAA的字符串。我已經搜索了一個類似的解決方案,但是我還沒有發現SO上的VBA的範圍問題的直接過濾器。基於範圍VBA的過濾列

我正在嘗試基於一系列標準篩選大型數據集。本來,我開始在單獨的類/子程序收藏玩,後來我壓縮到一個子程序中的使用範圍,具體如下:

Sub FilterTest1() 

Dim RngOne As Range 
Dim LastCell As Long 

Sheets("Criteria").Activate 
Sheets("Criteria").Select 
Range("A1").Select 

LastCell = Application.WorksheetFunction.CountA(ActiveSheet.Range("A:A")) 

Set RngOne = ActiveSheet.Range("A2:A" & LastCell) 

Sheets("Sheet 1").Activate 
Sheets("Sheet 1").Select 

With ActiveSheet 
    If .FilterMode Then 
    .ShowAllData 
    End If 
End With 

Columns("A:A").Select 
Selection.AutoFilter 
ActiveSheet.Range("A:A").AutoFilter Field:=1, Criteria1:=RngOne, Operator:=xlOr 

End Sub 

不幸的是,我的單元格區域不過濾數據,甚至當使用諸如Operator:=xlOr的標準時 - 它只顯示用於標準的最後一個單元格值。 VBA代碼不會失敗 - 它只是基於範圍不能正確過濾。

我覺得確實存在一個簡單的解決方案,但我不太明白。

+0

您是否考慮過使用ADO,以便您可以使用SQL命令進行過濾(但仍使用Excel)?在標準和數據集之間執行內部連接可能適合賬單 – barrowc 2012-08-08 23:05:19

+0

此問題早期回答類似問題的幫助 - http://stackoverflow.com/a/7863452/53614?我在沒有管理員權限的工作機器上使用ADO,它工作正常。 YMMV,但值得一試 – barrowc 2012-08-10 02:28:49

+0

好吧;我會在週末給大家一個鏡頭,看看它下週如何部署。對於我的一些較大的數據集使用ADO可能是值得的,因爲任何依賴於SQL的東西都可能長期以更快的速度執行。如果它的功能,那麼這意味着另一個+1你的答案=) – JackOrangeLantern 2012-08-10 14:04:55

回答

5

您當前行:

ActiveSheet.Range("A:A").AutoFilter Field:=1, Criteria1:=RngOne, Operator:=xlOr 

正試圖通過一個Range對象過濾您的第一個字段,而不是在範圍內的每個值。

我已經提供了一種方法來做到這一點,將您的值加載到數組中,然後將數組傳遞給過濾條件。

值得注意的幫助你(和其他人在未來)的幾點:

  • 我學會了正確的語法使用宏錄製在選擇對象的篩選。
  • 此網站幫助我瞭解了陣列技巧:Pass Array to Filter Criteria
  • 我還清理了您的代碼,通過刪除無用的select語句等來更有效率和更快速地執行代碼。 (沒什麼大不了的代碼這一點點,但得到的是實踐將幫助您爲更大的項目!)

下面的代碼:

Sub FilterTest1() 

Dim RngOne As Range, cell As Range 
Dim LastCell As Long 
Dim arrList() As String, lngCnt As Long 

With Sheets("Criteria") 
    LastCell = .Range("A" & Sheets("Criteria").Rows.Count).End(xlUp).Row 
    Set RngOne = .Range("A2:A" & LastCell) 
End With 

'load values into an array 
lngCnt = 0 
For Each cell In RngOne 
    ReDim Preserve arrList(lngCnt) 
    arrList(lngCnt) = cell.Text 
    lngCnt = lngCnt + 1 
Next 


With Sheets("Sheet 1") 

    If .FilterMode Then .ShowAllData 

    .Range("A:A").AutoFilter Field:=1, Criteria1:=arrList, Operator:=xlFilterValues 

End With 

End Sub 
+0

你好斯科特,我想我明白你要去哪裏 - 用一串字符串作爲標準而不是範圍。至於代碼清理 - 非常感謝,我一次經常檢查10,000行。但是,當我測試您的代碼時,我遇到了「類型不匹配」錯誤消息。進入代碼並檢查代碼語法的其餘部分後,它發生在第25行:'.Range(「A:A」)。AutoFilter字段:= 1,Criteria1:= Array(strList),Operator:= xlFilterValues' 。你知道爲什麼這可能會發生嗎?代碼的其餘部分似乎正常工作。 – JackOrangeLantern 2012-08-08 21:47:33

+0

您是否看到我編輯的答案?我在原始(但已刪除)的帖子中解決了這個問題。 – 2012-08-09 14:02:48

+0

我現在會測試 - 剛回來。=) – JackOrangeLantern 2012-08-09 14:07:13

3

要注意的一個事情是, Criteria1需要字符串變量作爲參數。您可以將一個範圍分配給一個數組,然後將string數組傳遞給條件。另一個需要注意的是,爲了將數組傳遞給標準,就我所知,它必須是連續的,而不是列。 StringArray(0,3)而不是StringArray(3,0)。因此,爲什麼你會得到你的範圍內的最後一個值。只需使用Application.Transpose(StringArray)即可轉換成一行。

這個小小的代碼適用於我,並且很容易擴展到更大的數組。

Sub test() 
Dim StringArray(0, 1 To 3) As String 'This is a fixed dimension of an array, you can easily change to dynamic by using the ReDim statement. 
ActiveSheet.AutoFilterMode = False 'To reset autofilter 

Range("D3:D5").Select 

For c = 1 To 3 'Step through the range that you wish to use as the criteria. 
StringArray(0, c) = CStr(Selection(c, 1).Value) 
Next 

Range("A:A").AutoFilter Field:=1, Criteria1:=StringArray, Operator:=xlFilterValues 

End Sub 
+1

你的解釋很有幫助,並增加了接受的答案。 +1 – JackOrangeLantern 2012-08-09 14:19:21