Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1288to1292
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 beschleunigen

Makro beschleunigen
09.12.2012 18:07:30
lutz
Hallo Excel-Spezialisten,
ich habe einen Code der mir bei der Abrechnung ein Bezahlt Text in meine Buchungstabelle schreibt.
Leider wird der Code immer langsamer und dauert mittlerweile bei 4000 Datensätzen über eine Minute.
Kann man den Code beschleunigen? Ich habe schon ein paar Sachen eingebaut es dauert aber immer noch recht lange...
Hier der Code:
Sub Bezahlt_markieren2()
Dim RechnungsFeld, Listenfeld As Object
Dim Awsheet As String
Awsheet = ActiveSheet.Name
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.DisplayAlerts = False
Application.Calculation = xlManual
ActiveWorkbook.Sheets("Liste").Activate
For Each RechnungsFeld In Worksheets(Awsheet).Range("V10:V" & Worksheets(Awsheet).Cells. _
SpecialCells(xlCellTypeLastCell).Row)
For Each Listenfeld In ActiveSheet.Range("V2:V" & ActiveSheet.Cells.SpecialCells( _
xlCellTypeLastCell).Row)
If Listenfeld.Text = RechnungsFeld.Text Then
'If Listenfeld.Offset(0, 1) = RechnungsFeld.Offset(0, 1) Then
ActiveSheet.Range("AL" & Listenfeld.Row) = "bez"
ActiveSheet.Range("AM" & Listenfeld.Row) = Now
'End If
End If
Next Listenfeld
Next RechnungsFeld
Application.ScreenUpdating = True
Application.EnableEvents = True
Application.DisplayAlerts = True
Application.Calculation = xlAutomatic
ActiveWorkbook.Sheets(Awsheet).Activate
End Sub

Vielen Dank für Eure Hilfe und viele Grüße Lutz

26
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Makro beschleunigen
09.12.2012 18:44:25
Daniel
Hi
wäre es nicht einfacher, anstelle des Makros einfach einfach eine Formel zu verwenden ?
formel in
AL2: =Wenn(SVerweis(V2;Tabelle1!$V$10:$W$4000;2;0)=W2;"bez.";"")
AM2: =Wenn(SVerweis(V2;Tabelle1!$V$10:$W$4000;2;0)=W2;Heute();"")

danachd dann spalte AL und AM kopieren und an gleicher Stelle als Wert einfügen (damit das Datum fixiert wird)
noch schneller wirds, wenn du die Tabelle1 vorher noch nach der Spalte V sortierst, dann kannst du die schneller Verwsion des SVerweises verwenden (4. Parameter = 1), dann musst du die Formel allerdings etwas abändern:
AL2: =Wenn(SVerweis(V2;Tabelle1!$V$10:$V$4000;1;1)=V2;Wenn(SVerweis(V2;Tabelle1!$V$10:$W$4000;2;1)=W2;"bez.";"");"")
wenn du ein schnelles Makro brauchst, dann würde ich eins schreiben, welches genau diese Schritte ausführt:
- Sortieren
- SVerweis Formel einfügen
- Formel durch Werte ersetzen.
Gruß Daniel

Anzeige
AW: Makro beschleunigen
09.12.2012 19:04:47
lutz
Hallo Daniel,
vielen Dank für Deinen Tipp - vielleicht ist der Ablauf nicht ganz klar geworden:
Im aktiven Blatt suche ich nach einem Kunden und erstelle die Abrechnung. Die Drucke ich aus und der Kunde zahlt.
Nun muß im Blatt "Liste" genau nach diesem Kunden gesucht werden und seine Datensätze auf "bez" gesetzt werden.
Dann kommt der nächste Kunde und ich gehe wieder in das aktive Blatt und selektiere nach diesem Kunden... (nun würde die Formel aber bei dem Kunden aber nichts mehr finden und die Sätze wären wieder offen)
Der Sinn des Codes ist den gerade selekierten Kunden (der sich danach wieder ändert) im Blatt Liste zu suchen und alle seine Datensätze auf "bez" zu setzen (fest; im Blatt Liste dürfen/sollen keine Formeln sein da wird immer wieder etwas angehängt)
Was evt. Sinn machen wwürde ist im Blatt Liste am Anfang einen Autofilter zu setzen, dann nur noch die sichtbaren Datensätze durchzugehen und den Autofilter wieder zu entfernen - ich weiß aber nicht wie das per Makro geht.
Viele Grüße Lutz

Anzeige
AW: Makro beschleunigen
09.12.2012 19:28:38
Daniel
Hi
sorry, ich habe versucht das umzusetzen, was dein Code macht.
was du erreichen willst und wie deine Datei dazu aussieht, daß hast du uns leider verschiegen.
beide Informationen sind aber wichtig, wenn man einen Ablauf beschleunigen will
also beschreib mal genauer, was passieren soll und ladei die Datei hier hoch, dann kann kann man sich mal überlegen, wie das ganze zu beschleunigen ist.
gruß Daniel

AW: Makro beschleunigen
09.12.2012 20:53:53
lutz
Hallo Daniel,
da sind unsere gesamten Kundendaten drin...
Das Problem liegt doch wohl hier:
For Each Listenfeld In ActiveSheet.Range("V2:V" & ActiveSheet.Cells.SpecialCells(xlCellTypeLastCell).Row)
If Listenfeld.Text = RechnungsFeld.Text Then
'If Listenfeld.Offset(0, 1) = RechnungsFeld.Offset(0, 1) Then
ActiveSheet.Range("AL" & Listenfeld.Row) = "bez"
ActiveSheet.Range("AM" & Listenfeld.Row) = Now
Er geht durch jede Zeile und sucht nach
Listenfeld.Text = RechnungsFeld.Text
Kann man das nicht schon scneller machen wenn man sagt wenn Listenfeld.Text ungleich RechnungsFeld.Text dann gehe weiter - und nur wenn es gleich ist tue...
ActiveSheet.Range("AL" & Listenfeld.Row) = "bez"
ActiveSheet.Range("AM" & Listenfeld.Row) = Now
Oder eben filtere in einem Schlag Spalte V mit Filterkriterium Rechnungsfeld und gehe dann durch die gefilterten Zeilen und setze
ActiveSheet.Range("AL" & Listenfeld.Row) = "bez"
ActiveSheet.Range("AM" & Listenfeld.Row) = Now
Eine der beiden Möglichkeiten sollte doch schneller gehen?
Viele Grüße Lutz

Anzeige
AW: Makro beschleunigen
09.12.2012 21:09:56
Daniel
Hi
die Frage ist, sind die Werte in den Feldern eindeutig oder können sie mehrfach vorkommen?
Gruß Daniel

AW: Makro beschleunigen
09.12.2012 21:20:05
lutz
Hallo Daniel,
das ist eine Kundennummer - die ist eindeutig, kann natürlich in vielen Zeilen vorkommen.
Ein Kunde = 1 Nummer
Aber es gubt z.B. 103, 1003, 1103
Viele Grüße Lutz

AW: Makro beschleunigen
09.12.2012 21:27:15
Daniel
Hi
sorry, aber ohne die beiden Listen zu kennen, sehe ich mich ausserstande, da was passends zu schreiben.
ne Beispieldatei mit ein paar Zeilen wäre hilfreich.
du kannst Personenbezogene Daten ja verfälschen (Max Mustermann)
Gruß Daniel

Anzeige
AW: Makro beschleunigen
09.12.2012 21:30:35
Daniel
Hi
sorry, aber ohne die beiden Listen zu kennen, sehe ich mich ausserstande, da was passends zu schreiben.
ne Beispieldatei mit ein paar Zeilen wäre hilfreich.
du kannst Personenbezogene Daten ja verfälschen (Max Mustermann)
Gruß Daniel

AW: Makro beschleunigen
09.12.2012 21:45:03
lutz
Hallo Daniel,
hier ist mal eine Beispieldatei - komischerweise geht es in dieser Datei rasend schnell auch wenn man 4000 Zeilen runterkopiert.
https://www.herber.de/bbs/user/82952.xls
Viele Grüße Lutz

AW: Makro beschleunigen
09.12.2012 22:08:50
Daniel
dein tabellenblatt "Prov" ist ziemlich leer.
ist das in der Realität auch so ?
ich kann ja jetzt nicht erkennen, in welchem Feld und warum da jetzt ein "bez" eingetragen werden sollte.
Gruß Daniel

Anzeige
AW: Makro beschleunigen
09.12.2012 22:11:51
lutz
Hallo Daniel, das bez wird im Blatt Liste eingetragen - Spalte AL.
Viele Grüße Lutz

AW: Makro beschleunigen
09.12.2012 22:19:52
Daniel
Hi
das ist mir klar.
soll das einfach für alle Werte eingetragen werden ?
die Kundennummer kommt ja mehrfach vor.
in deinem Codebeispiel hattest du ja noch eine weitere Abfrage (das mit dem .Offset)
dazu kann ich in der Beispieldatei nichts finden.
Sorry, aber es ist echt verdammt mühselig, dir jede Information einzeln abzuringen.
Gruß Daniel

AW: Makro beschleunigen
09.12.2012 22:26:30
lutz
Hallo Daniel,
sorry wenn es nicht rüberkommt aber es ist immer die gleiche Aufgabe und an den Codings hat sich auch nichts geändert.
Im Blatt Prov Spalte V trägt man die Kundennummer ein, mit dieser Nummer geht der Code in das Blatt Liste, sucht in Spalte V nach der Kundennummer (in jeder Zeile denn der Kunde kann mehrere Artikel gekauft haben) und trägt dann über offset in den Spalten AL = "bez" und in Spalte AM das aktuelle Datum ein.
Viele Grüße Lutz

Anzeige
AW: Makro beschleunigen
09.12.2012 22:39:59
Daniel
Hi
ich vermute mal, daß Problem liegt auch in deiner Rechungsdatei.
wenn dort die "LastCell" nicht passt und zuviele Zellen angezogen werden, dann läuft die Schleife unnötig oft mit unnützen werten.
Bedenke daß "LastCell" auch Formatierte Zellen berücksichtigt, auch wenn diese keinen Inhalt haben.
für den Fall, daß die auskommentierte Bedingung nicht mehr benötigt wird, habe ich das Makro mal so umgeschrieben:
Sub Bezahlt_markieren2()
Dim RechnungsFeld As Range
Dim Awsheet As Worksheet
Set Awsheet = ActiveSheet
For Each RechnungsFeld In Awsheet.Range("V10:V" & Awsheet.Cells.SpecialCells(xlCellTypeLastCell) _
.Row)
With Sheets("Liste").Range("V:V")
.Replace RechnungsFeld.Text, True, xlWhole
If WorksheetFunction.CountIf(.Cells, True) > 0 Then
With .SpecialCells(xlCellTypeConstants, 4)
Intersect(.EntireRow, .Parent.Range("AL:AL")).Value = "bez"
Intersect(.EntireRow, .Parent.Range("AM:AM")).Value = Now
.Value = RechnungsFeld.Text
End With
End If
End With
Next
End Sub
aber wie gesagt, wich würde mal checken, was da bei LastCell so rauskommt und ggf hier die Ermittlung des Zellbereichs überprüfen.
Gruß Daniel

Anzeige
AW: Makro beschleunigen
09.12.2012 22:49:23
lutz
Hallo Daniel,
Bingo - das scheint es zu sein - habe mal ganz unten in Spalte V auf Fett gesetzt und dann meinen Code laufen lassen; der war langsam - Deiner nicht.
Vielen lieben Dank für Deine Hilfe und viele Grüße Lutz

AW: Makro beschleunigen
09.12.2012 23:00:42
Daniel
Hi
diesbezüglich ist mein Code nicht besser als einer, weil auch mein Code nutzt ja die LastCell zum ermitteln der Anzahl der Werte in der Rechungsdatei.
um den besten Code zu finden, sollte man hier nochmal ansetzen, dazu müsste man aber sehen, wie das Blatt "Prov" tatsächlich aussieht.
gruß Daniel

AW: Makro beschleunigen
09.12.2012 21:47:25
fcs
Hallo Lutz,
warum hast du die äußere For-Each-Schleife (Rechnungsfeld), wenn du nur die Daten eines Kunden in der Liste auf "bez" setzen willst. Ermittle die KundenNummer und vergleiche dann die KundenNummer mit den Einträgen in Spalte V der Liste.
Dann muss die For-Each-Schleife (Listenfeld) nur einmal durchlaufen werden.
Bei sehr langen Listen ist es ggf. schneller mit der Suchenfunktion von Excel zu arbeiten statt mit einer For-Next-Schleife.
Gruß
Franz

Anzeige
AW: Makro beschleunigen
09.12.2012 21:50:16
lutz
Hallo Franz, vielen Dank für den Tipp - was genau muß ich da ändern?
Viele Grüße Lutz

AW: Makro beschleunigen
11.12.2012 04:30:39
fcs
Hallo Lutz,
hier ein an deine Beispiel-Datei angepasstes Makro.
Laufzeit des Makros sollte jetzt max. 2 Sekunden sein. Ist natürlich abhängig von Rechner-Power und Auslastung des Rechners.
Weitere Beschleunigung bei der Ausführung des Makros besteht in der Sortierung von Blatt "Liste"
Wenn diese nach der Kunden-Nr oder dem Bezahl-Zeitpunkt sortiert ist, dann kann man die Suchschleife abbrechen, wenn alle Zeilen mit der abzugleichenden Kunden-Nr abgearbeitet sind, oder wenn in der Liste zur Kunden-Nr. die 1. Zeile mit "bez" auftaucht.
Gruß
Franz
Sub Bezahlt_markieren2()
Dim wksAktiv As Worksheet, wksListe As Worksheet
Dim ZeileAktiv As Long, ZeileListe As Long
Dim ZeileAktivL As Long, ZeileListeL As Long
Dim Zeit As Date, strKndNr As String
Set wksAktiv = ActiveSheet 'Rechnungsblatt / Prov
Set wksListe = Worksheets("Liste")
'Prüfen, ob Blatt "Liste" aktives Blatt
If wksAktiv.Name = wksListe.Name Then
MsgBox "Makro darf nicht gestartet werden, wenn Blatt ""Liste"" das aktive blatt ist",  _
_
vbInformation + vbOKOnly, "Makro: Bezahlt_markieren2"
GoTo Beenden
End If
With Application
.ScreenUpdating = False
.EnableEvents = False
.DisplayAlerts = False
.Calculation = xlManual
End With
With wksAktiv 'Rechnungsblatt
'Letzte Zeile mit Daten in Spalte V (22)
ZeileAktivL = .Cells(.Rows.Count, 22).End(xlUp).Row
If ZeileAktivL >= 10 Then
'Kundennummer ermitteln
For ZeileAktiv = 10 To ZeileAktivL
With .Cells(ZeileAktiv, 22)
If Val(.Text) > 0 Then
strKndNr = .Text
Exit For
End If
End With
Next ZeileAktiv
Else
MsgBox "Keine Daten im aktiven Blatt Spalte V"
GoTo Beenden
End If
End With
If strKndNr = "" Then
MsgBox "Keine Kunden-Nr, in Spalte V im aktiven Blatt gefunden"
GoTo Beenden
End If
With wksListe 'Listenblatt
'Letzte Zeile mit Daten in Spalte V (22)
ZeileListeL = .Cells(.Rows.Count, 22).End(xlUp).Row
If ZeileListeL >= 2 Then
'.Activate
Zeit = Now
For ZeileListe = 2 To ZeileListeL
If .Cells(ZeileListe, 22).Text = strKndNr Then
'Prüfung, ob "bez" für Kunden-Nr. schon eingetragen
If .Cells(ZeileListe, 38).Value  "bez" Then
.Cells(ZeileListe, 38).Value = "bez"  'Spalte AL
.Cells(ZeileListe, 39).Value = Zeit   'Spalte AM
End If
End If
Next ZeileListe
Else
MsgBox "Keine Daten in Spalte V im Blatt ""Liste"""
End If
End With
Beenden:
With Application
.ScreenUpdating = True
.EnableEvents = True
.DisplayAlerts = True
.Calculation = xlAutomatic
End With
wksAktiv.Activate
Set wksAktiv = Nothing
Set wksListe = Nothing
End Sub

Anzeige
AW: Makro beschleunigen
16.12.2012 21:58:38
lutz
Hallo Franz - vielen Dank, war leider unterwegs und komme erst jetzt dazu.
Toller Code und wirklich sehr schnell!!!
Viele Grüße Lutz

Wahrscheinlich, denn du vglst jedes ...
09.12.2012 19:02:06
Luc:-?
Listenfeld mit jedem RechnungsFeld direkt aus den Blättern, Lutz.
Ich würde beide Bereiche erst in Datenfelder lesen (mit WorksheetFunction.Transpose) und dann, wenn wirklich jedes Element des einen gleich irgendeinem des anderen Datensatzes sein darf/kann, das ebenfalls mit 2 For-Each-Schleifen lösen. Sollte dann aber schon merklich schneller laufen.
Falls es aber auch auf die Position ankommt, d.h. nur die Gleichheit gleicher Positionen relevant ist, würde man nur eine For-Each-Schleife benötigen, die auch beide Datenfelder gleichzeitig durchlaufen könnte, wenn man die vorher in einem Variant so kombiniert, dass die Laufvariable ein Vektor aus 2 Elementen ist, was möglicherweise etwas schneller wäre als die direkte Indizierung per For-Schleife, die hierfür sonst wohl erforderlich sein dürfte.
Spielt die Position keine Rolle, weil beide Datenfelder weder positionsgleich sind noch gemacht wdn können, ist diese Methode natürl nicht anwendbar.
Gruß Luc :-?

AW: Wahrscheinlich, denn du vglst jedes ...
09.12.2012 19:07:39
lutz
Hallo Luc,
vielen Dank für Deine Hilfe - ich muß wohl sagen, dass ich den geposteten Code nicht selber geschrieben habe. D.h. ich kann Deine Tipps leider nicht ohne Hilfe umsetzen.
Hier noch mal etwas was ich eben Daniel geantwortet hatte:
vielen Dank für Deinen Tipp - vielleicht ist der Ablauf nicht ganz klar geworden:
Im aktiven Blatt suche ich nach einem Kunden und erstelle die Abrechnung. Die Drucke ich aus und der Kunde zahlt.
Nun muß im Blatt "Liste" genau nach diesem Kunden gesucht werden und seine Datensätze auf "bez" gesetzt werden.
Dann kommt der nächste Kunde und ich gehe wieder in das aktive Blatt und selektiere nach diesem Kunden... (nun würde die Formel aber bei dem Kunden aber nichts mehr finden und die Sätze wären wieder offen)
Der Sinn des Codes ist den gerade selekierten Kunden (der sich danach wieder ändert) im Blatt Liste zu suchen und alle seine Datensätze auf "bez" zu setzen (fest; im Blatt Liste dürfen/sollen keine Formeln sein da wird immer wieder etwas angehängt)
Was evt. Sinn machen wwürde ist im Blatt Liste am Anfang einen Autofilter zu setzen, dann nur noch die sichtbaren Datensätze durchzugehen und den Autofilter wieder zu entfernen - ich weiß aber nicht wie das per Makro geht.
Vielen Dank schon einmal und viele Grüße Lutz

AW: Makro beschleunigen
09.12.2012 21:58:02
Gerd
Hallo Lutz,
probier doch mal inetwa wie von Luc vorgeschlagen.
Sub Bezahlt_markieren2()
Dim RechnungsFelder, Listenfelder, L As Long, M As Long
Dim Awsheet As String
Awsheet = ActiveSheet.Name
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.DisplayAlerts = False
Application.Calculation = xlManual
'ActiveWorkbook.Sheets("Liste").Activate
RechnungsFelder = Worksheets(Awsheet).Range("V10:V" & Worksheets(Awsheet).Cells. _
SpecialCells(xlCellTypeLastCell).Row).Value
Listenfelder = ActiveWorkbook.Sheets("Liste").Range("V2:V" & ActiveWorkbook.Sheets("Liste") _
.Cells.SpecialCells( _
xlCellTypeLastCell).Row).Value
Ausgabefelder = ActiveWorkbook.Sheets("Liste").Range("AL2:AM" & ActiveWorkbook.Sheets(" _
Liste").Cells.SpecialCells( _
xlCellTypeLastCell).Row).Value
For L = LBound(RechnungsFelder, 1) To UBound(RechnungsFelder, 1)
For M = LBound(Listenfelder, 1) To UBound(Listenfelder, 1)
If Listenfelder(M, 1) = RechnungsFelder(L, 1) Then
Ausgabefelder(M, 1) = "bez"
Ausgabefelder(M, 2) = Now
End If
Next Listenfelder
Next RechnungsFelder
ActiveWorkbook.Sheets("Liste").Range("AL2:AM" & ActiveWorkbook.Sheets("Liste").Cells. _
SpecialCells( _
xlCellTypeLastCell).Row).Value = Ausgabefelder
Application.ScreenUpdating = True
Application.EnableEvents = True
Application.DisplayAlerts = True
Application.Calculation = xlAutomatic
'ActiveWorkbook.Sheets(Awsheet).Activate
End Sub
Gruß Gerd

AW: Makro beschleunigen
09.12.2012 22:10:39
lutz
Hallo Gerd,
vielen Dank, leider steigt der Code hier aus:
Next Listenfelder
Fehlermeldung:
Ungültiger Verweis auf Next
Viele Grüße Lutz

AW: Makro beschleunigen
09.12.2012 22:25:44
Gerd
Hallo Lutz,
lösche die Bezeichnungen hinter "Next" einfach. (Da müsste M bzw. L stehen.)
Gruß Gerd

AW: Makro beschleunigen
09.12.2012 22:37:12
lutz
Hallo Gerd,
Danke für die Hilfe,
leider steigt er immer noch aus:
For L = LBound(RechnungsFelder, 1) To UBound(RechnungsFelder, 1)
For M = LBound(Listenfelder, 1) To UBound(Listenfelder, 1)
Er erwartet ein Datenfeld bei RechnungsFelder
Ich habe mal ein paar Variablentypen getestet: Long, Variant, Object aber er steigt immer aus:(
Viele Grüße Lutz

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige