Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1412to1416
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

VBA Code sehr langsam - Optimierungen?

VBA Code sehr langsam - Optimierungen?
06.03.2015 09:34:55
hennerich
Hallo Forum,
in meiner Excel Tabelle werden Soll Stunden und Ist Stunden verglichen. Dazu gibt es verschiedene Projekte mit jeweils einzelnen Vorgängen.
Ein Beispiel:
Projekt: Garten
Vorgang: Pflanzen, Design, Planung
Projekt: Haus
Vorgang: Planung, Aufbau, Qualitätskontrolle
Die Soll Werte befinden sich in einem separaten Tabellenblatt Soll in einer formatierten Tabelle tblSoll.
Die Ist Werte befinden sich in einem anderen Tabellenblatt Ist in einer formatierten Tabelle tblIst.
Pro Monat werden dort die erfassten Ist Werte eingetragen, um sie dann mittels einer Pivot-Tabelle grafisch aufzubereiten.
Nun gibt es ein Problem, welches ich lösen möchte. Mangels der Möglichkeit zwei Pivot-Tabellen als Basis für ein Diagramm zu nutzen habe ich in meiner Ist-Tabelle bereits Spalten für die Berechnung der Differenzen Soll-Ist eingefügt. So schaffe ich eine einzige Datenbasis. Das funktioniert bisher ganz gut.
Bis auf die Tatsache, dass es passieren kann, dass in einem Monat keine Ist Werte für einen bestimmten Vorgang erfasst werden. Daraus folgt, dass in der Privot-Tabelle aufgrund des Vergleiches Soll-Ist auch kein Wert für diesen Vorgang auftaucht und damit mein Diagramm verfälscht wird (ich habe Stunden geplant, diese werden aber nicht angezeigt).
Um dieses Problem zu lösen, wollte ich über einen Workaround (was Besseres ist mir nicht eingefallen) Dummy-Stunden als Ist Werte per VBA einfügen. Das kann schon mal viel werden, denn pro Projekt (ca. 5-20 an der Zahl) und pro Vorgang im Projekt (ca. 4) muss ich für jeden Monat eine Dummy-Zeile einfügen. Damit komme ich schnell auf bis zu 1.000 Zeilen.
Das Makro ist auch soweit fertig und funktioniert, jedoch extrem langsam.
Habt ihr eine Idee, wie ich es schneller bekommen kann?
Sub InsertStandard()
Dim iAnzahl As Integer, iZeile As Integer, iEnde As Integer, iMonat As Integer
Application.ScreenUpdating = False
'** bestimmen der Anzahl der benutzten Zeilen in der Soll-Tabelle
iZeile = ThisWorkbook.Sheets("Soll").Range("A65536").End(xlUp).Rows.Row - 1
With ThisWorkbook.Sheets("Ist")
'** bestimmen der Anzahl der benutzen Zeilen in der Ist-Tabelle
iEnde = .UsedRange.SpecialCells(xlCellTypeLastCell).Row - 1
For iAnzahl = 1 To iZeile
For iMonat = 1 To 12
'** neue Zeile einfügen
.Cells(iEnde + iMonat, 1).EntireRow.Insert
'** Projektname einfügen
.Cells(iEnde + iMonat, 6).Value = Sheets("Soll").Cells(iAnzahl + 1, 1).Value
'** Datum einsetzen
.Cells(iEnde + iMonat, 11).Value = DateSerial(Sheets("Dashboard").Range("Dat").Value,  _
iMonat, 1)
'** Dummy Wert für Stunden einsetzen
.Cells(iEnde + iMonat, 12).Value = "0,01"
'** Stundenwert in Zahlenformat umwandeln
.Cells(iEnde + iMonat, 12).NumberFormat = "General"
'** Vorgang einfügen
.Cells(iEnde + iMonat, 18).Value = Sheets("Soll").Cells(iAnzahl + 1, 2).Value
Next iMonat
iEnde = .UsedRange.SpecialCells(xlCellTypeLastCell).Row - 1
Next iAnzahl
End With
Application.ScreenUpdating = True
End Sub
Danke und Grüße
Henri

6
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: VBA Code sehr langsam - Optimierungen?
06.03.2015 09:41:12
Rudi
Hallo,
schalte die üblichen Bremsen aus.
Recherche: Getmorespeed
Gruß
Rudi

AW: VBA Code sehr langsam - Optimierungen?
06.03.2015 09:58:23
hennerich
Hallo Rudi,
wow, erstmal danke für deine schnelle Antwort. Und das zweite Danke kommt für deinen Tipp, mit dem Makro bin ich mal eben von (gefühlt) einer Minute Durchlaufzeit auf 5sek runter :)
*daumenhoch*
Grüße und schönes Wochenende
Henri

AW: VBA Code sehr langsam - Optimierungen?
06.03.2015 10:22:34
Daniel
Hi
das Einfügen von Zeilen und das beschreiben von Excelzellen ist sehr langsam.
eine möglichkeit, das ganze zu beschleunigen wäre folgende:
1. befülle die Zellen nicht direkt, sondern schreibe die Daten zunächst in ein zweidimensionales Array.
2. füge dann die benögitgen Leerzeilen auf einmal ein (das dauert genausolange wie das einfügen einer Zeile)
3. schreibe dann die Arrayinhalte als Block in die freien Zellen.
Auch das ist für Excel ein Einfügevorgang (unabängig von der Anzahl der eingefügten Werte)
ausserdem sollte man Zellwerte, die man immer wieder auslisest und die sich nicht ändern, in eine Variable schreiben, weil auch beim Lesen der Zugriff auf Variablen schneller ist als auf Excelzellen:

Sub InsertStandard()
Dim iAnzahl As Integer, iZeile As Integer, iEnde As Integer, iMonat As Integer
Dim arr
Dim Jahr As Long
Application.ScreenUpdating = False
'** bestimmen der Anzahl der benutzten Zeilen in der Soll-Tabelle
iZeile = ThisWorkbook.Sheets("Soll").Range("A65536").End(xlUp).Rows.Row - 1
With ThisWorkbook.Sheets("Ist")
'** bestimmen der Anzahl der benutzen Zeilen in der Ist-Tabelle
iEnde = .UsedRange.SpecialCells(xlCellTypeLastCell).Row - 1
Jahr = Sheets("Dashboard").Range("Dat").Value
ReDim arr(1 To iZeile * 12, 1 To 18)
For iAnzahl = 0 To iZeile - 1
For iMonat = 1 To 12
'** neue Zeile einfügen
'** Projektname einfügen
arr(iAnzahl * 12 + iMonat, 6) = Sheets("Soll").Cells(iAnzahl + 1, 1).Value
'** Datum einsetzen
arr(iAnzahl * 12 + iMonat, 11) = DateSerial(Jahr, iMonat, 1)
'** Dummy Wert für Stunden einsetzen
arr(iAnzahl * 12 + iMonat, 12) = "0,01"
'** Stundenwert in Zahlenformat umwandeln
'** Vorgang einfügen
arr(iAnzahl * 12 + iMonat, 18) = Sheets("Soll").Cells(iAnzahl + 1, 2).Value
Next iMonat
Next iAnzahl
'** Daten zurückschreiben
.Rows(iEnde + 1).Resize(UBound(arr, 1)).Insert
.Cells(iEnde, 1).Resize(UBound(arr, 1), UBound(arr, 2)).Value = arr
End With
Application.ScreenUpdating = True
End Sub
weiter Optimierungen sind sicherlich möglich (so könnte man auch die Werte aus derm Sheet Soll noch in ein Array lesen und auf dieses zugreifen).
Gruß Daniel

Anzeige
AW: VBA Code sehr langsam - Optimierungen?
06.03.2015 21:14:53
hennerich
Hallo Daniel,
vielen Dank für den weiteren Tipp. Habe das eben versucht, bekomme aber beim Ausführen von:
arr(iAnzahl * 12 + iMonat, 6) = Sheets("Soll").Cells(iAnzahl + 1, 1).Value
den Fehler:
Index außerhalb des gültigen Bereichs.
Woran kann das liegen?
Grüße
Henri

AW: VBA Code sehr langsam - Optimierungen?
06.03.2015 22:17:56
Daniel
die Fehlermeldung kommt, wenn du bei einem Array (hier arr) als Index einen Wert angibst, der ausserhalb der Grenzen liegt, die du bei der Dimensionierung angegeben hast, oder wenn du bei Sheets("...") einen falschen, nicht vorhandenen Tabellenblattnamen verwendest.
also check mal deine Variablen (auch mal ausmultiplizieren) und den Tabellenblattnamen.
Gruß Daniel

Anzeige
AW: VBA Code sehr langsam - Optimierungen?
12.03.2015 11:23:17
hennerich
Hallo Daniel,
ok, ich habe verstanden, dass
ReDim arr(1 To iZeile * 12, 1 To 18)
irgendwie davon ausgeht, dass Inhalte als Zahlen da sein müssen. Ich brauch aber auch Strings.
Anhand meiner Kommentare im Code kann man die Typen der einzelnen Zellen ableiten:
'** Projektname einfügen
arr(iAnzahl * 12 + iMonat, 6) = Sheets("Soll").Cells(iAnzahl + 1, 1).Value
'** Datum einsetzen
arr(iAnzahl * 12 + iMonat, 11) = DateSerial(iJahr, iMonat, 1)
'** Dummy Wert für Stunden einsetzen
arr(iAnzahl * 12 + iMonat, 12) = "0,01"
'** Vorgang einfügen
arr(iAnzahl * 12 + iMonat, 18) = Sheets("Soll").Cells(iAnzahl + 1, 2).Value
Kannst du mir bitte nochmal helfen?
Danke
Henri
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige