Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1964to1968
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 baucht zu lange (Not responding)

Makro baucht zu lange (Not responding)
20.02.2024 10:46:39
Kace
Hallo zusammen,

mein Problem ist eigentlich relativ simpel:

Das Makro ist zu ineffizient und bringt Excel zum aufhängen. Wenn man lange genug wartet antwortet Excel zwar irgendwann und schließt den Vorgang auch ab, dies dauert aber wie gesagt zu lange. Ich habe mich bereits ein wenig durchs Forum gelesen und Screenupdating, etc ausgeschaltet. Aber das bringt auch relativ wenig. Ich denke, dass das Problem einfach daran liegt, dass die Dateien sehr groß sind (ca. 32.000 Zeilen) und jede dieser Zeilen auf Übereinstimmung geprüft wird. Falls mehr Hintergrundinformationen erforderlich sind, als der Code hergibt, oder Fragen bestehen, werde ich diese gerne beantworten. Falls jemand eine Alternative hat, bin ich ebenfalls offen.

Danke


Hier der Code:




Sub CopyQualiStatus()
Dim wsSource As Worksheet
Dim wsTarget As Worksheet
Dim rng As Range
Dim cell As Range
Dim i As Long

'Mehr Performance?
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
.EnableEvents = False
End With

'Arbeitsblätter setzen
Set wsSource = ThisWorkbook.Sheets("alle Qualis gefiltert")
Set wsTarget = ThisWorkbook.Sheets("Aktueller Quali-Status")

'jede Zeile von "alle Qualis gefiltert" durchlaufen
For Each cell In wsSource.Range("B2:B" & wsSource.Cells(wsSource.Rows.Count, "B").End(xlUp).Row)
'jede Zeile von "aktueller Quali-Status" durchlaufen
For i = 9 To wsTarget.Cells(wsTarget.Rows.Count, "C").End(xlUp).Row
' Wenn ID und Qualifikation übereinstimmen und in Spalte H nicht gleich Spalte G ist, in "alle Qualis gefiltert"
If wsTarget.Cells(i, "C").Value = cell.Value And wsTarget.Cells(i, "F").Value = wsSource.Cells(cell.Row, "E").Value And wsTarget.Cells(i, "H").Value > wsSource.Cells(cell.Row, "G").Value Then
wsSource.Cells(cell.Row, "I").Value = wsTarget.Cells(i, "H").Value
' Beenden Sie die Schleife, sobald eine Übereinstimmung gefunden wurde
Exit For
End If
Next i
' Wenn keine Übereinstimmung gefunden wurde, lassen Sie die Zelle leer
If wsSource.Cells(cell.Row, "I").Value = "" Then
wsSource.Cells(cell.Row, "I").Value = ""
End If
Next cell

'Mehr Performance?
With Application
.ScreenUpdating = True
.Calculation = xlAutomatic
.EnableEvents = True
End With

'Nachricht
MsgBox "Der Vorgang wurde beendet.", vbInformation

End Sub

5
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Makro baucht zu lange (Not responding)
20.02.2024 11:23:37
peter
Hallo

Folgender Code ist eigentlich Unsinn



If wsSource.Cells(cell.Row, "I").Value = "" Then
wsSource.Cells(cell.Row, "I").Value = ""
End If


Bei der "großen" IF Anweisung werden immer ALLE Kriterien geprüft, daher wären hier geschachtelte IF besser (wenn auf C keine Übereinstimmung gefunden wurde, braucht der Rest nicht mehr kontrolliert werden).

Wenn keine Zeile mit allen Kriterien gefunden werden kann, durchläufst du die Schleife immer bis zum Ende. Kannst du vielleicht ein Abbruchkriterium einbauen? (z.B. Quali Status nach C sortieren und erkennen ob es noch Sinn macht weiter zu suchen).

Ein anderere Ansatz wäre Range.Find bzw. Range.FindNext für das 1. Kriterium.

Mfg.
Peter
Anzeige
AW: Makro baucht zu lange (Not responding)
20.02.2024 11:48:06
daniel
Hi
bei der Datenmenge musst du so vorgehen:

1. verkette in beiden Listen die Zellen, die den Vergleichswert darstellen (also die ID) zu einem Text
also in wsSource die Spalten B, E und G, und in wsTarget die Spalten C, F und H.
dh in wsSource in einer Hilfsspalte ab Zeile 2 die Formel: =B2&"-"&E2&"-"&G2
und in wsTarget in einer Hilfsspalte ab Zeile 9 die Formel =C2&"-"&F2&"-"&H2
Stelle die Hilfsspalte an den Anfang also in Spalte A

2. Sortiere die wsTarget nach der Hilfsspalte aufsteigend.

3. Löse die Aufgabe jetzt mit folgender Formel in einer weiteren Hilfsspalte im Blatt wsSource:
=Wennfehler(Wenn(SVerweis(A2;'Aktueller Quali-Status'!A9:A???;1;wahr)=A2;SVerweis(A2;'Aktueller Quali-Status'!A9:I???;9;wahr);I2);I2)

4. kopiere dann diese Hilfsspalte als Wert nach Spalte I

5. lösche gegebenenfalls die ID-Spalten und sortiere in die Original-Sortierung zurück , falls erforderlich


das ist schneller, weil du hier aufgrund der Sortierung die schnelle SVerweis-Variante verwenden kannst und nicht mehr Zelle für Zelle vergleichen (nur der SVerweis und Vergleich können in Excel die Schnelle Suche in sortierten Daten durchführen)

mach die oben aufgeführten Schritte erst mal von hand. Wenn es klappt und du verstanden hast, was da passiert, kannst du dir diese Schritte als Makro programmieren.

Gruß Daniel
Anzeige
AW: Makro baucht zu lange (Not responding)
20.02.2024 12:02:32
Kace
Hi an alle,
vielen Dank für die schnellen Antworten!

Keine Ahnung ob ich hier mehreren Leuten gleichzeitig antworten kann, deswegen jetzt so.

Ich habe die If Anweisung gesplitet, das hat denke ich schon ein wenig geholfen.

Außerdem habe ich den Code mal an den Bing Copilot geschickt und mit Ansätzen aus diesem Thread gefüttert. Die KI hat Dictonaries verwendet, um den Vorgang deutlich zu beschleunigen. Jetzt läuft der Code in 1-2 Sekunden durch und es kommt denke ich zu keinen Problemen. Falls der neue Code jemanden interessiert und er ihn durchliest oder überfliegt und Probleme findet, wäre ich jedoch dankbar, wenn ihr mich darauf hinweist :)

Der abgeänderte Code:




Sub CopyQualiStatus()
Dim wsSource As Worksheet
Dim wsTarget As Worksheet
Dim rng As Range
Dim cell As Range
Dim i As Long
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")

'Screenupdates etc. ausschalten für mehr Performance
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
.EnableEvents = False
End With

'Arbeitsblätter setzen
Set wsSource = ThisWorkbook.Sheets("alle Qualis gefiltert")
Set wsTarget = ThisWorkbook.Sheets("Aktueller Quali-Status")

'jede Zeile von "aktueller Quali-Status" durchlaufen und in Dictionary speichern
For i = 9 To wsTarget.Cells(wsTarget.Rows.Count, "C").End(xlUp).Row
dict(wsTarget.Cells(i, "C").Value & "|" & wsTarget.Cells(i, "F").Value) = wsTarget.Cells(i, "H").Value
Next i

'jede Zeile von "alle Qualis gefiltert" durchlaufen
For Each cell In wsSource.Range("B2:B" & wsSource.Cells(wsSource.Rows.Count, "B").End(xlUp).Row)
' Wenn ID und Qualifikation übereinstimmen und Spalte H nicht gleich Spalte G ist, in "alle Qualis gefiltert" einfügen
If dict.Exists(cell.Value & "|" & wsSource.Cells(cell.Row, "E").Value) And dict(cell.Value & "|" & wsSource.Cells(cell.Row, "E").Value) > wsSource.Cells(cell.Row, "G").Value Then
wsSource.Cells(cell.Row, "I").Value = dict(cell.Value & "|" & wsSource.Cells(cell.Row, "E").Value)
Else
' Wenn keine Übereinstimmung gefunden, Zeile leer lassen
wsSource.Cells(cell.Row, "I").Value = ""
End If
Next cell

'Screenupdates etc. anschalten für mehr Performance
With Application
.ScreenUpdating = True
.Calculation = xlAutomatic
.EnableEvents = True
End With

'Nachricht
MsgBox "Der Vorgang wurde beendet.", vbInformation

End Sub

Anzeige
AW: Makro baucht zu lange (Not responding)
20.02.2024 14:52:09
Yal
Hallo Kace,

vielleicht nicht viel schneller:

Sub CopyQualiStatus()

Dim dict As Object
Dim Arr
Dim i As Long
Dim BE As String

'Screenupdates etc. ausschalten für mehr Performance
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False

'Arbeitsblätter setzen
'jede Zeile von "aktueller Quali-Status" durchlaufen und in Dictionary speichern
With ThisWorkbook.Sheets("Aktueller Quali-Status")
Set dict = CreateObject("Scripting.Dictionary")
Arr = Range(.Cells(9, "H"), .Cells(Rows.Count, "C").End(xlUp)).Value
For i = LBound(Arr, 1) To UBound(Arr, 1)
dict(Arr(i, 1) & "|" & Arr(i, 4)) = Arr(i, 6) 'Array-Spalte 1 ist "C", 4 ist "F" und 6 ist "H"
Next i
End With
'jede Zeile von "alle Qualis gefiltert" durchlaufen
With ThisWorkbook.Sheets("alle Qualis gefiltert")
For i = 1 To .Cells(Rows.Count, "B").End(xlUp).Row
' Wenn ID und Qualifikation übereinstimmen und Spalte H nicht gleich Spalte G ist, in "alle Qualis gefiltert" einfügen
BE = .Cells(i, "B").Value & "|" & .Cells(i, "E").Value
.Cells(i, "I").ClearContents 'grundsätzlich leeren
If dict.Exists(BE) Then If dict(BE) > .Cells(i, "G").Value Then .Cells(i, "I").Value = dict(BE) 'dann situativ nachfüllen
Next cell
End With

'Screenupdates etc. anschalten für mehr Performance
Application.ScreenUpdating = True
Application.Calculation = xlAutomatic
Application.EnableEvents = True

'Nachricht
MsgBox "Der Vorgang wurde beendet.", vbInformation
End Sub


VG
Yal
Anzeige
AW: Zellen-Vergleich besonders langsam
20.02.2024 11:34:21
Fennek
Hallo,

der Zugriff auf einzelne Zellen ist recht langsam. Warum nutzt Du nicht die Suchfunktion mit "Range.Find"?

mfg

Links zu Excel-Dialogen

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige