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

Forumthread: Makro sehr langsam, Speicher leeren möglich?

Makro sehr langsam, Speicher leeren möglich?
04.03.2009 13:02:43
uli
Hallo Experten,
ich habe ein enormes Geschwindigkeitsproblem bei einem Makro. In diesem wird eine Schleife rund 60.000 mal durchlaufen. Innerhalb der Schleife nochmals eine Schleife mit 12 Durchläufen.
Am Anfang ist das Makro noch befriedigend schnell. Nach ungefähr 10.000 Schleifendurchgängen allerdings sehr langsam.
Wenn ich nun den Code anhalte, speicher und die Arbeitsmappe schließe, danach wieder öffne und den Code an der Stelle weiterlaufen lasse, an der ich ihn vorher angehalten habe, gehts wieder sehr schnell los. Nach weiteren 10.000 Durchgängen allerdings wieder sehr langsam.
Daraus habe ich geschlossen, dass es sich (neben der vielleicht etwas bescheidenen Programmierung) um ein Speicherproblem handeln könnte.
Gibt es eine Möglichkeit den Speicher zwischendurch leeren zu lassen?
Ihr werdet mir jetzt wahrscheinlich raten die Anzahl der Schleifen zu reduzieren. Dies ist in meinen Augen allerdings nicht möglich, daher hoffe ich, dass ihr mir mit dem Speicheransatz weiterhelfen könnt.
Gruß
Uli
Anzeige

12
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Makro sehr langsam, Speicher leeren möglich?
04.03.2009 13:23:41
Renee
Hi Uli,
Solange wir nicht wissen, was dein Makro macht, können wir auch nicht deinen Speicher leeren ;-))
GreetZ Renée
AW: Makro sehr langsam, Speicher leeren möglich?
04.03.2009 14:01:43
uli
Hallo Renée,
hmmm, das ist ein wenig schwer zu erklären.
Die Tabelle enthält rund 60.000 Zeilen. Für jede Zeile sollen nun 12 Werte errechnet werden.
In Spalte 1 steht ein Name (String). dieser soll nun in 12 Monaten unterschiedlich verarbeitet werden. Daher eine Unterschleife mit n=12.
Ausgangspunkt sind nun 12 Strings, die in den Spalten 2-13 stehen. In Abhängigkeit des Monats wird ein String gewählt und eingelesen. Über eine select case Auswahl werden Werte, die in einem anderen Tabellenblatt diesem String zugeordnet sind in Variablen gespeichert (52 cases). Die Variablen werden mit einem Wert aus Spalte 13-25 (monatsabhängig) multipliziert und das Ergebnis in eine Zelle geschrieben.
Ich hoffe du kannst was damit anfangen.
Gruß
Uli
Anzeige
AW: Makro sehr langsam, Speicher leeren möglich?
04.03.2009 14:02:46
uli
Hallo Renée,
hmmm, das ist ein wenig schwer zu erklären.
Die Tabelle enthält rund 60.000 Zeilen. Für jede Zeile sollen nun 12 Werte errechnet werden.
In Spalte 1 steht ein Name (String). dieser soll nun in 12 Monaten unterschiedlich verarbeitet werden. Daher eine Unterschleife mit n=12.
Ausgangspunkt sind nun 12 Strings, die in den Spalten 2-13 stehen. In Abhängigkeit des Monats wird ein String gewählt und eingelesen. Über eine select case Auswahl werden Werte, die in einem anderen Tabellenblatt diesem String zugeordnet sind in Variablen gespeichert (52 cases). Die Variablen werden mit einem Wert aus Spalte 13-25 (monatsabhängig) multipliziert und das Ergebnis in eine Zelle geschrieben.
Ich hoffe du kannst was damit anfangen.
Gruß
Uli
Anzeige
AW: Makro sehr langsam, Speicher leeren möglich?
04.03.2009 14:03:54
uli
Hallo Renée,
hmmm, das ist ein wenig schwer zu erklären.
Die Tabelle enthält rund 60.000 Zeilen. Für jede Zeile sollen nun 12 Werte errechnet werden.
In Spalte 1 steht ein Name (String). dieser soll nun in 12 Monaten unterschiedlich verarbeitet werden. Daher eine Unterschleife mit n=12.
Ausgangspunkt sind nun 12 Strings, die in den Spalten 2-13 stehen. In Abhängigkeit des Monats wird ein String gewählt und eingelesen. Über eine select case Auswahl werden Werte, die in einem anderen Tabellenblatt diesem String zugeordnet sind in Variablen gespeichert (52 cases). Die Variablen werden mit einem Wert aus Spalte 13-25 (monatsabhängig) multipliziert und das Ergebnis in eine Zelle geschrieben.
Ich hoffe du kannst was damit anfangen.
Gruß
Uli
Anzeige
AW: Makro sehr langsam, Speicher leeren möglich?
04.03.2009 14:41:00
Renee
Hi Uli,
Damit kann ich nicht sehr viel anfangen, ausser das ich sehe das viele Berechnungen gemacht werden.
Aber werden z.B. auch Screenupdating, CalculationMode, Events etc. ausgeschalter, solange diese Berechnungen laufen? Hat es keine .Selects und .Activates im Code? etc....
Wirf mal dieses Makro in ein Modul:

Sub GetMoreSpeed(Optional ByVal Modus As Boolean = True)
Static intCalculation As Integer
If Modus = True Then intCalculation = Application.Calculation
With Application
.ScreenUpdating = Not Modus
.EnableEvents = Not Modus
.Calculation = IIf(Modus, xlManual, intCalculation)
.Cursor = IIf(Modus, 2, -4143)
End With
End Sub


Dann in DeinMakro:

Sub DeinMakro()
GetMoreSpeed True
' .... dein bestehender Code
GetMoreSpeed False
End Sub


GreetZ Renée
Anzeige
AW: Makro sehr langsam, Speicher leeren möglich?
04.03.2009 14:43:48
fcs
Hallo Uli,
warum postest du deine Problem-Prozedur nicht einfach hier mit deiner Frage; die Prozeduren klingen jedenfalls nicht so als ob da jede menge Know-how drin versteckt wäre.
Typische Bremsen sind Bildschirmaktualisierung, Berechnen und Ereignismakros, die während der Makroausführung stattfinden. Allerdings sollten diese nicht plötzlich bei ca. 10000 Schleifen bremsend wirken. Ähnlich bremsend wirken Select-Anweisungen im Code.
Bereinige ggf. deine Prozdur mit folgenden Anweisungen:

'zu Beginn der Prozedur
Application.ScrennUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
'.... hier dein Code
'am Ende
Application.ScrennUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True


Je nach zur verarbeitenden Datenmenge kann es auch sein, dass die Daten nicht mehr im Arbeitsspeicher verwaltet werden können, sondern temporär auf die Festplatte ausgelagert werden müssen. Da dein Tabellenblatt mit 60000 Zeilen ziemlich ausgereizt ist, könnte das der Fall sein.
Den Speicher leeren kann man eigenlich nicht, man kann aber durch "ungeschickte" Makroprogrammierung dafür sorgen, dass sich unnötig Datenmüll ansammelt.
Das Speichern und schließen der Datei führt allerdings dazu, dass bestimmte temporäre Informationen zurückgesetzt werden (z.B. Datenmüll aus VBA-Aktionen, das Rückgäng-Machen (dieses wird allerdings bei Makro-Aktionen eh nicht mit Daten gefüttert)).
Gruß
Franz

Anzeige
AW: Makro sehr langsam, Speicher leeren möglich?
04.03.2009 15:39:27
uli
Hallo Franz und Renée,
eure Tipps haben leider keinen bemerkbaren Geschwindigleitsvorteil nach Schleifedurchlauf 1X.XXX gebracht.
Hier mal das Problem:

Sub test()
Dim erlösm(1 To 12)
Dim schleifekd As Long
Dim anzahlkd As Long
Abplication.ScreenUpdating = False
anzahlkd = Abplication.WorksheetFunction.CountA(Sheets(1).Columns(1))
For schleifekd = 2 To anzahlkd
vj = Sheets(1).Cells(schleifekd, 18).Value
Lst = Sheets(1).Cells(schleifekd, 16).Value
For Monat = 1 To 12
tmon = Sheets(1).Cells(schleifekd, 22 + Monat).Text
vm = Sheets(1).Cells(schleifekd, 36 + Monat).Value
If tmon = "" Then
For schleife = Monat - 1 To 1 Step -1
tmon = Sheets(1).Cells(schleifekd, 22 + schleife).Text
If tmon  "" Then Exit For
Next schleife
End If
ab = 0
gb = 0
sp = 0
grenze = 0
a = 0
G = 0
Spe = 0
erlös = 0
Select Case tmon
Case "hallo1 ", "hallo2GSV510 "
ab = Sheets(6).Cells(4, Monat + 1).Value
gb = 0
sp = Sheets(6).Cells(4, 50).Value
Case "hallo3 ", "hallo4 ", "hallo5 "
ab = Sheets(6).Cells(6, Monat + 1).Value
gb = 0
sp = Sheets(6).Cells(6, 50).Value
Case "hallo6 ", "hallo7 ", "hallo8 ", "hallo9 "
ab = Sheets(6).Cells(9, Monat + 1).Value
gb = 0
sp = Sheets(6).Cells(9, 50).Value
Case "hallo11"
ab = Sheets(6).Cells(13, Monat + 1).Value
gb = 0
sp = Sheets(6).Cells(13, 50).Value
Case "hallo12 ", "hallo13 "
ab = Sheets(6).Cells(14, Monat + 1).Value
gb = 0
sp = Sheets(6).Cells(14, 50).Value
Case "hallo14 "
ab = Sheets(6).Cells(16, Monat + 1).Value
gb = 0
sp = 0
Case "hallo15 ", "hallo16", "hallo17", "hallo18", "hallo19"
ab = Sheets(6).Cells(17, Monat + 1).Value
gb = Sheets(6).Cells(17, Monat + 25).Value
sp = Sheets(6).Cells(17, 50).Value
grenze = 30
Case "hallo20 "
ab = Sheets(6).Cells(21, Monat + 1).Value
gb = Sheets(6).Cells(21, Monat + 25).Value
sp = 0
Case "hallo21 "
If vj  30 And grenze = 30 Then
Spe = (Lst – 30) * sp
Else
Spe = sp * Lst
End If
erlös = a + G + Spe
Sheets(1).Cells(schleifekd, 48 + Monat * 3).Value = erlös
erlösm(Monat) = erlös
Next Monat
erlösesum = Abplication.WorksheetFunction.Sum(erlösm)
Sheets(1).Cells(schleifekd, 87).Value = erlösesum
Next schleifekd
Abplication.ScreenUpdating = True
End Sub


Anzeige
AW: Makro sehr langsam, Speicher leeren möglich?
04.03.2009 15:39:36
uli
Hallo Franz und Renée,
eure Tipps haben leider keinen bemerkbaren Geschwindigleitsvorteil nach Schleifedurchlauf 1X.XXX gebracht.
Hier mal das Problem:

Sub test()
Dim erlösm(1 To 12)
Dim schleifekd As Long
Dim anzahlkd As Long
Abplication.ScreenUpdating = False
anzahlkd = Abplication.WorksheetFunction.CountA(Sheets(1).Columns(1))
For schleifekd = 2 To anzahlkd
vj = Sheets(1).Cells(schleifekd, 18).Value
Lst = Sheets(1).Cells(schleifekd, 16).Value
For Monat = 1 To 12
tmon = Sheets(1).Cells(schleifekd, 22 + Monat).Text
vm = Sheets(1).Cells(schleifekd, 36 + Monat).Value
If tmon = "" Then
For schleife = Monat - 1 To 1 Step -1
tmon = Sheets(1).Cells(schleifekd, 22 + schleife).Text
If tmon  "" Then Exit For
Next schleife
End If
ab = 0
gb = 0
sp = 0
grenze = 0
a = 0
G = 0
Spe = 0
erlös = 0
Select Case tmon
Case "hallo1 ", "hallo2GSV510 "
ab = Sheets(6).Cells(4, Monat + 1).Value
gb = 0
sp = Sheets(6).Cells(4, 50).Value
Case "hallo3 ", "hallo4 ", "hallo5 "
ab = Sheets(6).Cells(6, Monat + 1).Value
gb = 0
sp = Sheets(6).Cells(6, 50).Value
Case "hallo6 ", "hallo7 ", "hallo8 ", "hallo9 "
ab = Sheets(6).Cells(9, Monat + 1).Value
gb = 0
sp = Sheets(6).Cells(9, 50).Value
Case "hallo11"
ab = Sheets(6).Cells(13, Monat + 1).Value
gb = 0
sp = Sheets(6).Cells(13, 50).Value
Case "hallo12 ", "hallo13 "
ab = Sheets(6).Cells(14, Monat + 1).Value
gb = 0
sp = Sheets(6).Cells(14, 50).Value
Case "hallo14 "
ab = Sheets(6).Cells(16, Monat + 1).Value
gb = 0
sp = 0
Case "hallo15 ", "hallo16", "hallo17", "hallo18", "hallo19"
ab = Sheets(6).Cells(17, Monat + 1).Value
gb = Sheets(6).Cells(17, Monat + 25).Value
sp = Sheets(6).Cells(17, 50).Value
grenze = 30
Case "hallo20 "
ab = Sheets(6).Cells(21, Monat + 1).Value
gb = Sheets(6).Cells(21, Monat + 25).Value
sp = 0
Case "hallo21 "
If vj  30 And grenze = 30 Then
Spe = (Lst – 30) * sp
Else
Spe = sp * Lst
End If
erlös = a + G + Spe
Sheets(1).Cells(schleifekd, 48 + Monat * 3).Value = erlös
erlösm(Monat) = erlös
Next Monat
erlösesum = Abplication.WorksheetFunction.Sum(erlösm)
Sheets(1).Cells(schleifekd, 87).Value = erlösesum
Next schleifekd
Abplication.ScreenUpdating = True
End Sub


Anzeige
AW: Makro sehr langsam, Speicher leeren möglich?
04.03.2009 15:54:20
Renee
Hi Uli,
Da so wird aber die Berechnung bei jeder Zelländerung durchgeführt! Kein Wunder...
Hast du mal meinen Vorschlag mit der GetMoreSpeed Function probiert ?
und btw was zum Teufel ist Abplication.WorksheetFunction. ?
GreetZ Renée
AW: Makro sehr langsam, Speicher leeren möglich?
04.03.2009 16:03:11
uli
Hallo Renée,
hab gerade in word das Makro ein bisschen verfremdet und Variablennamen mit ap durch ab ersetzt, dabei ist dann abplication entstanden :)
GetMoreSpeed hab ich getestet. Ist allerdings nicht schneller. Allenfalls die ersten 5000-10000 Schleifendurchgänge sind vielleicht etwas schneller durchlaufen worden, darüber hinaus wieder schneckentempo.
Im ganzen Arbeitsblatt ist keine einzige Formel, daher hab ich die automatische Berechnung ist ausgeschaltet.
Anzeige
ok, dann keine Idee mehr, sorry! (owT)
04.03.2009 16:21:59
Renee

AW: dann mal was ganz abstruses
04.03.2009 20:32:25
Daniel
könntest du, wenn du Datentabelle im Sheet(6) entsprechend aufbaust, die Werte per FORMEL berechnen (das Auswählen der Daten könnte über den SVERWEIS funktionieren, mit dem Monat als Spaltenwert)?
und dann im Makro nur noch die Formeln in die Zellen schreiben und anschließend die Formeln durch Werte zu ersetzen?
das ist meiner Erfahrung nach bei grossen Datenmengen oft deutlich schneller als ein Schleifenmakro. (zumindest solange das Makro mit Cells und RANGE direkt arbeitet).
Gruß, Daniel
Anzeige
;
Anzeige
Anzeige

Infobox / Tutorial

Makrooptimierung und Speicherverwaltung in Excel


Schritt-für-Schritt-Anleitung

  1. Makro-Optimierung: Beginne damit, das ScreenUpdating, die Berechnungseinstellungen und die Ereignisse während der Makroausführung zu deaktivieren. Das kannst du mit folgender Funktion erreichen:

    Sub GetMoreSpeed(Optional ByVal Modus As Boolean = True)
       Static intCalculation As Integer
       If Modus = True Then intCalculation = Application.Calculation
       With Application
           .ScreenUpdating = Not Modus
           .EnableEvents = Not Modus
           .Calculation = IIf(Modus, xlManual, intCalculation)
           .Cursor = IIf(Modus, 2, -4143)
       End With
    End Sub
  2. In dein bestehendes Makro integrieren: Rufe die GetMoreSpeed-Funktion zu Beginn und am Ende deines Makros auf:

    Sub DeinMakro()
       GetMoreSpeed True
       ' .... dein bestehender Code
       GetMoreSpeed False
    End Sub
  3. Arbeitsspeicher leeren: Während der Ausführung deines Makros kannst du den Arbeitsspeicher nicht direkt leeren, aber du kannst sicherstellen, dass temporäre Daten nicht unnötig gespeichert werden. Dies kann durch die Vermeidung von .Select und .Activate erreicht werden.


Häufige Fehler und Lösungen

  • Problem: Excel wird plötzlich extrem langsam.

    • Lösung: Stelle sicher, dass du das automatische Berechnen von Formeln deaktiviert hast (Application.Calculation = xlCalculationManual).
  • Problem: Der Arbeitsspeicher wird voll.

    • Lösung: Überprüfe, ob du unnötige Daten in Variablen speicherst. Stelle sicher, dass du alle nicht mehr benötigten Variablen auf Nothing setzt.
  • Problem: Bildschirmaktualisierungen verursachen Verzögerungen.

    • Lösung: Schalte die Bildschirmaktualisierung zu Beginn deines Makros aus (Application.ScreenUpdating = False) und aktiviere sie am Ende wieder.

Alternative Methoden

  • Verwendung von Formeln: Anstatt alles in VBA zu berechnen, kannst du Excel-Formeln verwenden. Berechne die Werte in einer Tabelle und nutze dann dein Makro nur für die Verarbeitung der Ergebnisse. Dies kann oft schneller sein, insbesondere bei großen Datenmengen.

  • Datenbankansatz: Überlege, die Daten in einer Datenbank zu speichern und mit SQL-Abfragen zu arbeiten. Dies kann die Geschwindigkeit erheblich erhöhen und den Arbeitsspeicher entlasten.


Praktische Beispiele

Hier ist ein Beispiel für ein optimiertes Makro:

Sub OptimiertesMakro()
    Dim i As Long
    Dim anzahlkd As Long
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual

    anzahlkd = Application.WorksheetFunction.CountA(Sheets(1).Columns(1))

    For i = 2 To anzahlkd
        ' Berechnungen hier
    Next i

    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
End Sub

Tipps für Profis

  • Speicher leeren: Um den Arbeitsspeicher zu optimieren, kannst du den Cache leeren. Dies geschieht nicht direkt in VBA, aber durch regelmäßiges Speichern und Schließen der Datei.

  • Verwende Dim: Deklariere deine Variablen mit dem kleinsten nötigen Datentyp. Das spart Arbeitsspeicher und erhöht die Geschwindigkeit.

  • Ereignisse vermeiden: Überlege, ob du Application.EnableEvents = False setzen kannst, um zu verhindern, dass andere Makros während deiner Ausführung aktiv werden.


FAQ: Häufige Fragen

1. Wie kann ich den Excel Cache leeren? Um den Cache in Excel zu leeren, speichere die Datei und schließe sie, bevor du sie erneut öffnest. Dies hilft, temporäre Daten zu entfernen.

2. Was kann ich tun, wenn Excel plötzlich extrem langsam wird? Überprüfe, ob du große Datenmengen verarbeitest. Deaktiviere die Bildschirmaktualisierung und die automatische Berechnung, um die Leistung zu verbessern.

3. Gibt es eine Möglichkeit, den Arbeitsspeicher in VBA manuell zu leeren? Du kannst den Arbeitsspeicher nicht direkt leeren, aber du kannst durch das Schließen und Speichern von Dateien temporäre Daten entfernen. Achte darauf, dass du unnötige Variablen und Objekte auf Nothing setzt.

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