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

Schleife / Code verschnellern?

Schleife / Code verschnellern?
10.05.2019 09:31:00
Tim
Hallo zusammen,
der folgende Code funktioniert einwandfrei. Er ist mir persöhnlich nur zu langsam.
Meine Frage: Gibt es eine Möglichkeit ihn zu beschleunigen?
Aufbau meiner Datei:
Ich habe in der Linken Spalte einen Pfad stehen der sich in jeder Zeile ändert, manuell angepasst wird.
Dieser Pfad wird über STRG + Shift aus einem Laufwerk kopiert. (ca. 30-40 Pfäde)
Die werden dann in den Dateipfad und den Dateinamen aufgesplittet.
in den Zeilen über den Überschriften gibt es die Zeile: Tabelle und Zeile
Diese Werte ändern sich in jeder Spalte.
Also im Grunde sucht sich das Makro über eine Schleife die Daten aus mehreren Geschlossenen Arbeitsmappe zusammen wobei ich die Bereiche variable in Excel angebe.
Die Bereiche die ich oben in den ersten Zellen angebe sind in jeder Arbeitsmappe gleich.
Code:

Sub Zelle_auslesen_lang()
'** Dimensionierung der Variablen
'Quelle https://www.excel-inside.de/vba-loesungen/datei/947-daten-aus-geschlossener- _
arbeitsmappe-auslesen
'abgeändert von Tim.Ertl
Dim pfad As String, datei As String, blatt As String, zelle As String, bezug As String
Dim i As Long
Dim r As Long
Dim a As Long
Call ClearCells_lang
r = Selection.Row
a = WorksheetFunction.CountA(Worksheets("Analyse").Range("1:1")) - 2
Worksheets("Analyse").Cells(r, 4).Select
For i = 0 To a
ActiveCell.Offset(0, 1).Range("A1").Select
'** Angaben zur auszulesenden Zelle
pfad = Worksheets("Analyse").Cells(r, 2).Value
datei = Worksheets("Analyse").Cells(r, 3).Value
blatt = Worksheets("Analyse").Cells(1, 5 + i).Value
bezug = Worksheets("Analyse").Cells(2, 5 + i).Value
If blatt = "leer" Then GoTo Sprung
'** Eintragen in Zelle
ActiveCell.Value = GetValue(pfad, datei, blatt, bezug)
Sprung:
Next
End Sub

Public Function GetValue(pfad, datei, blatt, zelle)
'** Daten aus geschlossener Arbeitsmappe auslesen
'Quelle https://www.excel-inside.de/vba-loesungen/datei/947-daten-aus-geschlossener- _
arbeitsmappe-auslesen
'*** Dimensionierung der Variablen
Dim arg As String
'Sicherstellen, dass die Datei vorhanden ist
If Right(pfad, 1) "\" Then pfad = pfad & "\"
If Dir(pfad & datei) = "" Then
GetValue = "datei Not Found"
Exit Function
End If
'** Das Argument erstellen
arg = "'" & pfad & "[" & datei & "]" & blatt & "'!" & Range(zelle).Range("A1").Address(, , _
xlR1C1)
'** Auslesen über Excel4Macro
GetValue = ExecuteExcel4Macro(arg)
End Function

Sub ClearCells_lang()
Dim r As Long
Dim a As Long
Dim zelle As Range
r = Selection.Row
a = WorksheetFunction.CountA(Worksheets("Analyse").Range("1:1")) + 3
For Each zelle In Sheets("Analyse").Range(Cells(r, 5), Cells(r, a))
If zelle.HasFormula = True Then Else zelle.ClearContents
Next zelle
End Sub

Mit freundlichen Grüßen
Tim Ertl

14
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Schleife / Code verschnellern?
10.05.2019 10:24:21
Nepumuk
Hallo Ertl,
mit ExecuteExcel4Macro(arg) öffnest du jedes mal die Datei, oder glaubst du Excel kann direkt von der Festplatte lesen? Das ist natürlich langsam. Öffne die Datei einmal richtig und lese die Daten aus, das ist wesentlich schneller.
Gruß
Nepumuk
AW: Schleife / Code verschnellern?
10.05.2019 10:54:35
Tim
Hallo Nepumuk,
mir ist klar, dass ExecuteExcel4Macro(arg) die Datei in irgendeiner Art und Weise öffnet.
Jedoch dachte ich, dass dies schon der schnellste/optimalste weg wäre Daten aus einer Datei schreibgeschützt auszulesen.
Also ist es wesentlich schneller, wenn ich die Datei im Makro erst schreibgeschützt öffne und wieder schließe?
Wäre das nicht das "Gleich/Selbe" wie das was ExecuteExcel4Macro(arg) macht?
Wo würde da jetzt eigentlich der Unterschied liegen?
Ich werde mal schauen wie ich das umschreiben kann...
Danke schonmal für die Antwort
Mit freundlichen Grüßen
Tim Ertl
Anzeige
AW: Schleife / Code verschnellern?
10.05.2019 11:15:39
Nepumuk
Hallo Ertl,
Wäre das nicht das "Gleich/Selbe" wie das was ExecuteExcel4Macro(arg) macht?
Ja, aber der Unterschied ist, du öffnest die Datei einmal und liest mehrere Werte aus.
Gruß
Nepumuk
AW: Schleife / Code verschnellern?
10.05.2019 11:16:33
Nepumuk
Hallo Ertl,
Wäre das nicht das "Gleich/Selbe" wie das was ExecuteExcel4Macro(arg) macht?
Ja, aber der Unterschied ist, du öffnest die Datei einmal und liest mehrere Werte aus. Momentan öffnest du die Datei pro Wert einmal.
Gruß
Nepumuk
AW: Schleife / Code verschnellern?
10.05.2019 13:47:02
Tim
Hallo Nepumuk,
ah ok das wusste ich nicht, danke für die Information. Dies ist selbstverständlich unnötig... was die Geschwindigkeit erklären würde.
MfG
Tim
Anzeige
AW: Schleife / Code verschnellern?
10.05.2019 11:26:01
Daniel
HI
probier mal so:
With Worksheets("Analyse").Cells(r, 5).Resize(1, a + 1)
.FormulaR1C1 = "=IF(RC2=""leer"","""",""='""&RC2&""[""&RC3&""]""&R1C&""'!""&R2C)"
.Formula = .Value
.Formula = .Value
End with
dies ersetzt die komplette For-Next-Schleife und die Zeile davor.
das GetValue brauchst du dann auch nicht mehr (weil es im Prinzip genau das gleiche macht)
wenn du den Code ausführst, solltest du darauf achten, dass die Werte korrekt sind und korrekte, vorhandende Zellbezüge ergeben.
auch solltest du das Makro erstmal mit einer Spalte testen (a = 0)
Gruß Daniel
Anzeige
AW: Schleife / Code verschnellern?
10.05.2019 13:45:47
Tim
Hallo Daniel,
vielen Dank für den Code.
Ich habe ihn gerade testen können und das Ergebnis ist schonmal viel versprechend.
Jedoch öffnet sich immer ein Explorer zum Auswählen der Datei und danach auch des Tabellenblattes.
Wie könnte ich das umgehen?
Ich habe mal eine starkabgeänderte Version meiner Datei hochgeladen.
https://www.herber.de/bbs/user/129705.xlsm
Mit freundlichen Grüßen
Tim Ertl
AW: Schleife / Code verschnellern?
10.05.2019 14:13:27
Daniel
Hi
die Rückfrage kommt immer dann, wenn du versuchst, einen Externen Zellbezug zu erzeugen, der nicht vorhanden ist!
das müsstest du für alle Zellen sicherstellen.
dh Pfad, Dateiname, Tabellenblattname und Adresse müssen korrekt geschrieben und in der Kombination auch vorhanden sein!
erst darfst du das Makro ausführen.
eine Bremse ist übrignes auch das Makro ClearCells_lang (und -_kurz auch)
Du solltest generell in Excel vermeiden, eine große Anzahl von Zellen in einer Schleife einzeln zu bearbeiten, wenn es dafür eine Massenfunktion gibt.
in deinem Fall wäre das, wenn du alle Zellen, die keine Formel haben in einem Bereich leeren willst:
Sheets(...).Range(...).SpecialCells(xlcelltypeconstants).ClearContents

bzw, um Fehler beim wiederholten ausführen zu vermeiden:
On Error Resume Next
Sheets(...).Range(...).SpecialCells(xlcelltypeconstants).ClearContents
On Error Goto 0
Gruß Daniel
Anzeige
AW: Schleife / Code verschnellern?
10.05.2019 14:49:53
Tim
Hallo,
habe den Fehler gefunden.
Meine "Splittformel" die den Pfad in Dateipfad und Dateiname splittet hat ein "\" übersprungen.
Jetzt kann ich nur noch WOW!!! sagen.
Von 14minuten Laufzeit runter auf 75sec.
Aktuell sind mir nur noch ein paar Formatierungs Fehler aufgefallen.
Unter anderem Zellen, die als Text formatiert sind behalten natürlich den Pfad des Makros bei und werden nicht zur Zahl / dem Datum oder einen Text, der in der Zelle steht.
Außerdem wird die Formel leider überschrieben.
Ich bedanke mich trotzdem schonmal sehr für die große Hilfe.
Ich wünsche dir/euch ein schönes Wochenende und ich werde mir am Montag mal den Rest zur Brust nehmen und ggf. nochmal hier Nachfragen, falls ich mir etwas auffällt oder ihr Vorschläge zu meinen aktuellen Problemen gibt. :)
Mit freundlichen Grüßen
Tim Ertl
Anzeige
AW: Schleife / Code verschnellern?
10.05.2019 14:53:39
Tim
Ps.: meine Hauptschleife schaut nun so aus:
Sub Zellen_auslesen_lang_all()
Dim a As String
Dim i As String
startTime = Time 'start
Call Applications_Anfang
a = WorksheetFunction.CountA(Worksheets("Analyse_lang").Range("A:A")) - 2
Worksheets("Analyse_lang").Cells(5, 4).Select
i = 0
On Error GoTo Error
Do Until i = a
Call Zelle_auslesen_lang2
ActiveCell.Offset(1, 0).Range("A1").Select
i = i + 1
Loop
stopTime = Time 'stop
elapsedTime = (stopTime - startTime) * 24 * 60 * 60 'umrechnung
If Format(elapsedTime, "0") >= 60 Then MsgBox ("Alle Werte wurden in " & Format(elapsedTime /  _
60, "0") & " Sekunden neu geladen!") Else
MsgBox ("Alle Werte wurden in " & Format(elapsedTime, "0") & " Sekunden neu geladen!")
Call Applications_Ende
Exit Sub
Call Applications_Ende
Error:
MsgBox ("Fehler! Pfad falsch?")
End Sub

Sub Zelle_auslesen_lang2()
'Code erstellt von Tim.Ertl mit großer hilfe von >Danielhttps://www.herber.de/cgi-bin/callthread.pl?index=1691896
Dim r As Long
Dim a As Long
Call ClearCells_lang
r = Selection.Row
a = WorksheetFunction.CountA(Worksheets("Analyse_lang").Range("1:1")) - 2
With Worksheets("Analyse_lang").Cells(r, 5).Resize(1, a + 1)
.FormulaR1C1 = "=IF(R1C=""leer"","""",""='""&RC2&""[""&RC3&""]""&R1C&""'!""&R2C)"
.Formula = .Value
.Formula = .Value
End With
End Sub


Sub ClearCells_lang()
'Code erstellt von Tim.Ertl mit großer hilfe von >Danielhttps://www.herber.de/cgi-bin/callthread.pl?index=1691896
Dim r As Long
Dim a As Long
Dim zelle As Range
r = Selection.Row
a = WorksheetFunction.CountA(Worksheets("Analyse_lang").Range("1:1")) + 3
On Error Resume Next
Sheets("Analyse_lang").Range(Cells(r, 5), Cells(r, a)).SpecialCells(xlCellTypeConstants). _
ClearContents
On Error GoTo 0
End Sub

Anzeige
AW: Schleife / Code verschnellern?
10.05.2019 15:05:49
Daniel
Hi
auch die Hauptschleife ist überflüssig.
du kannst die Formel wirklich in alle Zellen gleichzeitig schreiben, in die komplette Tabelle.
With Worksheets("Analyse_lang")
a = .Cells(.Rows.Count, 1).End(xlup).Row
b = .Cells(.1, .Columns.count).End(xltoleft).Column
With .Range(.Cells(5, 5), .Cells(a, b))
.FormulaR1C1 = "=IF(R1C=""leer"","""",""='""&RC2&""[""&RC3&""]""&R1C&""'!""&R2C)"
.Formula = .Value
end with
end with

Gruß Daniel
AW: Schleife / Code verschnellern?
10.05.2019 14:55:39
Daniel
Hi
wenn du die Formeln mit den Zellbezügen behalten willst, dann lass einfach das zweite .Formula = .Value weg.
eins brauchst du, um die per Formel als Text generierten externe Zellbezüge in echte externe Zellbezüge umzuwandeln, das zweite sollte dann dazu dienen, diese externen Zellbezüge dann in normale Werte zu wandeln. Das ist natürlich Optional, ich hatte das nur eingebaut, damit das Ergebnis dann gleich dem Ergebnis deines ursprünglichen Makros ist.
Gruß Daniel
Anzeige
AW: Schleife / Code verschnellern?
16.05.2019 11:27:59
Tim
Hallo Daniel,
entschuldige die so späte Antwort.
Ich konnte heute die Schleife umschreiben und bin mal wieder positiv überrascht wie schnell die Datei nun ist.
Die Hauptschleife benötigt nun nur noch 30sec.
Dim b As Long
Dim a As Long
Call ClearCells_all
With Worksheets("Einlesen_ErhBg_lang")
a = .Cells(.Rows.Count, 1).End(xlUp).Row
b = .Cells(1, .Columns.Count).End(xlToLeft).Column
With .Range(.Cells(5, 5), .Cells(a, b))
.FormulaR1C1 = "=IF(R1C=""leer"","""",IF(R1C=""Formel"",""=SUM(RC[-3]:RC[-1] _
)"",""='""&RC2&""[""&RC3&""]""&R1C&""'!""&R2C))"
.Formula = .Value
.Formula = .Value
End With
End With
Ich habe die Formel jetzt "einfach" in deine Programmierung integriert .. so kann mir da auch keiner die Formeln zerschießen.
Ich bedanke mich herzlich für die GROßE Hilfe :)
Mit freundlichen Grüßen
Tim Ertl
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige