Private Sub Worksheet_Change(ByVal Target As Range)
Dim ws As Worksheet
Dim rowStart As Long
Dim colD As Long, colE As Long, colF As Long
Dim colG As Long, colH As Long, colI As Long
Dim colJ As Long, colK As Long, colL As Long
Dim r As Long
Dim previousRow As Long
' Initialisierung
Set ws = Me ' Aktuelles Arbeitsblatt
rowStart = 4 ' Formel beginnt ab Zeile 4
colD = 4 ' Spalte D
colE = 5 ' Spalte E
colF = 6 ' Spalte F
colG = 7 ' Spalte G
colH = 8 ' Spalte H
colI = 9 ' Spalte I
colJ = 10 ' Spalte J
colK = 11 ' Spalte K
colL = 12 ' Spalte L
' Prüfen, ob die Änderung in den relevanten Spalten erfolgt ist
If Intersect(Target, ws.Columns(colD)) Is Nothing _
Or Intersect(Target, ws.Columns(colE)) Is Nothing _
Or Intersect(Target, ws.Columns(colF)) Is Nothing _
Or Intersect(Target, ws.Columns(colG)) Is Nothing _
Or Intersect(Target, ws.Columns(colH)) Is Nothing _
Or Intersect(Target, ws.Columns(colI)) Is Nothing _
Or Intersect(Target, ws.Columns(colJ)) Is Nothing _
Or Intersect(Target, ws.Columns(colK)) Is Nothing _
Or Intersect(Target, ws.Columns(colL)) Is Nothing Then Exit Sub
Exit Sub
' End If
Application.EnableEvents = False ' Verhindert Endlosschleifen durch Worksheet_Change
' Schleife durch die geänderten Zellen
For Each Cell In Target
r = Cell.Row
' Nur für Zeilen ab rowStart
If r >= rowStart Then
' Verarbeitung für Spalten D, E, F
If Not IsEmpty(ws.Cells(r, colD).Value) Or Not IsEmpty(ws.Cells(r, colE).Value) Then
previousRow = FindLastNonEmptyRow(ws, colF) ' ? Nur zwei Argumente
'' previousRow = FindLastNonEmptyRow(ws, colF, r, rowStart)
If previousRow > 0 Then
ws.Cells(r, colF).Formula = _
"=" & ws.Cells(previousRow, colF).Address & "+" & _
ws.Cells(r, colE).Address & "-" & ws.Cells(r, colD).Address
Debug.Print "Formel eingetragen für Zeile " & r & ": " & ws.Cells(r, colF).Formula
Else
ws.Cells(r, colF).Formula = _
"=" & ws.Cells(2, colF).Address & "+" & ws.Cells(r, colE).Address & "-" & ws.Cells(r, colD).Address
End If
Else
ws.Cells(r, colF).ClearContents
End If
' Verarbeitung für Spalten G, H, I
If Not IsEmpty(ws.Cells(r, colG).Value) Or Not IsEmpty(ws.Cells(r, colH).Value) Then
previousRow = FindLastNonEmptyRow(ws, colI) ' ? Nur zwei Argumente
'' previousRow = FindLastNonEmptyRow(ws, colI, r, rowStart)
If previousRow > 0 Then
ws.Cells(r, colI).Formula = _
"=" & ws.Cells(previousRow, colI).Address & "+" & _
ws.Cells(r, colH).Address & "-" & ws.Cells(r, colG).Address
Debug.Print "Formel eingetragen für Zeile " & r & ": " & ws.Cells(r, colI).Formula
Else
ws.Cells(r, colI).Formula = _
"=" & ws.Cells(2, colI).Address & "+" & ws.Cells(r, colH).Address & "-" & ws.Cells(r, colG).Address
End If
Else
ws.Cells(r, colI).ClearContents
End If
' Verarbeitung für Spalten J, K, L
If Not IsEmpty(ws.Cells(r, colJ).Value) Or Not IsEmpty(ws.Cells(r, colK).Value) Then
previousRow = FindLastNonEmptyRow(ws, colL) ' ? Nur zwei Argumente
' previousRow = FindLastNonEmptyRow(ws, colL, r, rowStart)
If previousRow > 0 Then
ws.Cells(r, colL).Formula = _
"=" & ws.Cells(previousRow, colL).Address & "+" & _
ws.Cells(r, colK).Address & "-" & ws.Cells(r, colJ).Address
Debug.Print "Formel eingetragen für Zeile " & r & ": " & ws.Cells(r, colL).Formula
Else
ws.Cells(r, colL).Formula = _
"=" & ws.Cells(2, colL).Address & "+" & ws.Cells(r, colK).Address & "-" & ws.Cells(r, colJ).Address
End If
Else
ws.Cells(r, colL).ClearContents
End If
End If
Next Cell
Application.EnableEvents = True ' Ereignisse wieder aktivieren
End Sub
' Funktion zur Suche der letzten Zeile mit einem tatsächlichen Wert in einer Spalte
Private Function FindLastNonEmptyRow(ws As Worksheet, col As Long) As Long
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, col).End(xlUp).Row
If lastRow < 4 Then FindLastNonEmptyRow = 4 Else FindLastNonEmptyRow = lastRow
End Function