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

Langsames Makro

Langsames Makro
20.06.2020 13:59:58
Marc
Hi Community
Ich habe ein Makro geschrieben um Teile von Daten von einer Basis-Liste in eine andere zu kopieren. Es ist nicht gerade hochstehend, aber es funktioniert einwandfrei. Das Problem ist nur, es ist ungeheuer langsam, mir schläft fast das Gesicht ein. Ich habe schon im Format xlsb gespeichert, weil ich mal gelesen habe, so würde das Excel schneller arbeiten, immer noch katastophal. Ist irgend etwas mit meinen Schleifen verkehrt?
Ich danke euch für euer Feedback, geniesst den Tag.
Grüess
Marc
Sub Projekte_mit_Meilensteinen()
' mal ein erster Gehversuch mit den Meilensteinen
' zuerst lösche ich mal die Werte in den Spalten A bis F im Blatt1. Aufräumen bevor ich  _
kopiere.
Sheets("Liste").Activate
zeilen = Cells(Rows.Count, 1).End(xlUp).Row
Sheets("Meilensteine").Activate
ActiveSheet.Range("A4:F199").Select
Selection.ClearContents
Dim z As Integer
z = 2
zz = 4
Do Until z = zeilen
Worksheets("Liste").Cells(z, 1).Copy Cells(zz, 1) ' Cells(Zeilen, Spalten)
Worksheets("Liste").Cells(z, 4).Copy Cells(zz, 2)
Worksheets("Liste").Cells(z, 7).Copy Cells(zz, 3)
Worksheets("Liste").Cells(z, 8).Copy Cells(zz, 4)
Worksheets("Liste").Cells(z, 11).Copy Cells(zz, 5)
Worksheets("Liste").Cells(z, 12).Copy Cells(zz, 6)
Worksheets("Liste").Cells(z, 13).Copy Cells(zz + 1, 5)
Worksheets("Liste").Cells(z, 14).Copy Cells(zz + 1, 6)
Worksheets("Liste").Cells(z, 15).Copy Cells(zz + 2, 5)
Worksheets("Liste").Cells(z, 16).Copy Cells(zz + 2, 6)
z = z + 1
zz = zz + 3
Loop
End Sub

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

Betreff
Datum
Anwender
Anzeige
AW: Langsames Makro
20.06.2020 14:31:01
Daniel
Hi
Jede Veränderung in einer Zelle löst eine Reihe von Hintergrundaktivitäten in Excel aus, was natürlich Zeit kostet.
Einen Teil dieser Hintergrundaktivitäten kann man ausschalten, um den Vorgang zu beschleunigen. Such mal im WWW nach GetMoreSpeed, da solltest du einiges dazu finden.
Der andere Ansatz ist, dass man versucht mehrer Zellen möglichst als Block in einem Schritt zu bearbeiten und nicht jede Zelle einzeln. Dann kann Excel diese Hintergrundaktivitäten auch für alle Zellen gemeinsam ausführen. Im Prinzip so wie beim Bäcker, du kaufst ja auch nicht jedes Brötchen einzeln, sondern alle zusammen und musst nur 1x bezahlen und nicht 10x.
Bei deinem Blattaufbau ist das aber nicht so leicht, man könnte hier immer alle Zellen, die beim Einfügen direkt nebeneinander liegen, gemeinsam kopieren, also aus:
   Worksheets("Liste").Cells(z, 1).Copy Cells(zz, 1)
Worksheets("Liste").Cells(z, 4).Copy Cells(zz, 2)
Worksheets("Liste").Cells(z, 7).Copy Cells(zz, 3)
Worksheets("Liste").Cells(z, 8).Copy Cells(zz, 4)
Worksheets("Liste").Cells(z, 11).Copy Cells(zz, 5)
Worksheets("Liste").Cells(z, 12).Copy Cells(zz, 6)
Worksheets("Liste").Cells(z, 13).Copy Cells(zz + 1, 5)
Worksheets("Liste").Cells(z, 14).Copy Cells(zz + 1, 6)
Worksheets("Liste").Cells(z, 15).Copy Cells(zz + 2, 5)
Worksheets("Liste").Cells(z, 16).Copy Cells(zz + 2, 6)

wird:
with Sheets("Liste")
Intersect(.Rows(z), .Range("a:a,d:d,g:h,k:l").Copy Cells (zz, 1)
Intersect(.Rows(z), .Range("m:n").copy cells(zz + 1, 5)
Intersect(.Rows(z), .Range("o:p").copy cells(zz + 2, 5)
End With
Weiterhin kannst du dein Do-Loop hier besser durch ein For-Next ersetzen (für das z).
For-Next ist etwas schneller als Do-Loop, aber das dürfte hier nicht der ausschlaggebende Zeitbaustein sein.
Also aus
z = 2
Do Until z = zeilen
z = z + 1
Loop

Wird
For z = 2 to Zeilen - 1
Next
Gruß Daniel
Anzeige
For-Next schneller als Do-Loop?
20.06.2020 15:54:46
Zwenn
Hallo Daniel,
Du schreibst:
Weiterhin kannst du dein Do-Loop hier besser durch ein For-Next ersetzen (für das z).
For-Next ist etwas schneller als Do-Loop, aber das dürfte hier nicht der ausschlaggebende Zeitbaustein sein.

Das habe ich noch nie gehört. Hast Du dazu eine Quelle?
Das Laufzeitverhalten wird ja üblicherweise mit der O-Notation abgeschätzt. Da spielt die Schleifenform aber keine Rolle. Dass Groß-O in Excel nicht so richtig funktioniert, hast Du mit dem Hinweis auf "Hintergrundarbeiten" ja quasi schon erklärt und das ist auch völlig klar. Aber das verschiedene Schleifentypen unterschiedliche Geschwindigkeiten haben, erschließt sich mir nicht.
Viele Grüße,
Zwenn
Anzeige
AW: For-Next schneller als Do-Loop?
20.06.2020 17:15:19
Daniel
Hi
Kannst du mir vorher noch kurz erklären, was "O-Notation" und "Groß-O" bedeutet?
Gruß Daniel
AW: For-Next schneller als Do-Loop?
20.06.2020 19:14:47
Zwenn
Hallo Daniel,
sorry, ich hatte das einfach als bekannt vorausgesetzt.
Es gibt die Klein-o und Groß-O Notation. Mit O-Notation und Groß-O meine ich das gleiche. Etwas unsauber, ich weiß. Mann nennt es auch Landau Symbolik. Mit Groß-O wird eine Aussage über die Geschwindigkeit des Wachstums einer Funktion getätigt. Dabei werden im Grunde nur die größten Einflussfaktoren herangezogen, womit es eine Vereinfachung ist, die aber in der Praxis völlig ausreicht.
Man kann diese Notation auch auf das Laufzeitverhalten von Algorithmen anwenden. Ich kenne das unter anderem vom Klassiker der Vergleiche zwischen Sortieralgorithmen. Man kann damit herleiten, warum Quick- und Merge-Sort wesentlich schneller sind als ein Bubble-Sort.
Hier ist ein Video aus meinem Lieblingskanal für theoretische Informatik, der das Thema erklärt:
https://www.youtube.com/watch?v=LVP3jXQR_0M
Hier ist ein Video, dass die Anwendung auf die Programmierung zeigt:
https://www.youtube.com/watch?v=sVDHsLBD2hs
Daher meine Frage zum unterschiedlichen Laufzeitverhalten unterschiedlicher Schleifentypen. Ich habe noch nie gehört, dass es da in der Praxis relevante Unterschiede gibt.
Viele Grüße,
Zwenn
Anzeige
AW: For-Next schneller als Do-Loop?
20.06.2020 19:36:55
Daniel
Ich versteht zwar immer noch nicht was du meinst, aber seis drum.
Quelle: Eigener Versuch.
Grund für die Vermutung:
Im For-Next wird die Abbruchbedingung zu Beginn der Schleife festgelegt und ist nachträglich nicht mehr änderbar.
Im Do-Loop muss die Abbruchbedingung jedesmal neu ermittelt werden.
Außerdem muss im Do-Loop die Veränderung des Abbruchparameters explizit als eigener Programmschritt im Quellcode programmiert, übersetzt und ausgeführt werden, beim For-Next läuft das intern mit.
Somit ist der Aufwand im Do-Loop höher.
Und ja, der Geschwindigkeitsunterschied ist zwar da, aber in der Regel nicht praxisrelvant, das hatte ich aber geschrieben.
For-Next ist halt einfacher zu programmieren und Do-Loop wird nur dort verwenden, wo seine grössere Flexibilität benötigt wird.
Gruß Daniel
Anzeige
AW: ungeprüft
20.06.2020 14:41:56
Fennek
Hallo,
der Code kann Tippfehler enthalten, oder die Indices sind verrutscht:

sub T_1()
dim MS as worksheet, LL as Worksheet
dim Ar
set MS = sheets("Meilensteine")
set LL = sheets("Liste")
MS.Range("A4:F199").clearcontent
rnd = LL.Range("A4:P" & ll.cells(rows.count, 1).end(xlup).row)
ReDim Ar(ubound(rnd),6)
for i = LBound(rnd) to UBound(rnd) step 3
Ar(i, 1) = rnd(i, 1)
Ar(i, 4) = rnd(i, 2)
Ar(i, 7) = rnd(i, 3)
Ar(i, 8) = rnd(i, 4)
Ar(i, 11) = rnd(i, 5)
Ar(i, 12) = rnd(i, 6)
Ar(i, 13) = rnd(i+1, 5)
Ar(i, 14) = rnd(i+1, 6)
Ar(i, 15) = rnd(i+2, 5)
Ar(i, 16) = rnd(i+2, 6)
next i
ll.Range("A4").resize(ubound(Ar),6) = Ar
end sub
mfg
Anzeige
AW: ungeprüft
20.06.2020 15:06:48
Daniel
Da hast du aber Quelle und Ziel des kopiervorgangs vertauscht.
Gruß Daniel
AW: ungeprüft
20.06.2020 15:14:17
Marc
Super, herzlichen Dank. Ich werde morgen beide Lösungen mal ausprobieren. Ich bin sicher, mein Bastel-Makro wird dadurch einiges schneller.
Mit einem herzlichen Dankeschön und sonnigen Grüssen
Marc
AW: ungeprüft
20.06.2020 15:14:37
Marc
Super, herzlichen Dank. Ich werde morgen beide Lösungen mal ausprobieren. Ich bin sicher, mein Bastel-Makro wird dadurch einiges schneller.
Mit einem herzlichen Dankeschön und sonnigen Grüssen
Marc
AW: Nachfrage
20.06.2020 15:39:03
GerdL
Moin Marc,
willst du die Zellen kopieren oder nur deren Werte übertragen?
Gruß Gerd
AW: Nachfrage
22.06.2020 16:41:04
Marc
Hallo Gerd
Ich möchte die Zellen kopieren. Einen Vorschlag - der von Daniel - funktioniert leider nicht. Mit der For Next Schlaufe scheint es ein bisschen schneller geworden zu sein. Jetzt muss ich noch die Variante von Tino ausprobieren :)
Grüessli
Marc
Anzeige
AW: Nachfrage
25.06.2020 16:43:31
Gerd
Moin Marc!
Daniels Vorschlag geht doch!
Sub Projekte_mit_Meilensteinen()
Dim L As Worksheet, M As Worksheet, zz As Long, z As Long
Set L = Sheets("Liste")
Set M = Sheets("Meilensteine")
M.Range("A4:F199").ClearContents
zz = 4
For z = 2 To L.Cells(L.Rows.Count, 1).End(xlUp).Row
Union(L.Cells(z, 1), L.Cells(z, 4), L.Cells(z, 7), L.Cells(z, 8), _
L.Cells(z, 11), L.Cells(z, 12)).Copy M.Cells(zz, 1)
L.Range(L.Cells(z, 13), L.Cells(z, 14)).Copy M.Cells(zz + 1, 5)
L.Range(L.Cells(z, 15), L.Cells(z, 16)).Copy M.Cells(zz + 2, 5)
zz = zz + 3
Next
End Sub
Gruß Gerd
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige