2016-08-01 54 views
0

Ich frage mich, eine einfache Lösung für die Umkehrung der gefilterten Werte. Obwohl es mir eine leichte Aufgabe zu sein scheint, hatte ich keinen Erfolg bei der Recherche im Internet.VBA - 2010 - So invertieren Sie einen Filter

Die Situation und Problem: Ich habe eine Tabelle mit mehreren Spalten, und viele Zeilen (genaue Höhe spielt keine Rolle, natürlich) und ich will sehen, was nicht in genau eine Spalte gefiltert. Das Problem ist, dass ich normalerweise viel klicken

Zum Beispiel tun müssen - in der Datenbank der Projekte, die ich gefiltert habe die, die im Wert von über 500 000 €, die meine sind und kommen aus einem bestimmten Land. Mit einem Klick würde ich gerne sehen, welche unter 500 000 € sind), aber sind immer noch meins und kommen aus einem bestimmten Land.

Mögliche Lösungen, die mir in den Sinn kam:

  • Erstellen Sie eine eindeutige Liste von dem, was ungefiltert wird filtriert und schaffen durch die Differenz eine eindeutige Liste der vollständigen Spalte AdvanceFilter. (Das ist mein weißes Pferd - es könnte meiner Meinung nach funktionieren)
  • Gehen Sie durch jede Filteroptionen und aktivieren/deaktivieren Sie eines nach dem anderen.
  • Screenshot Filter, Transfer zum Text, eine eindeutige Wert in der Spalte erstellen, die Filter in erweiterten Filter invertieren (sehr verrückte Idee kamen Verzweiflung aus)
  • Irgendwo leicht eine Liste nehmen, was gefiltert ist und es invertiert durch einfache Funktion (das war mein erster Gedanke, aber nicht funktioniert!)

hat jemand eine Idee hat, wie diese Situation zu nähern? Ich bin in der Lage, die VBA auf eigene Faust zu versuchen, so würde ich mich freuen, wenn Sie mir in die richtige Richtung zeigen können. Natürlich würde ich Ihre Gedanken auch im Code begrüßen.

+0

Suchen Sie, dass diese Daten auf demselben Blatt oder auf einem separaten Blatt erscheinen? – viper941

+0

Auf demselben Blatt. Einfach nochmal gefiltert;) –

Antwort

1

Hier ist eine Idee, einen numerischen Filter umzuschalten. Es wird nicht mit allen numerischen Filtern funktionieren, aber die meisten davon. Zum Beispiel funktioniert es nicht mit Between, weil das Criteria1 und Criteria2 verwendet. Aber Sie könnten den Code erweitern, um dies zu berücksichtigen.

Auch funktioniert es nur wirklich auf numerische Filter. Es funktioniert bei einigen Textfiltern, aber nur wenn ein Kriterium angewendet wird.

Sub InvertNumericFilter() 

    Dim lFilter As Long 
    Dim lo As ListObject 
    Dim fltr As Filter 
    Dim aOper As Variant, aOpp As Variant 
    Dim i As Long 

    'aOpp is the opposite of the corresponding 
    'operator in aOper 
    aOper = Split("<> <= >= = < >") 
    aOpp = Split("= > < <> >= <=") 

    'Find which column you're in 
    Set lo = ActiveCell.ListObject 
    lFilter = ActiveCell.Column - lo.DataBodyRange.Column + 1 
    Set fltr = lo.AutoFilter.Filters(lFilter) 

    'if the first characters of the criteria are in aOper 
    'then swap them for aOpp 
    For i = LBound(aOper) To UBound(aOper) 
     If Left(fltr.Criteria1, Len(aOper(i))) = aOper(i) Then 
      lo.DataBodyRange.AutoFilter lFilter, Replace$(fltr.Criteria1, aOper(i), aOpp(i)) 
      Exit For 
     End If 
    Next i 

End Sub 

Ihr Beispiel passiert eine Reihe zu invertieren, aber wenn man es universell sein wollen (zu nonnumerics gelten), wäre es viel komplizierter.

aktualisieren

Dies wird Wertelisten umkehren, aber es macht einige Annahmen. Zum einen, wenn Sie nur zwei Werte haben, ist es keine Werteliste, es ist ein Operator. Wenn Sie in einem anderen Feldtyp verwenden, kann dies zu Problemen führen.

Sub InvertFilter() 

    Dim lFilter As Long 
    Dim lo As ListObject 
    Dim fltr As Filter 
    Dim aOper As Variant, aOpp As Variant 
    Dim i As Long, j As Long 
    Dim dc As Scripting.Dictionary 
    Dim vaValues As Variant 

    'Find which column you're in 
    Set lo = ActiveCell.ListObject 
    lFilter = ActiveCell.Column - lo.DataBodyRange.Column + 1 
    Set fltr = lo.AutoFilter.Filters(lFilter) 

    'lists of values or just two values 
    If fltr.Operator = xlFilterValues Or fltr.Operator = xlOr Then 
     'get all the possible values and put in a dictionary 
     vaValues = lo.ListColumns(lFilter).DataBodyRange.Value 
     Set dc = New Scripting.Dictionary 
     For i = LBound(vaValues, 1) To UBound(vaValues, 1) 
      If Not dc.Exists("=" & vaValues(i, 1)) Then 
       dc.Add "=" & vaValues(i, 1), "=" & vaValues(i, 1) 
      End If 
     Next i 

     'If it's more than two values 
     If IsArray(fltr.Criteria1) Then 
      'remove from dictionary 
      For i = LBound(fltr.Criteria1) To UBound(fltr.Criteria1) 
       If dc.Exists(fltr.Criteria1(i)) Then 
        dc.Remove fltr.Criteria1(i) 
       End If 
      Next i 
     Else 
      dc.Remove fltr.Criteria1 
      dc.Remove fltr.Criteria2 
     End If 
     'reapply filter 
     lo.DataBodyRange.AutoFilter lFilter, dc.Keys, xlFilterValues 
    ElseIf fltr.Operator = 0 Then 

     'aOpp is the opposite of the corresponding 
     'operator in aOper 
     aOper = Split("<> <= >= = < >") 
     aOpp = Split("= > < <> >= <=") 

     'if the first characters of the criteria are in aOper 
     'then swap them for aOpp 
     For i = LBound(aOper) To UBound(aOper) 
      If Left(fltr.Criteria1, Len(aOper(i))) = aOper(i) Then 
       lo.DataBodyRange.AutoFilter lFilter, Replace$(fltr.Criteria1, aOper(i), aOpp(i)) 
       Exit For 
      End If 
     Next i 
    End If 

End Sub