Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lernen Effiziente Datenverarbeitung | Arbeiten mit Excel-Daten
Excel VBA für Geschäftsautomatisierung

Effiziente Datenverarbeitung

Swipe um das Menü anzuzeigen

Bisher wurde immer nur eine Zelle nach der anderen bearbeitet – ausreichend für fünf Bestellungen, aber extrem langsam bei fünfzigtausend. Die Lösung besteht darin, nicht mehr Zelle für Zelle auf das Arbeitsblatt zuzugreifen, sondern den gesamten Bereich in ein Array im Speicher zu laden, dort zu bearbeiten und anschließend in einem Schritt zurückzuschreiben.

Einlesen eines Bereichs in ein Array

Dim dataArr As Variant
dataArr = ws.Range("A2:I6").Value    ' one read, not 45 individual reads

dataArr ist jetzt ein zweidimensionales Array im Speicher: dataArr(1,1) ist ORD1001, dataArr(1,4) ist "Laptop Stand" und so weiter — VBA-Arrays, die aus einem Bereich gelesen werden, sind 1-basiert, nicht 0-basiert, was häufig zu Verwirrung führt.

Verarbeitung des Arrays

Erfolgt mit normalen Schleifen – allerdings wird jetzt im Speicher gearbeitet, was tausendfach schneller ist als das Durchlaufen des Arbeitsblatts:

Dim i As Long
Dim recalculated As Double
 
For i = 1 To UBound(dataArr, 1)
    recalculated = dataArr(i, 5) * dataArr(i, 6) * (1 - dataArr(i, 7))
    If Abs(recalculated - dataArr(i, 8)) > 0.01 Then
        Debug.Print "Mismatch on row " & i & ": sheet says " & dataArr(i, 8) & _
                    ", recalculated " & Format(recalculated, "0.00")
    End If
Next i

Zurückschreiben des Arrays

Wieder ein einziger Vorgang:

ws.Range("A2:I6").Value = dataArr

Vermeidung von Select und Activate

Aufgezeichnete Makros verwenden diese häufig (Range("A1").Select gefolgt von Selection.Font.Bold = True), aber sie sind unnötig und langsam – jedes .Select zwingt Excel dazu, den Bildschirm neu zu zeichnen. Stattdessen den Bereich oder das Objekt direkt referenzieren:

' Avoid:
ws.Range("A1").Select
Selection.Font.Bold = True
 
' Prefer:
ws.Range("A1").Font.Bold = True

Leistungsaspekte

Diese werden relevant, sobald Ihre Daten mehr als ein paar hundert Zeilen umfassen:

Application.ScreenUpdating = False   ' stop redrawing while the macro runs
Application.Calculation = xlCalculationManual   ' pause recalculation
Application.EnableEvents = False     ' suppress other macros triggering mid-run
 
' ... your fast array-based code here ...
 
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True

Diese Einstellungen immer am Ende wiederherstellen – und die Wiederherstellung in eine Fehlerbehandlung einbinden, damit Excel bei einem Absturz nicht mit deaktivierter Bildschirmaktualisierung zurückbleibt.

Durchgearbeitetes Beispiel: Der Order Integrity Checker

Dieses Kapitel läuft auf Folgendes hinaus:

Option Explicit
 
Sub VerifyOrderTotals()
    Dim ws As Worksheet
    Dim dataArr As Variant
    Dim lastRow As Long
    Dim i As Long
    Dim recalculated As Double
    Dim issues As String
 
    Set ws = ThisWorkbook.Worksheets("Orders")
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
 
    Application.ScreenUpdating = False
 
    dataArr = ws.Range("A2:I" & lastRow).Value
    issues = ""
 
    For i = 1 To UBound(dataArr, 1)
        recalculated = dataArr(i, 5) * dataArr(i, 6) * (1 - dataArr(i, 7))
        If Abs(recalculated - dataArr(i, 8)) > 0.01 Then
            issues = issues & dataArr(i, 1) & ": sheet=" & dataArr(i, 8) & _
                      ", expected=" & Format(recalculated, "0.00") & vbNewLine
        End If
    Next i
 
    Application.ScreenUpdating = True
 
    If issues = "" Then
        MsgBox "All " & UBound(dataArr, 1) & " order totals check out."
    Else
        MsgBox "Discrepancies found:" & vbNewLine & issues
    End If
End Sub

Führen Sie dies mit der Beispieltabelle aus und es sollten alle fünf Summen als korrekt gemeldet werden – ändern Sie zum Testen den Wert von ORD1002 im Feld Total auf einen falschen Wert und führen Sie das Makro erneut aus, um die Fehlermeldung zu sehen.

Aufgabe

  1. Kopieren Sie VerifyOrderTotals in Ihre Arbeitsmappe und führen Sie es für die fünf Beispielaufträge aus.
  2. Ändern Sie manuell den Wert von Total eines Auftrags im Tabellenblatt (geben Sie eine offensichtlich falsche Zahl ein) und führen Sie das Makro erneut aus – bestätigen Sie, dass die Abweichung mit der richtigen Order ID gemeldet wird.
  3. Fügen Sie zehn weitere Zeilen mit erfundenen Auftragsdaten unterhalb von Zeile 6 hinzu und prüfen Sie, ob das Makro weiterhin ohne Codeänderungen funktioniert – das ist der Vorteil von lastRow und Array-Verarbeitung.
Helfer
expand arrow

Optionaler Helfer, falls Sie die zehn zusätzlichen Zeilen lieber per Code generieren möchten, anstatt sie von Hand einzutippen:

Sub AddTestOrders()
    Dim ws As Worksheet
    Dim i As Long
    Dim r As Long

    Set ws = ThisWorkbook.Worksheets("Orders")
    r = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1

    For i = 1 To 10
        ws.Cells(r, 1).Value = "ORD" & (1005 + i)
        ws.Cells(r, 2).Value = Date
        ws.Cells(r, 3).Value = "Test Customer " & i
        ws.Cells(r, 4).Value = "Sample Product"
        ws.Cells(r, 5).Value = i
        ws.Cells(r, 6).Value = 20 + i
        ws.Cells(r, 7).Value = 0.05
        ws.Cells(r, 8).Value = i * (20 + i) * (1 - 0.05)
        ws.Cells(r, 9).Value = "Pending"
        r = r + 1
    Next i
End Sub
Hinweis
expand arrow

1. Kopieren von VerifyOrderTotals

  • Geben Sie das Sub exakt wie in Abschnitt 3.5 gezeigt in das Modul Ihrer Arbeitsmappe ein — noch keine Änderungen nötig.
  • Führen Sie es einmal für die fünf ursprünglichen Zeilen aus und bestätigen Sie, dass Sie "All 5 order totals check out." erhalten.

2. Einen Total absichtlich fehlerhaft machen

  • Wählen Sie eine beliebige Total-Zelle einer Bestellung und geben Sie direkt im Arbeitsblatt (nicht per Code) eine offensichtlich falsche Zahl ein.
  • Führen Sie das gleiche Sub erneut aus — die Fehlermeldung sollte genau diese Order ID nennen, zusammen mit dem Wert aus dem Blatt und dem vom Makro neu berechneten Wert.
  • Korrigieren Sie die Zelle anschließend wieder, wenn Sie ein sauberes Blatt für den nächsten Schritt möchten.

3. Zehn weitere Zeilen hinzufügen

  • Geben Sie einfach neue Bestelldaten direkt in die Zeilen 7–16 ein — dieselben neun Spalten, beliebige plausible Werte.
  • Das Makro bleibt völlig unberührt. lastRow berechnet sich bei jedem Lauf des Sub automatisch neu, und das Array-Lesen (ws.Range("A2:I" & lastRow).Value) wächst automatisch mit — genau das soll hier demonstriert werden.
Lösung
expand arrow
Option Explicit

Sub VerifyOrderTotals()
    Dim ws As Worksheet
    Dim dataArr As Variant
    Dim lastRow As Long
    Dim i As Long
    Dim recalculated As Double
    Dim issues As String

    Set ws = ThisWorkbook.Worksheets("Orders")
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

    Application.ScreenUpdating = False

    dataArr = ws.Range("A2:I" & lastRow).Value
    issues = ""

    For i = 1 To UBound(dataArr, 1)
        recalculated = dataArr(i, 5) * dataArr(i, 6) * (1 - dataArr(i, 7))
        If Abs(recalculated - dataArr(i, 8)) > 0.01 Then
            issues = issues & dataArr(i, 1) & ": sheet=" & dataArr(i, 8) & _
                      ", expected=" & Format(recalculated, "0.00") & vbNewLine
        End If
    Next i

    Application.ScreenUpdating = True

    If issues = "" Then
        MsgBox "All " & UBound(dataArr, 1) & " order totals check out."
    Else
        MsgBox "Discrepancies found:" & vbNewLine & issues
    End If
End Sub
War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 3. Kapitel 5

Fragen Sie AI

expand

Fragen Sie AI

ChatGPT

Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen

Effiziente Datenverarbeitung

Bisher wurde immer nur eine Zelle nach der anderen bearbeitet – ausreichend für fünf Bestellungen, aber extrem langsam bei fünfzigtausend. Die Lösung besteht darin, nicht mehr Zelle für Zelle auf das Arbeitsblatt zuzugreifen, sondern den gesamten Bereich in ein Array im Speicher zu laden, dort zu bearbeiten und anschließend in einem Schritt zurückzuschreiben.

Einlesen eines Bereichs in ein Array

Dim dataArr As Variant
dataArr = ws.Range("A2:I6").Value    ' one read, not 45 individual reads

dataArr ist jetzt ein zweidimensionales Array im Speicher: dataArr(1,1) ist ORD1001, dataArr(1,4) ist "Laptop Stand" und so weiter — VBA-Arrays, die aus einem Bereich gelesen werden, sind 1-basiert, nicht 0-basiert, was häufig zu Verwirrung führt.

Verarbeitung des Arrays

Erfolgt mit normalen Schleifen – allerdings wird jetzt im Speicher gearbeitet, was tausendfach schneller ist als das Durchlaufen des Arbeitsblatts:

Dim i As Long
Dim recalculated As Double
 
For i = 1 To UBound(dataArr, 1)
    recalculated = dataArr(i, 5) * dataArr(i, 6) * (1 - dataArr(i, 7))
    If Abs(recalculated - dataArr(i, 8)) > 0.01 Then
        Debug.Print "Mismatch on row " & i & ": sheet says " & dataArr(i, 8) & _
                    ", recalculated " & Format(recalculated, "0.00")
    End If
Next i

Zurückschreiben des Arrays

Wieder ein einziger Vorgang:

ws.Range("A2:I6").Value = dataArr

Vermeidung von Select und Activate

Aufgezeichnete Makros verwenden diese häufig (Range("A1").Select gefolgt von Selection.Font.Bold = True), aber sie sind unnötig und langsam – jedes .Select zwingt Excel dazu, den Bildschirm neu zu zeichnen. Stattdessen den Bereich oder das Objekt direkt referenzieren:

' Avoid:
ws.Range("A1").Select
Selection.Font.Bold = True
 
' Prefer:
ws.Range("A1").Font.Bold = True

Leistungsaspekte

Diese werden relevant, sobald Ihre Daten mehr als ein paar hundert Zeilen umfassen:

Application.ScreenUpdating = False   ' stop redrawing while the macro runs
Application.Calculation = xlCalculationManual   ' pause recalculation
Application.EnableEvents = False     ' suppress other macros triggering mid-run
 
' ... your fast array-based code here ...
 
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True

Diese Einstellungen immer am Ende wiederherstellen – und die Wiederherstellung in eine Fehlerbehandlung einbinden, damit Excel bei einem Absturz nicht mit deaktivierter Bildschirmaktualisierung zurückbleibt.

Durchgearbeitetes Beispiel: Der Order Integrity Checker

Dieses Kapitel läuft auf Folgendes hinaus:

Option Explicit
 
Sub VerifyOrderTotals()
    Dim ws As Worksheet
    Dim dataArr As Variant
    Dim lastRow As Long
    Dim i As Long
    Dim recalculated As Double
    Dim issues As String
 
    Set ws = ThisWorkbook.Worksheets("Orders")
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
 
    Application.ScreenUpdating = False
 
    dataArr = ws.Range("A2:I" & lastRow).Value
    issues = ""
 
    For i = 1 To UBound(dataArr, 1)
        recalculated = dataArr(i, 5) * dataArr(i, 6) * (1 - dataArr(i, 7))
        If Abs(recalculated - dataArr(i, 8)) > 0.01 Then
            issues = issues & dataArr(i, 1) & ": sheet=" & dataArr(i, 8) & _
                      ", expected=" & Format(recalculated, "0.00") & vbNewLine
        End If
    Next i
 
    Application.ScreenUpdating = True
 
    If issues = "" Then
        MsgBox "All " & UBound(dataArr, 1) & " order totals check out."
    Else
        MsgBox "Discrepancies found:" & vbNewLine & issues
    End If
End Sub

Führen Sie dies mit der Beispieltabelle aus und es sollten alle fünf Summen als korrekt gemeldet werden – ändern Sie zum Testen den Wert von ORD1002 im Feld Total auf einen falschen Wert und führen Sie das Makro erneut aus, um die Fehlermeldung zu sehen.

Aufgabe

  1. Kopieren Sie VerifyOrderTotals in Ihre Arbeitsmappe und führen Sie es für die fünf Beispielaufträge aus.
  2. Ändern Sie manuell den Wert von Total eines Auftrags im Tabellenblatt (geben Sie eine offensichtlich falsche Zahl ein) und führen Sie das Makro erneut aus – bestätigen Sie, dass die Abweichung mit der richtigen Order ID gemeldet wird.
  3. Fügen Sie zehn weitere Zeilen mit erfundenen Auftragsdaten unterhalb von Zeile 6 hinzu und prüfen Sie, ob das Makro weiterhin ohne Codeänderungen funktioniert – das ist der Vorteil von lastRow und Array-Verarbeitung.
Helfer
expand arrow

Optionaler Helfer, falls Sie die zehn zusätzlichen Zeilen lieber per Code generieren möchten, anstatt sie von Hand einzutippen:

Sub AddTestOrders()
    Dim ws As Worksheet
    Dim i As Long
    Dim r As Long

    Set ws = ThisWorkbook.Worksheets("Orders")
    r = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1

    For i = 1 To 10
        ws.Cells(r, 1).Value = "ORD" & (1005 + i)
        ws.Cells(r, 2).Value = Date
        ws.Cells(r, 3).Value = "Test Customer " & i
        ws.Cells(r, 4).Value = "Sample Product"
        ws.Cells(r, 5).Value = i
        ws.Cells(r, 6).Value = 20 + i
        ws.Cells(r, 7).Value = 0.05
        ws.Cells(r, 8).Value = i * (20 + i) * (1 - 0.05)
        ws.Cells(r, 9).Value = "Pending"
        r = r + 1
    Next i
End Sub
Hinweis
expand arrow

1. Kopieren von VerifyOrderTotals

  • Geben Sie das Sub exakt wie in Abschnitt 3.5 gezeigt in das Modul Ihrer Arbeitsmappe ein — noch keine Änderungen nötig.
  • Führen Sie es einmal für die fünf ursprünglichen Zeilen aus und bestätigen Sie, dass Sie "All 5 order totals check out." erhalten.

2. Einen Total absichtlich fehlerhaft machen

  • Wählen Sie eine beliebige Total-Zelle einer Bestellung und geben Sie direkt im Arbeitsblatt (nicht per Code) eine offensichtlich falsche Zahl ein.
  • Führen Sie das gleiche Sub erneut aus — die Fehlermeldung sollte genau diese Order ID nennen, zusammen mit dem Wert aus dem Blatt und dem vom Makro neu berechneten Wert.
  • Korrigieren Sie die Zelle anschließend wieder, wenn Sie ein sauberes Blatt für den nächsten Schritt möchten.

3. Zehn weitere Zeilen hinzufügen

  • Geben Sie einfach neue Bestelldaten direkt in die Zeilen 7–16 ein — dieselben neun Spalten, beliebige plausible Werte.
  • Das Makro bleibt völlig unberührt. lastRow berechnet sich bei jedem Lauf des Sub automatisch neu, und das Array-Lesen (ws.Range("A2:I" & lastRow).Value) wächst automatisch mit — genau das soll hier demonstriert werden.
Lösung
expand arrow
Option Explicit

Sub VerifyOrderTotals()
    Dim ws As Worksheet
    Dim dataArr As Variant
    Dim lastRow As Long
    Dim i As Long
    Dim recalculated As Double
    Dim issues As String

    Set ws = ThisWorkbook.Worksheets("Orders")
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

    Application.ScreenUpdating = False

    dataArr = ws.Range("A2:I" & lastRow).Value
    issues = ""

    For i = 1 To UBound(dataArr, 1)
        recalculated = dataArr(i, 5) * dataArr(i, 6) * (1 - dataArr(i, 7))
        If Abs(recalculated - dataArr(i, 8)) > 0.01 Then
            issues = issues & dataArr(i, 1) & ": sheet=" & dataArr(i, 8) & _
                      ", expected=" & Format(recalculated, "0.00") & vbNewLine
        End If
    Next i

    Application.ScreenUpdating = True

    If issues = "" Then
        MsgBox "All " & UBound(dataArr, 1) & " order totals check out."
    Else
        MsgBox "Discrepancies found:" & vbNewLine & issues
    End If
End Sub
War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 3. Kapitel 5
some-alt