2013-09-06 4 views
3

Я работаю с автофильтрами в VBA с Microsoft Excel. У меня возникла проблема с тем, как он обрабатывает массивы для фильтрации; Я разбавлять свой первоначальный контекст упрощенной версии (первоначально в надежде на понимание вопроса):Excel VBA AutoFilter Array

В рабочем листе в диапазоне A1: A5, скажем, у нас есть Fruit, Apple, Banana, Orange и Pear, соответственно. AutoFilter был применен так, что Fruit является заголовком столбца.

Запуск ниже код возвращает ожидаемые результаты (Apple, Banana и Orange но не Pear):

Range("A1").Select 
ActiveSheet.Range("A1:A5").AutoFilter Field:=1, _ 
    Criteria1:=Array("=*an*", "=*app*"), Operator:=xlFilterValues 

В проекте я работаю, критерии фильтрации передаются в качестве переменных String, который работает как указано выше. Проблема в том, что не каждый критерий применяется каждый раз, поэтому некоторые из них не должны иметь никакого эффекта.

Например:

Dim A As String, B As String, C As String 
A = "=*an*" 
B = Empty 
C = "=*ap*" 

Range("A1").Select 
ActiveSheet.Range("A1:A5").AutoFilter Field:=1, _ 
    Criteria1:=Array(A, B, C), Operator:=xlFilterValues 

С B бросили в смесь, не фильтруя возвращает никаких записей (будь то осталось пустым, чтобы установить Empty, или использует символы как =*). Однако замена B на Empty (жестко запрограммированная) в массиве реальных критериев возвращает ожидаемый результат.

Я использовал аналогичный код в прошлом (и имел его работу), хотя и с AutoFilter, который был частью ListObject. На данный момент, единственное, о чем я могу думать, это объединение фильтров в String с разделителями и разделение его на переменную Array (так что это точный размер, так как неустановленный элемент в коллекции беспорядок то же самое стандартная переменная). Но это кажется неинтуитивным и громоздким.

Я пропустил что-то очевидное здесь?

ответ

4

Я не могу придумать способ сделать это, который не включает тестирование пустых параметров, вот один из подходов, который может сработать для вас, а также предотвращает дублирование выражений.

Sub Main() 
    Dim a As String 
    Dim B As String 
    Dim C As String 
    Dim filterCriteria as Variant 
    a = "=*an*" 
    B = Empty 
    C = "=*ap*" 
    filterCriteria = CombineArrays(Array(a, B, C)) 

    If Not uBound(filterCriteria) = -1 Then 

     Range("A1").Select 
     ActiveSheet.Range("A1:A5").AutoFilter Field:=1, _ 
      Criteria1:=filterCriteria, Operator:=xlFilterValues 

    End If 
End Sub 

Function CombineArrays(arr As Variant) As Variant 
    Dim a As Variant 
    Dim filterDic As Object 'Scripting.Dictionary 
    Set filterDic = CreateObject("Scripting.Dictionary") 

    For Each a In arr 
     If Not filterDic.Exists(a) And Not a = vbNullString Then 
      filterDic.Add a, a 
     End If 
    Next 

    CombineArrays = filterDic.Keys 

    Set filterDic = Nothing 
End Function 
+0

Слишком поздно, но я думаю, что вы можете опустить условие в заполняющий словарь, поскольку он не будет добавлять элемент с ключом, который уже существует в словаре, если вы не добавили его в цикл быстрее. – AntiDrondert

+1

@AntiDrondert да, вы можете опустить проверку Exists, но тогда вы не можете использовать метод Add, который вам нужно просто косвенно сделать 'filterDic (a) = a'. –

Смежные вопросы