Anzeige
Archiv - Navigation
1056to1060
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

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

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

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige
Archiv - Verwandte Themen
Forumthread
Beiträge