In meiner täglichen Arbeit mit Excel stieß ich auf eine häufige Herausforderung: Wie ermittelt man effizient den letzten Wert eines Zellbereichs, der bestimmte Kriterien erfüllt? Die gängige Frank-Kabel-Lösung mittels Excel-Formel ist ein guter Ansatz, aber sie hat ihre Grenzen, besonders wenn man Werte ausschließen möchte, die sowohl 0 als auch leer (“”) sind. Als VBA-Entwickler suchte ich nach flexibleren Lösungen, die verschiedene Anforderungen erfüllen können.

Ermitteln mittels Excel-Formel

Um den letzten Wert eines Zellbereiches der > 0 ist zu ermitteln, kann man die bekannte Frank-Kabel-Lösung verwenden.

> =VERWEIS(2;1/(ZELLBEREICH<>0);ZELLBEREICH)

bzw. für Werte ungleich “” 

> =VERWEIS(2;1/(ZELLBEREICH<>””);ZELLBEREICH)

Das ganze hat jedoch folgende Einschränkung – man kann nicht festlegen, dass Zellbereich <> 0 und Zellbereich <> “” ausgewertet wird. (Jedenfalls habe ich noch keine Lösung dafür gefunden)

Ermitteln mittels VBA

' Funktion, um den letzten Wert in einem Zellbereich zu finden, der nicht Null und nicht leer ist
Function letzterWert(myRange As Range) As Double
' Deklariert eine Variable für die Durchlauf-Elemente in myRange
Dim element As Range
' Durchläuft jedes Element in dem übergebenen Zellbereich
For Each element In myRange
' Überprüft, ob der Wert des Elements weder Null noch leer ist
If element.Value <> 0 And element.Value <> "" Then
' Gibt die Adresse und den Wert des aktuellen Elements in der Direktfenster-Ausgabe aus
Debug.Print element.AddressLocal & " - " & element.Value
' Setzt den Wert des aktuellen Elements als Rückgabewert der Funktion
letzterWert = element.Value
End If
Next
End Function

Bei einzelnen Spalten oder Zeilen ist die Vorgehensweise des Skripts logisch (von oben nach unten, von links nach recht). Aber wie sieht es bei Zellbereichen aus, die sowohl mehrer Zeilen als auch mehrere Spalten haben. 

Das mag zwar praktisch sein, wirklich viel damit machen kann man aber noch nicht. Wie sieht es aus, wenn man statt horizontal vertikal auslesen möchte? Was ist wenn man den den 4.letzten Wert haben möchte usw. 

Ausgangslage ist folgender Bereich:

Mit der erweiterten Formel kann man dann den Bereich auch folgendermaßen auslesen:

erweiterte Formel

Option Explicit
' Funktion, um den letzten oder n-letzten Wert in einem Zellbereich zu finden
Function letzterWert_Extended(myRange As Range, Optional how As Integer = 1, _
Optional ignoreError As Boolean = True, _
Optional ignoreEmptyCells As Boolean = True, _
Optional ignorenull As Boolean = False, _
Optional Stelle As Integer = 1) As Variant
Dim i As Integer, j As Integer, counter As Integer
Dim myArray() As Variant
Dim bIgnore As Boolean
Dim returnValue As Variant
' Entscheidet, ob horizontal (1) oder vertikal (2) durchsucht werden soll
If how = 1 Or how = 2 Then
For i = 1 To IIf(how = 1, myRange.Rows.Count, myRange.Columns.Count)
For j = 1 To IIf(how = 1, myRange.Columns.Count, myRange.Rows.Count)
' Prüft auf leere Zellen, Fehler oder Nullwerte, um sie ggf. zu ignorieren
bIgnore = False
If IsEmpty(myRange.Cells(IIf(how = 1, i, j), IIf(how = 1, j, i)).Value) And ignoreEmptyCells Then
bIgnore = True
End If
If IsError(myRange.Cells(IIf(how = 1, i, j), IIf(how = 1, j, i)).Value) And ignoreError Then
bIgnore = True
End If
If IsNumeric(myRange.Cells(IIf(how = 1, i, j), IIf(how = 1, j, i)).Value) Then
If (myRange.Cells(IIf(how = 1, i, j), IIf(how = 1, j, i)).Value = 0) And ignorenull Then
bIgnore = True
End If
End If
' Speichert den Wert, wenn er nicht ignoriert wird
If Not bIgnore Then
ReDim Preserve myArray(counter)
myArray(counter) = myRange.Cells(IIf(how = 1, i, j), IIf(how = 1, j, i)).Value
returnValue = myArray(counter)
counter = counter + 1
End If
Next
Next
Else
returnValue = CVErr(xlErrNA)
End If
' Gibt den letzten oder den n-letzten Wert zurück
If Stelle = 1 Then
letzterWert = returnValue
Else
If counter >= Stelle Then
letzterWert = myArray(counter - Stelle)
Else
letzterWert = CVErr(xlErrNA)
End If
End If
End Function

Damit kann man nun eine Menge anstellen. Hier ein paar Beispiele:

Links