Live-Forum - Die aktuellen Beiträge
Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Langsames Makro beschleunigen

Forumthread: Langsames Makro beschleunigen

Langsames Makro beschleunigen
03.04.2020 08:34:04
Mayerhofer
Guten Morgen zusammen,
mein Makro quält mich nun schon seit Tagen. Es ist einfach MEGA LANGSAM. Ich habe mich durch die einschlägigen Beiträge gelesen und diverse Anpassungen vorgenommen - aber die Performance ist bescheiden. Wäre klasse, wenn ihr mir helfen würdet.
Zum Makro: Es soll auf Basis von drei Selektionskriterien Zeile für Zeile durchgehen und bei einem Match eine Zeile duplizieren und an diversen Stellen (Zellen) Änderungen / Einträge vornehmen.
So sieht das aktuell aus:

Sub RUESTEN_separieren_Tabellenblatt()
Dim zeile As Integer
Dim rueckmeldeart As String
zeile = ActiveCell.Row
rueckmeldeart = ""
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Do Until zeile = 6000 Or Range("A" & zeile).Value = "" And Range("I" & zeile).Value = ""
If ActiveCell.Offset(0, 10).Value = "Arbeit" And ActiveCell.Offset(0, 12).Value  "" And    _
_
_
ActiveCell.Offset(0, 14).Value  "" Then
Rows(zeile).Select
Selection.Copy
Selection.Insert Shift:=xlDown
ActiveCell.EntireRow.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
ActiveCell.Activate
ActiveCell.Offset(0, 6).Value = "AFO0001"
ActiveCell.Offset(0, 7).Value = "Rüsten"
ActiveCell.Offset(0, 12).Value = ""
ActiveCell.Offset(0, 15).Value = ""
ActiveCell.Offset(0, 16).Value = "nach Maschinen- und Einstellblatt"
ActiveCell.Offset(1, 14).Value = ""
rueckmeldeart = ActiveCell.Offset(1, 20).Value
ActiveCell.Offset(0, 20).Value = rueckmeldeart
ActiveCell.Offset(0, 22).Value = "A1"
ActiveCell.Offset(1, 22).Value = "A2"
Else
ActiveCell.Offset(1, 0).Select
End If
Range("A" & zeile).Activate
zeile = zeile + 1
ActiveCell.Offset(1, 0).Select
Loop
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Call Calculate
End Sub

Die Zeilensuche funktioniert ganz ordentlich hinsichtlich Geschwindigkeit - nur die Zeilenbearbeitung... Die wird von Zeile für Zeile langsamer.
Für eure Rückmeldungen - schon mal herzlichen Dank
Anzeige

16
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Langsames Makro beschleunigen
03.04.2020 09:37:58
Luschi
Hallo Mayerhofer,
das hat mehrere Ursachen:
- Select-Befehl ist langsam und unnötig-
- arbeite mit Range-Objectvariablen
- bei Schleifen mit Zeilen-Einfügen-Befehlen ist es besser
  von letzter möglicher Zeile nach oben zu arbeiten
- ist das 'Worksheet_Change' oder 'Workbook_SheetChange' definiert
- muß die Application.EnableEvents-Eigenschaft vorübergehend abgeschaltet werden
Mit einem Testbeispiel kann Dir besser geholfen werden, als mit verbalen Beschreibungen.
Gruß von Luschi
aus klein-Paris
Anzeige
AW: Langsames Makro beschleunigen
03.04.2020 09:58:35
Herbert
Hallo,
wenn du die Daten zuerst in einem Array sammelst und erst am Ende in einem Rutsch in das Sheet schreibst, dann geht das ruckizucki! Falls du nicht weißt wie das geht, gib kurz Bescheid.
Servus
AW: Langsames Makro beschleunigen
03.04.2020 11:23:22
Luschi
Hallo Herbert,
Dein Vorschlag mit dem Array-Gedöns klingt gut, aber bei Array-Kopieroperationen mittendrin (Rows-Insert-Operation) dürften selbst ambitionierte Vba-Entwickler zurückschrecken.
Ich habe sowas in einem C#-AddIn für Excel demonstriert, aber glaube mir, das war kein Zusckerschlecken und den Zeitaufwand kann man bei der heutigen 'Geiz-ist-Geil-Mentalität' Niemanden in Rechnung stellen - aber den Spaß war's wert.
Gruß von Luschi
aus klein-Paris
Anzeige
AW: Langsames Makro beschleunigen
03.04.2020 12:08:37
Herbert
Hallo Luschi,
da werde ich mich deiner geballten Kompetenz nicht verweigern und lasse das mit dem Array lieber. Danke für den Hinweis!
Servus
AW: Langsames Makro beschleunigen
03.04.2020 10:02:56
Daniel
Hi
Kannst du Mal ne Beispieldatei mit zwei Blättern hochladen?
Es sollten dein Makro und ein paar Datenzeilen vorhanden sein, mit denen man dann dein und sein neues Makro testen kann.
Gruß Daniel
Anzeige
AW: Langsames Makro beschleunigen
03.04.2020 10:04:53
Herbert
Hallo Daniel,
genau, das hatte ich noch vergessen dazu zu schreiben. Danke fürs mitdenken!
Servus
AW: Langsames Makro beschleunigen
03.04.2020 10:10:05
Daniel
Hi
Ich würde so vorgehen:
1. Schreibe die Zeilennummer in eine Hilfsspalte
2. Sortiere nach den Bedingungsspalten, so dass alle zu duplizierenden Zeilen direkt untereinander stehen
3. Kopiere den Block und füge ihn unten an.
4. Nimm im eingefügten Block die Veränderungen vor, dabei kannst du jede Spalte in einem Schritt bearbeiten.
5. Sortiere über die Hilfsspalte in die Originalreihenfolge zurück.
Gruß Daniel
Anzeige
AW: Langsames Makro beschleunigen
03.04.2020 12:47:46
Mayerhofer
Hallo Luschi, Herbert und Daniel,
vielen dank, dass ihr euch zu meiner Anfrage gemeldet habt.
Gleich vorweg; Ich bin VBA Laie. Das mit der Änderung in Range-Befehle verstehe ich noch - Array - sagt mir nichts.
Die Idee, die zu modifizierenden Zeilen aus der Tabelle zu extrahieren und separat zu modifizieren wäre mir zu riskant, dass da beim Zurückspielen ein Wurm reinkommt.
Ich habe einen Datenauszug erstellt und hochgeladen
https://www.herber.de/bbs/user/136374.zip
Wäre klasse, wenn es den Turbo gäbe. Ich habe das Makro mal bis Zeile 1250 laufen lassen - da war es dann so langsam, dass ich abbrechen musste.
Grüße Julius
Anzeige
AW: Langsames Makro beschleunigen
03.04.2020 16:46:52
Mayerhofer
Hallo Luschi,
ganz herzliches Dankeschön für dein Makro. Ich hab das gerade mal gestartet. Da es sich um knapp 7000 Datenzeilen und um ca 1800 Zeilen handelt, die diese Kopierfunktion benötigen, bin ich gespannt, wie lange er dazu benötigt. Sobald es durch ist - melde ich mich.
Grüße
Julius
Anzeige
AW: Langsames Makro beschleunigen
03.04.2020 19:14:29
Mayerhofer
Hallo Luschi, so, Lauf ist durch. Knapp 60min - dafür fehlerfrei in einem Rutsch. Vielen Dank. Du hast mir sehr geholfen
Grüße
Julius
AW: Langsames Makro beschleunigen
03.04.2020 14:18:55
Daniel
Hi
probier mal diesen Code.
er liefert bei mir mir der Beispieldatei das gleiche Ergebnis wie dein Code, sollte aber etwas schneller sein, auch bei größeren Datenmengen.
ich hab ein paar Kommentare eingefügt, damit du siehst was in diesem Programmabschnitt gemacht wird.
der Ablauf entspricht dem, was ich in meinem ersten Beitrag beschrieben habe.
durch die Zeilennummer in der Hilfsspalte wird die korrekte Rücksortierung gewährleistet.
Sub RüstenEinbauen()
Dim S1 As Long, S2 As Long
Dim rng1 As Range, rng2 As Range
With ActiveSheet.UsedRange
'--- Reihenfolge sichern
With .Columns(.Columns.Count + 1)
S1 = .Column
.Cells(1, 1).Value = 1
.DataSeries Rowcol:=xlColumns, Type:=xlLinear, Step:=1
End With
'--- zu bearbeitende Zeilen kennzeichnen
With .Columns(.Columns.Count + 2)
S2 = .Column
.FormulaR1C1 = "=if(AND(RC11=""Arbeit"",RC13"""",RC15""""),1,"""")"
.Formula = .Value
End With
End With
With ActiveSheet.UsedRange
'--- umsortieren, zu kopierende Zeilen in einen Block
.Sort Key1:=.Cells(1, S2), order1:=xlAscending, Header:=xlNo
'--- kopieren, dabei kopier und einfügebereich in Variablen merken
Set rng1 = Intersect(.Cells, .Columns(S2).SpecialCells(xlCellTypeConstants, 1).EntireRow)
rng1.Copy
Cells(.Row + .Rows.Count, 1).PasteSpecial xlPasteAll
Set rng2 = Selection
'--- Bearbeigung durchführen
With rng1
.Columns(7).Value = "AF00001"
.Columns(8).Value = "Rüsten"
.Columns(13).ClearContents
.Columns(16).ClearContents
.Columns(17).Value = "nach Maachinen- und Einstellblatt"
.Columns(23) = "A1"
End With
With rng2
.Columns(23) = "A2"
.Columns(15).ClearContents
End With
End With
'--- Rücksortieren und Hilfsspalten leeren
With ActiveSheet.UsedRange
.Sort Key1:=.Cells(1, S1), order1:=xlAscending, Header:=xlNo
.Columns(S1).ClearContents
.Columns(S2).ClearContents
End With
End Sub
wie gesagt, ich habe den Code mit deinen Beispieldaten getestet.
probiers mal mit deinen Echtdaten.
Gruß Daniel
Anzeige
AW: Langsames Makro beschleunigen
03.04.2020 16:50:07
Mayerhofer
Hallo Daniel,
auch dir ein herzliches Dankeschön für deinen Einsatz. Gerade test ich den Vorschlag von Luschi. Dann lasse ich gerne dein Makro mal drüberlaufen. In Summe sind es 7000 Datenzeilen, in denen sich knapp 1800 Zeilen befinden, die diese Dopplung benötigen. Das dauert vermutlich etwas. Sobald ich die Ergebnisse habe, stelle ich die gerne hier noch rein.
Grüße
Julius
Anzeige
AW: Langsames Makro beschleunigen
03.04.2020 19:16:19
Mayerhofer
Hallo Daniel, Konnte jetzt meine Tabelle final bearbeiten. Danke für deinen Einsatz. Grüße Julius
Es wäre nett von dir gewesen Julius,
03.04.2020 19:52:23
dir
wenn du ein paar mehr Worte zu meinem Makro zu sagen hättest, ins besondere zur Laufzeit.
Wenn ich mir schon die Mühe mache, Dir einen Code zu schreiben, dann könntest du auch kurz darüber berichten.
Zumal ich davon ausgegangen bin, dass mein Code etwas schneller ist als 60 Minuten.
60 Sekunden sind für diese Aufgabenstellung schon viel.
auch ohne Makro sollte man nicht länger als 5-10 Minuten dafür benötigen, wenn man sich ein bisschen mit Excel auskennt.
Gruß Daniel
Anzeige
Es wäre nett von dir gewesen Julius,
03.04.2020 19:52:25
dir
wenn du ein paar mehr Worte zu meinem Makro zu sagen hättest, ins besondere zur Laufzeit.
Wenn ich mir schon die Mühe mache, Dir einen Code zu schreiben, dann könntest du auch kurz darüber berichten.
Zumal ich davon ausgegangen bin, dass mein Code etwas schneller ist als 60 Minuten.
60 Sekunden sind für diese Aufgabenstellung schon viel.
auch ohne Makro sollte man nicht länger als 5-10 Minuten dafür benötigen, wenn man sich ein bisschen mit Excel auskennt.
Gruß Daniel
Anzeige
;
Anzeige

Infobox / Tutorial

Langsames Makro beschleunigen


Schritt-für-Schritt-Anleitung

Um dein langsames Makro zu beschleunigen, kannst du folgende Schritte ausführen:

  1. Deaktiviere Bildschirmaktualisierungen: Setze Application.ScreenUpdating = False, um die Bildschirmaktualisierung zu deaktivieren. Dies verringert die Zeit, die für das Zeichnen der Benutzeroberfläche benötigt wird.

  2. Ändere die Berechnungsmethode: Verwende Application.Calculation = xlCalculationManual, um die automatische Berechnung während der Makroausführung zu deaktivieren. Vergiss nicht, sie am Ende wieder auf xlCalculationAutomatic zu setzen.

  3. Vermeide Select und Activate: Nutze direkt die Objekte, anstatt sie auszuwählen. Beispiel:

    Rows(zeile).Copy
    Rows(zeile).Insert Shift:=xlDown

    Stattdessen direkt:

    Rows(zeile).Copy Destination:=Rows(zeile + 1)
  4. Nutze Arrays: Wenn du viele Daten verarbeiten musst, ist es oft schneller, die Daten in ein Array zu laden, alle notwendigen Änderungen vorzunehmen und dann das gesamte Array zurück in das Excel-Blatt zu schreiben.

  5. Verwende Range-Objekte: Arbeite mit Range-Objekten, um die Leistung zu verbessern.


Häufige Fehler und Lösungen

  • Fehler: Das Makro bleibt bei einer Zeile hängen.

    • Lösung: Überprüfe die Abbruchbedingungen in deiner Schleife. Stelle sicher, dass das Makro die Schleifenbedingungen korrekt bewertet.
  • Fehler: Langsame Ausführung trotz Optimierungen.

    • Lösung: Stelle sicher, dass du die Bildschirmaktualisierung und Berechnung korrekt aktiviert/deaktiviert hast.
  • Fehler: Select-Befehle in Schleifen.

    • Lösung: Ersetze alle Select-Befehle durch direkte Referenzierung.

Alternative Methoden

  • Hilfsspalten verwenden: Schreibe die Zeilennummern in eine Hilfsspalte, sortiere die Daten nach den Kriterien und führe die Einfügungen durch. Dies kann die Leistung erheblich verbessern.

  • VBA Arrays nutzen: Lade die Daten in ein Array, bearbeite diese und schreibe sie dann auf einmal zurück ins Blatt. Dies reduziert die Anzahl der Schreibvorgänge und beschleunigt den Prozess.


Praktische Beispiele

Hier ist ein optimierter VBA-Code, der zeigt, wie du eine Hilfsspalte nutzen kannst, um die Ausführung zu beschleunigen:

Sub OptimiertesMakro()
    Dim zeile As Long
    Dim rng As Range

    ' Bildschirmaktualisierung deaktivieren
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual

    ' Hilfsspalte zur Identifizierung nutzen
    With ActiveSheet
        Set rng = .UsedRange
        rng.Columns(1).Insert Shift:=xlToRight ' Hilfsspalte hinzufügen
        .Cells(1, 1).Value = "Index" ' Titel für Hilfsspalte
        For zeile = 2 To rng.Rows.Count
            If .Cells(zeile, 2).Value = "Arbeit" Then ' Bedingung anpassen
                .Cells(zeile, 1).Value = zeile ' Zeilennummer speichern
            End If
        Next zeile
        ' Weitere Logik hier...
    End With

    ' Bildschirmaktualisierung aktivieren
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
End Sub

Tipps für Profis

  • Profiling: Nutze das VBA-Profiling, um herauszufinden, welche Teile deines Codes die meiste Zeit in Anspruch nehmen und optimiere gezielt diese Bereiche.

  • Schnelle Sortierung: Verwende die native Excel-Sortierung, um Daten effizient zu sortieren, bevor du sie bearbeitest.

  • Fehlerbehandlung: Implementiere eine angemessene Fehlerbehandlung, um sicherzustellen, dass dein Makro auch bei unerwarteten Daten nicht abstürzt.


FAQ: Häufige Fragen

1. Wie kann ich mein Excel-Makro beschleunigen? Indem du Bildschirmaktualisierungen und automatische Berechnungen während der Laufzeit deaktivierst und auf die Verwendung von Select-Befehlen verzichtest.

2. Was sind die Vorteile der Verwendung von Arrays in VBA? Arrays ermöglichen es dir, Daten im Speicher zu manipulieren, was in der Regel schneller ist als das direkte Arbeiten mit Excel-Blättern.

3. Warum ist mein Makro trotz Optimierungen immer noch langsam? Überprüfe die Logik deiner Schleifen und ob du alle empfohlenen Optimierungen wie das Arbeiten mit Range-Objekten und das Vermeiden von Select-Befehlen umgesetzt hast.

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Entdecke mehr
Finde genau, was du suchst

Die erweiterte Suchfunktion hilft dir, gezielt die besten Antworten zu finden

Suche nach den besten Antworten
Unsere beliebtesten Threads

Entdecke unsere meistgeklickten Beiträge in der Google Suche

Top 100 Threads jetzt ansehen
Anzeige