Live-Forum - Die aktuellen Beiträge
Datum
Titel
24.04.2024 19:29:30
24.04.2024 18:49:56
Anzeige
Archiv - Navigation
304to308
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
304to308
304to308
Aktuelles Verzeichnis
Verzeichnis Index
Verzeichnis Index
Übersicht Verzeichnisse
Inhaltsverzeichnis

VBA mit Datenfelder

VBA mit Datenfelder
08.09.2003 17:50:37
Christoph
Hallo bestes Forum,
Durch das Archiv bin ich darauf gestoßen, dass Berechnungen in VBA mit Arrays in der Regel viel schneller sind als mit der herkömmlichen Methode über Zellwerte.
Bei einer Gegenüberstellung dieser Methoden (siehe z.B. Archiv: https://www.herber.de/forum/archiv/12to16/t12635.htm) wurde behauptet, dass die Berechnung von z.B. 30000 Werten mit Array doppelt so schnell ist. (Laufzeit wird im Makro verarbeitet und anschließend ausgegeben)
Ich habe mir eine Tabelle wie im oben angegebenen Thread nachgebaut, und habe festgestellt, dass die Berechnungszeit der Werte bei der Array-Methode etwas kürzer ist. Es kommt allerdings noch die Zeit hinzu, um die Daten in den Array einzulesen.(ergo ist die Array-Methode sogar langsamer)
Mit Datenfeldern in VBA hab ich so gut wie gar keine Ahnung.
Mein Frage: läßt sich die Beispiel-Aufgabe: "Wert aus Zeile A plus Wert aus Zeile B minus Wert aus Zeile C" unter VBA mit Arrays anders formulieren, so dass die Bearbeitungszeit wirklich verkürzt wird?

hier der Link zu meiner nachgebauten Tabelle:
https://www.herber.de/bbs/user/936.xls

und der Code:


Sub berechnung_mit_Array()
Dim arr1() As Long
Dim ZeilenAnz As Long, m As Long, i As Long
Dim n As Integer
Dim t1 As Double, t2 As Double
ZeilenAnz = 30000
t1 = Now
Application.ScreenUpdating = False
'Einlesen der Daten:
ReDim Preserve arr1(ZeilenAnz, 3)
For m = 3 To ZeilenAnz
For n = 1 To 3
arr1(m, n) = Cells(m, n).Value
Next n
Next m
'Berechnen:
t2 = Now
For i = 3 To ZeilenAnz
Cells(i, 5) = arr1(i, 1) + arr1(i, 2) - arr1(i, 3)
Next i
Application.ScreenUpdating = True
Cells(4, 8) = t2 - t1       'Zeit, um Daten einzulesen
Cells(5, 8) = Now - t2      'Berechnungszeit
Cells(6, 8) = Now - t1      'Gesamtzeit
End Sub


vielen Dank für eure Hilfe
Gruß
Christoph

8
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: VBA mit Datenfelder
08.09.2003 18:09:26
ChrisL
Hi Christoph

Versuchs mal hiermit...


Sub berechnung_mit_Array()
Dim ZeilenAnz As Long, i As Long
Dim t1 As Double
t1 = Now
'Einlesen des Ergebnisses in den Array:
ReDim Arr(Range("N6") - 3) As Variant
For i = 3 To Range("N6")
Arr(i - 3) = Cells(i, 1) + Cells(i, 2) - Cells(i, 3)
Next i
'In Tabelle eintragen
Range("C3:C" & Range("N6")) = Arr
Cells(6, 8) = Now - t1      'Gesamtzeit
End Sub


Das Ergebnis schaut ein bischen anders aus. Ich habe den Hinweis, dass Berechnungen in Arrays schneller sind auch schon mehrfach gelesen, aber die Mühe es zu überprüfen habe ich mir bisher noch nie gemacht ;-)

Jedenfalls denke ich, dass die Zeitersparnis vorallem im Eintragen in die Tabelle liegt. Dass du in deinem Beispiel die zur Berechnung nötigen Daten erst auch ins Array einliest ist m.E. nicht nötig/sinnvoll. Hingegen alle Ergebnisse ins Array einlesen und dann alle auf einmal in die Tabelle zu schreiben ist m.E. die Zeitersparnis.

Gruss
Chris
Anzeige
Danke,aber....
08.09.2003 18:26:50
Christoph
Hi Chris,
Danke für deine Hilfe. Es gibt allerdings einen Schönheitsfehler in deinem Code.
Es wird nur die Zelle E3 richtig berechnet. Alle weiteren Einträge in der Spalte E
sind die selben wie in E3.

Woran liegt das?
Gruß
Christoph
PS: die Ergebnisse von A+B-C werden in der Spalte E dargestellt, daher habe ich deinen Code korrigiert:
Range("E3:E" & Range("N6")) = arr
wer kann es beweisen? ;-)
08.09.2003 20:09:27
ChrisL
Hallo Christoph

Das kommt davon, wenn man sich nicht die Mühe macht, auch tatsächlich Werte einzutragen. Deshalb war das Ergebnis sowieso überall Null und ich habs nicht gemerkt ;-)

Jedenfalls ist das Array horizontal, da aber nur 256 Spalten, musst du es noch transponieren, was aber in meinem Test nur bis ca. 5000 Zeilen funktioniert hat.


Sub berechnung_mit_Array()
Dim ZeilenAnz As Long, i As Long
Dim t1 As Double
t1 = Now
'Einlesen des Ergebnisses in den Array:
ReDim arr(Range("N6") - 3) As Variant
For i = 3 To Range("N6")
arr(i - 3) = Cells(i, 1) + Cells(i, 2) - Cells(i, 3)
Next i
'In Tabelle eintragen
Range("E3:E" & Range("N6")) = Application.WorksheetFunction.Transpose(arr)
Cells(6, 8) = Now - t1      'Gesamtzeit
End Sub


Und dann das Ergebnis, welche Enttäuschung, war sowohl mit als auch ohne Array genau das selbe :-(

Also vielleicht ist das Berechnungsbeispiel auch nicht besonders geeignet, allerdings fällt mir auch kein besseres Beispiel ein :-)

Nichts für Ungut und noch einen schönen Abend

Chris
Anzeige
AW: wer kann es beweisen? ;-)
08.09.2003 20:41:16
Christoph
Hallo Chris,
du hast recht, man muss es transponieren.
Aber warum funktioniert das nur bis 5000?
kann man das Array nicht gleich in zwei Dimensionen erzeugen und dann nur die 2. Dimension berücksichtigen?
Wie gesagt, ich hab so gut wie keine Ahnung von Arrays, will aber genau durch solche Probleme schlauer werden.
Noch was zur Bearbeitungszeit: wenn du in meiner Bsp-Tabelle die Zahlen vor jeder Berechnung (mit Array oder ohne) neu erstellst, dann sind sie Zeitunterschiede nicht unerheblich. (Array ist doppelt bis dreimal so schnell)

bleibt nur noch das Problem mit der Dimension bzw. Anzahl5000 zu lösen.
Wenn du noch Lust hast...vielleicht fällt dir ja noch was ein.
Ich bedanke mich auf jeden Fall für deine Hilfe
Gruß
Christoph
Anzeige
AW: wer kann es beweisen? ;-)
08.09.2003 20:48:25
PeterW
Hallo Chris,

jetzt versteh ich nix mehr. Das Array wird nicht mehr deklarierst und statt es zu transponieren könnte man doch gleich ein zweidimensionales anlegen und dieses in den Zielbereich schreiben.

Gruß
Peter
@Peter: hat du 'ne Lösung?
08.09.2003 21:31:17
Christoph
Hi Peter,
sowas ähnliches hab ich mir auch gedacht, aber wie in meiner letzten Antwort an Chris geschrieben...der Erfolg gib ihm Recht, das Teil ist schneller als vorher.
Eben mit der Einschränkung, dass es nur bis zur Zeile 5463 läuft.
Frage: hast du 'ne saubere Lösung?
schon mal vielen Dank
Christoph
Lösung gefunden - Danke an alle
08.09.2003 21:59:27
Christoph
Hallo Chris, hallo Peter,
von Chris kam der wichtige Hinweis, dass die Daten eingelesen und komplett ausgegebne werden....und der Code:
arr(i - 3, 0) = Cells(i, 1) + Cells(i, 2) - Cells(i, 3)
statt wie ursprünglich: Cells(i, 5) = arr1(i, 1) + arr1(i, 2) - arr1(i, 3)
von Peter der wichtige Hinweis mit den Dimensionen.
noch ein bischen "drauf rumgedacht" und ausprobiert und siehe da:
Der untenstehende Code bringt die Lösung.
Ergebnis: bei großen Zahlen (10000 bis 50000) ist das Array 4-5 mal schneller.

Ich hab euch zu danken, ich hab was gelernt,
Gruß
Christoph


Sub berechnung_mit_Array()
Dim ZeilenAnz As Long, i As Long
Dim t1 As Double
Dim arr() As Long
t1 = Now
'Einlesen des Ergebnisses in den Array:
ReDim Preserve arr(Range("N6") - 3, 0)
For i = 3 To Range("N6")
arr(i - 3, 0) = Cells(i, 1) + Cells(i, 2) - Cells(i, 3)
Next i
'In Tabelle eintragen
Range("E3:E" & Range("N6")) = arr
Cells(6, 8) = Now - t1      'Gesamtzeit
End Sub

Anzeige
AW: Lösung gefunden - Danke an alle
09.09.2003 11:06:38
ChrisL
Hi Christoph

Cool, jetzt habe ich auch noch was gelernt, beschäftige mich selber nämlich auch noch nicht so lange mit Arrays ;-)

Danke fürs Feedback und Gruss
Chris

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige