Zurück zur Homepage

Häufigkeit von Werten ermitteln

Manchmal möchte man wissen, wie oft ein Wert in einem Bereich vorkommt. Dazu kann man die Tabellenfunktion Zählenwenn verwenden. Will man wissen, wie häufig unbekannte Werte in einem Bereich vorkommen, sollte man sich eine Pivot-Tabelle anschauen. Ein kleines Makro schafft das aber auch. Möglicherweise ist die Methode bei größeren Bereichen etwas langsam, aber Geschwindigkeit ist bekanntlich relativ.

Beispielmappe (histogramm.zip 17 KB
 

'Click-Ereignis von Buttons auf einem Tabellenblatt
'Der Bereich hat den Namen "Testbereich"

Private Sub cmbAnzeigen_Click()
    WerteZählenAnzeigen Me.Range("Testbereich")
End Sub

Private Sub cmbListe_Click()
Dim x As Collection, i As Long
Set x = Zählen(Me.Range("Testbereich"))
Me.Range("A6:B65536").ClearContents
For i = 1 To x.Count
    Me.Cells(i + 5, 1) = x(i)("Anzahl")
    Me.Cells(i + 5, 2) = x(i)("Wert")
Next
End Sub

 

'In ein Modul

Option Explicit
Public Function Zählen(Bereich As Range) As Collection
Dim x As New Collection, y As Variant
Dim z As Collection, Anzahl As Long
On Error Resume Next 'Wichtig
For Each y In Bereich
    'Eine neue Collection für Wert und Anzahl anlegen
    Set z = New Collection
    'Wert ablegen
    z.Add y.Value, "Wert"
    'Anzahl auf 1
    z.Add 1, "Anzahl"
    'Das Error Objekt zurücksetzen
    Err.Clear
    'Jeder Schlüssel einer Collection ist einmalig.
    'Beim Versuch, einen neuen Eintrag mit dem gleichen
    'Key zu erstellen, gibt es einen Fehler, der aber
    'durch die Zeile 'On Error Resume Next' ignoriert wird.
    'Deshalb für beliebig viel gleiche Werte nur ein Item.

    If y <> "" Then x.Add z, "X" & y.Value
    If Err.Number > 0 Then
        'Der Eintrag ist schon mal vorhanden
        'Erst einmal Anzahl ermitteln

        Anzahl = x("X" & y.Value)("Anzahl")
        'Eine neue Collection für Wert und Anzahl anlegen
        Set z = New Collection
        'Wert ablegen
        z.Add y.Value, "Wert"
        'Anzahl auf Anzahl + 1
        z.Add Anzahl + 1, "Anzahl"
        'Erst alten Eintrag löschen
        x.Remove ("X" & y.Value)
        'Dann neuen mit neuer Anzahl anlegen
        x.Add z, "X" & y.Value
    End If
Next
Set Zählen = x
End Function


Public Sub WerteZählenAnzeigen(Bereich As Range)

Dim x As New Collection, y As Variant
Dim z As Collection, Anzahl As Long
Dim Meldung As String
On Error Resume Next 'Wichtig
For Each y In Bereich
    'Eine neue Collection für Wert und Anzahl anlegen
    Set z = New Collection
    'Wert ablegen
    z.Add y.Value, "Wert"
    'Anzahl auf 1
    z.Add 1, "Anzahl"
    'Das Error Objekt zurücksetzen
    Err.Clear
    'Jeder Schlüssel einer Collection ist einmalig.
    'Beim Versuch, einen neuen Eintrag mit dem gleichen
    'Key zu erstellen, gibt es einen Fehler, der aber
    'durch die Zeile 'On Error Resume Next' ignoriert wird.
    'Deshalb für beliebig viel gleiche Werte nur ein Item.

    If y <> "" Then x.Add z, "X" & y.Value
    If Err.Number > 0 Then
        'Der Eintrag ist schon mal vorhanden
        'Erst einmal Anzahl ermitteln

        Anzahl = x("X" & y.Value)("Anzahl")
        'Eine neue Collection für Wert und Anzahl anlegen
        Set z = New Collection
        'Wert ablegen
        z.Add y.Value, "Wert"
        'Anzahl auf Anzahl + 1
        z.Add Anzahl + 1, "Anzahl"
        'Erst alten Eintrag löschen
        x.Remove ("X" & y.Value)
        'Dann neuen mit neuer Anzahl anlegen
        x.Add z, "X" & y.Value
    End If
Next
'Anzahl der Items in der Collection ermitteln
Meldung = x.Count & " verschiedene Werte gefunden" & vbCrLf
For Each y In x
    'Alle Items der Collection durchlaufen und die Werte
    'zu einem String zusammensetzen.

    Meldung = Meldung & y("Anzahl") & " mal " & y("Wert") & vbCrLf
Next
'Die Msgbox kann aber leider nur eine begrenzte Zahl Zeilen darstellen
MsgBox Meldung
End Sub