Clevere Auswertungen per VBA mit dem AutoFilter von Excel
Das Arbeiten mit dem AutoFilter von Excel ist eine tolle Angelegenheit, wenn große Datenmengen gefiltert und danach auf andere Tabellen kopiert werden müssen. Im nachfolgenden Praxis-Beispiel soll eine Liste (exemplarisch enthält diese 1.000 Datensätze) mit Hilfe des Datenfilters ausgewertet und auf eine vorgegebene Matrix verteilt werden. Sehen Sie sich dazu einmal die Ausgangssituation auf der folgenden Abbildung an.
Filtern, summieren und zählen
Die Ausgangsliste ist gegliedert in Datumswerte, Länderbezeichnungen, Kategorien und Mengen. In der Tabelle TBL_ÜBERSICHT sollen einige Länder zusammengefasst, summiert und gezählt werden. Sehen Sie sich dazu Abb.2 an.
Der Bereich von D3:F10 wurde als Vorbereitung über das Namensfeld von Excel mit dem Namen "REGIONENSUMME" benannt. In diesem Bereich sollen alle umgesetzten Mengen pro Land und Kategorie (Haushalt, Gewerbe, Verein) summiert werden. Im Bereich D11:F11 liefert uns eine Kontrollsumme größtmögliche Sicherheit, damit wir beim automatischen Filtern der Tabelle TBL_DATEN keine Sätze verlieren. Im Bereich C3:C10 finden Sie eine Zusammenstellung der Länder, die zusammengefasst werden sollen. Diese Spalte kann später ausgeblendet werden.
Die Übersichtstabelle existiert sowohl für die Summierung der Umsätze sowie auch für die Zählung der umgesetzten Waren. Dazu wurde der Zellenbereich J3:L10 mit dem Zellennamen "REGIONENANZAHL" belegt.
Filtern per Hand contra Filtern per Makro
Wenn Sie sich die beiden Matrizen ansehen, dann erkennen Sie, dass Sie insgesamt 48 Felder (2 x 24) befüllen müssen. Das bedeutet, dass Sie manuell 48 Filteraktionen durchführen müssten. Dabei würden Sie in der Tabelle TBL_DATEN die Spalte B nach den Vorgaben der Länder aus der Übersicht filtern und gleichzeitig in Spalte C die jeweilige Kategorie einstellen. Nach der Filterung würden Sie die Summe bzw. die Anzahl der Datensätze ermitteln und jeweils in die Matrix übertragen. Was für eine sportliche Aufgabenstellung. Nehmen wir einmal an, dass Sie für jede Filterung und Übertragung des Filterergebnisses eine Minute brauchen, dann kommen wir auf ca. 45 Minuten. Ganz davon abgesehen, dass diese "Strafarbeit" auch fehleranfällig ist, haben Sie sicher keine Lust, dies händisch zu machen, oder?
Das folgende Makro ist in weniger als einer Sekunde fertig! Dabei macht das Makro von der Vorgehensweise nichts anderes, als Sie manuell, eben nur viel, viel schneller.
Sub FilterMitDatenfeldAusstatten()
Dim lngZeileMax As Long
Dim tblA As Worksheet
Dim Vardat As Variant
Dim rngZelle As Range
Set tblA = tbl_Übersicht
tblA.Range("RegionenSumme").ClearContents
tblA.Range("RegionenAnzahl").ClearContents
Application.ScreenUpdating = False
With tbl_Daten
lngZeileMax = .UsedRange.Rows.Count
.Rows(1).AutoFilter
For Each rngZelle In tblA.Range("RegionenSumme")
Vardat = Split(tblA.Cells(rngZelle.Row, 3).Value, ",")
.Range("$A$1:$D$" & lngZeileMax).AutoFilter Field:=2, _
Criteria1:=Array(Vardat), Operator:=xlFilterValues
.Range("$A$1:$D$" & lngZeileMax).AutoFilter Field:=3, _
Criteria1:=tblA.Cells(2, rngZelle.Column).Value
rngZelle.Value = WorksheetFunction.Subtotal(9, .Columns(4))
.ShowAllData
Next rngZelle
For Each rngZelle In tblA.Range("RegionenAnzahl")
Vardat = Split(tblA.Cells(rngZelle.Row, 3).Value, ",")
.Range("$A$1:$D$" & lngZeileMax).AutoFilter Field:=2, _
Criteria1:=Array(Vardat), Operator:=xlFilterValues
.Range("$A$1:$D$" & lngZeileMax).AutoFilter Field:=3, _
Criteria1:=tblA.Cells(2, rngZelle.Column).Value
rngZelle.Value = WorksheetFunction.Subtotal(3, .Columns(3)) - 1
.ShowAllData
Next rngZelle
End With
Application.ScreenUpdating = False
End Sub
Zu Beginn des Makros wird der Tabelle TBL_ÜBERSICHT ein etwas kürzerer Name (TBLA) gegeben. Über diesen Namen kann die Tabelle im weiteren Verlauf des Makros angesprochen werden. Danach werden die beiden benannten Bereiche über die Methode ClearContents zunächst einmal geleert. Damit die automatisierte Filterung dem Anwender verborgen bleibt, schalten Sie die Bildschirmaktualisierung über die Eigenschaft ScreenUpdating aus, indem Sie der Eigenschaft den Wert False zuweisen. Damit wird der Bildschirm während des Makroablaufs temporär eingefroren. Dies schont den Bildschirm sowie auch ihre Augen.
Mit der Anweisung With wird nun auf die Tabelle TBL_DATEN referenziert, in der die Filterung der Daten durchgeführt werden soll. Über die Eigenschaft AutoFilter wird der Datenfilter von Excel eingeschaltet. Zuvor ermitteln Sie mit Hilfe der Eigenschaften Usedrange und Rows sowie der Funktion Count die Gesamtanzahl der Zeilen, die verarbeitet werden sollen.
In einer For Each Next-Schleife arbeiten Sie sich anschließend Zelle für Zelle durch den benannten Bereich. Da mehrere Länder in der Auswertung zusammengefasst werden sollen, splitten Sie den Inhalt der Spalte C der jeweiligen Zeile auf, indem Sie die Funktion Split einsetzen. Dabei geben Sie das Trennzeichen an, über welches die einzelnen Länder in Spalte C getrennt sind. Nach der Aufsplittung befindet sich die aufgetrennte Liste im Arbeitsspeicher. Diesen Speicher können Sie über die Anzeige des Lokalfensters in der Entwicklungsumgebung sichtbar machen. Wählen Sie dazu in der Entwicklungsumgebung aus dem Menü Ansicht den Befehl Lokal-Fenster. Arbeiten Sie sich anschließend über die Taste F8 Zeile für Zeile durch das Makro durch.
Nach der Aufsplittung der Länder und Speicherung in der Variablen VarDat wird die Methode AutoFilter verwendet. Bei dieser Methode geben Sie an, welche Daten Sie filtern möchten. Dabei verweisen Sie auf den Bereich .Range("$A$1:$D$" & lngZeileMax) der Tabelle TBL_DATEN. In der Variablen ZeileMax steht dabei dynamisch die letzte belegte Zeile der Tabelle TBL_DATEN. So bleibt die Auswertung jederzeit dynamisch, selbst wenn das Datenvolumen zunehmen sollte.
Im ersten Parameter der Methode AutoFilter geben Sie die Nummer der Spalte an, die gefiltert werden soll. Dabei entspricht das Field:=2 der Spalte B von Tabelle TBL_DATEN. Als weiteren Parameter geben Sie die Länderliste, die in der Variablen VarDat verzeichnet ist, an. Im Parameter Operator geben Sie an, dass Sie Werte filtern möchten, indem Sie diesem Parameter die Konstante xlFilterValues zuweisen.
Als zweites Filterkriterium filtern Sie die Spalte C (Field:=3) und übergeben als Filterkriterium die Zeile 2 sowie die Spaltennummer der jeweils abzuarbeitenden Zelle, die Sie über die Eigenschaft Column bekannt geben.
Das Ergebnis der Filterung wird anschließend in die aktuell verarbeitende Zelle übertragen. Dabei wird mit Hilfe der Funktion Subtotal (=TEILERGEBNIS) die Summe bzw. die Anzahl der umgesetzten Mengen ermittelt. Hier ist wichtig zu wissen, dass Sie die Daten aus einer gefilterten Liste nicht mit den Standard-Excelfunktionen SUMME und ANZAHL2 ermitteln können. Stattdessen müssen Sie bei gefilterten Listen auf die Tabellenfunktion TEILERGEBNIS (vba: Subtotal) zurückgreifen. Dabei wird die Zahl 9 für die Summe und die Zahl 3 für die Zählung der gefilterten Datensätze verwendet.
Nach der Übertragung der Daten wenden Sie die Methode ShowAllData an, um wieder alle Sätze in der Tabelle TBL_DATEN anzuzeigen. Vergessen Sie nicht, am Ende des Makros die Bildschirmaktualisierung wieder einzuschalten, indem Sie der Eigenschaft ScreenUpdating den Wert True zuweisen.