Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1952to1956
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 effizienter machen

Makro effizienter machen
13.11.2023 13:25:58
Julian
Guten Tag,

ich hab folgendes Problem, da ich mich in VBA nicht gut auskenne: Bei dem unten abgebildeten Makro ist das Ziel Das Blatt "Arbeit" mit den restlichen Blättern zu vergleichen, nach möglichen Duplikaten schauen und wenn ein Duplikat auftaucht dieses zu löschen. Problem hierbei ist, dass es eine ewig lange Durchlaufzeit hat, da das Blatt Arbeit jedes Mal neu durchlaufen wird.
Ist es möglich die anderen Blätter z.B. in Array zu packen und das Blatt "Arbeit" dann nur noch mit dem Array, in dem sich alle anderen Blätter zu vergleichen, um so Zeit einzusparen?

Vielen Dank schon mal im Voraus und ich bin gespannt auf eure Ideen!

LG Julian

Dim k As Long

With Sheets("Arbeit")
For k = .Cells(Rows.Count, "CV").End(xlUp).Row To 2 Step -1
If Application.IsNumber(Application.Match(.Cells(k, "CV"), Sheets("Arbeit 1").Columns(100), 0)) Then
.Cells(k, "CV").EntireRow.Delete
ElseIf Application.IsNumber(Application.Match(.Cells(k, "CV"), Sheets("Arbeit 2").Columns(100), 0)) Then
.Cells(k, "CV").EntireRow.Delete
ElseIf Application.IsNumber(Application.Match(.Cells(k, "CV"), Sheets("Arbeit 3").Columns(100), 0)) Then
.Cells(k, "CV").EntireRow.Delete
ElseIf Application.IsNumber(Application.Match(.Cells(k, "CV"), Sheets("Arbeit 4").Columns(100), 0)) Then
.Cells(k, "CV").EntireRow.Delete
ElseIf Application.IsNumber(Application.Match(.Cells(k, "CV"), Sheets("Arbeit 5").Columns(100), 0)) Then
.Cells(k, "CV").EntireRow.Delete
ElseIf Application.IsNumber(Application.Match(.Cells(k, "CV"), Sheets("Arbeit 6").Columns(100), 0)) Then
.Cells(k, "CV").EntireRow.Delete
ElseIf Application.IsNumber(Application.Match(.Cells(k, "CV"), Sheets("Arbeit 7").Columns(100), 0)) Then
.Cells(k, "CV").EntireRow.Delete
ElseIf Application.IsNumber(Application.Match(.Cells(k, "CV"), Sheets("Arbeit 8").Columns(100), 0)) Then
.Cells(k, "CV").EntireRow.Delete
End If
Next
End With

End Sub

11
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Makro effizienter machen
13.11.2023 13:29:31
onur
" in dem sich alle anderen Blätter zu vergleichen" ???
AW: Makro effizienter machen
13.11.2023 14:50:20
daniel
HI

du hast hier zwei Zeitfresser.
zum einen die Suche in jedem Tabellenblatt mit dem langsamen VLookup, zum anderen das Löschen einzelner Zeilen.

mit etwas Vorbereitung kann man das erheblich beschleunigen.
ich würde hier zuerst mal alle Spalten CV der einzelnen Blätter auf einem neuen Blatt in eine Spalte zusammen kopieren, dort die Duplikate entfernen und diese sortieren, dann brauchst du nur an einer Stelle suchen und du kannst aufgrund der Sortierung die Schnelle Variante des SVerweises verwenden.

zum Löschen markiert man dann in einer Hilfsspalte die Zeilen, die gelöscht werden sollen mit 0 und die anderen mit der Zeilennummer.
dann kann man die Zeilen über das Duplikate-Entfernen löschen, was sehr schnell geht.

sieht als Code dann so aus (mangels bespieldatei ungetestet)
zur Vorbereitung musst du noch das Blatt mit dem Namen "neu" anlegen.
Durchsucht werden alle Blätter mit dem Namen "Arbeit x", also "Arbeit" mit nachfolgender Nummer mit Leerzeichen davor.

Sub Duplikate_Löschen_mehrere_Arbeitsblätter()

Dim wsh As Worksheet
Dim sp As Long
sp = 100
With Sheets("neu")
.cells.Clear
.Cells(1, 1).Value = 0
For Each wsh In ThisWorkbook.Worksheets
If wsh.Name Like "Arbeit *" Then
wsh.UsedRange.Columns(sp).Copy
.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End If
Next
.Columns(1).RemoveDuplicates 1, xlNo
.Columns(1).Sort Key1:=.Cells(1, 1), order1:=xlAscending, Header:=xlNo
End With

With Sheets("Arbeit").UsedRange
With .Columns(.Columns.Count + 1)
.FormulaR1C1 = "=IF(VLookUp(RC" & sp & ",neu!C1,1,1)=RC" & sp & ",0,Row())"
.Cells(1, 1).Value = 0
.EntireRow.RemoveDuplicates .Column, xlNo
.ClearContents
End With
End With
Sheets("neu").Cells.Clear
End Sub


Gruß Daniel
Anzeige
AW: Makro effizienter machen
14.11.2023 09:46:01
Julian
Hallo Daniel,
Es läuft um einiges schneller, allerdings ist das Ergebnis nicht dasselbe wie mit meinem ineffizienten Makro.
Im Blatt Arbeit sollten am Ende eigentlich um die 98 tausend Ergebnisse stehen, bei deinem Makro steht 1...woran könnte das liegen?

LG

AW: Makro effizienter machen
14.11.2023 10:03:56
daniel
es könnte daran liegen, dass du bei deinem Makro was falsch gemacht hast.
funktionierende Makros sind immer ein Zusammenspiel aus Code und den zu bearbeitenden Daten.
Wie soll ich das beurteilen können, ohne deine Daten und ohne dein Makro zu kennen?
und was bedeutet: "bei deinem Makro steht 1..."
bitte versuche dich in meine Lage zu versetzen und formuliere dein Anliegen so, dass ich es verstehen kann mit den Informationen, die du mir gegeben hast und nicht mit den Informationen die dir vorliegen.
Gruß Daniel
Anzeige
AW: Makro effizienter machen
13.11.2023 18:45:44
Yal
Hallo Julian,

anbei eine andere Variante: Daten in einem Dictionary sammeln und dem ggü prüfen. Bei Vorhandensein wird die boolsche Wert "WAHR" in Spalte "AC" gelegt und alle Zeile mit boolscher Wert in diese Spalte gelöscht (setz voraus, dass in Spalte AC keine andere Zelle mit WAHR/FALSCH als Konstant vorkommt).

Ob damit schneller als Daniels Lösung, zweifle ich. Aber mir macht spass zu tüfeln.

Sub Duplikate_Löschen_mehrere_Arbeitsblätter()

Dim wsh As Worksheet
Dim Dic
Dim Z

Set Dic = CreateObject("Scripting.Dictionary")
'Inhalt der Spalten 100 sammeln
For Each wsh In ThisWorkbook.Worksheets
If wsh.Name > "Arbeit" Then
For Each Z In wsh.UsedRange.Columns(100)
Dic(Z.Value) = 1
Next
End If
Next
'prüfen und löschen
Application.ScreenUpdating = False
Application.EnableEvents = False
With Worksheets("Arbeit").UsedRange.Columns(100)
For Each Z In .Cells
If Dic.Exists(Z.Value) Then Z.Value = True
Next
.SpecialCells(xlCellTypeConstants, 4).EntireRow.Delete
End With
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub


VG
Yal
Anzeige
AW: Makro effizienter machen
14.11.2023 17:31:55
Piet
Hallo Julian

ich biete dir mal meine Idee zum testen an. Ich benutze dafür die WorksheetFunktion Methode.
Ich gehe davon aus das die Duplicate im Sheet "Arbeot" gelöscht werden sollen. Istdas richtig??
Würde mich technisch interessieren ob das schneller ist, und ob es damit klappt???

mfg Piet

Sub Makro1()

With Sheets("Arbeit")
lz1 = .Cells(Rows.Count, "CV").End(xlUp).Row
For k = 2 To lz1
Wert = .Cells(k, "CV").Value
If Application.WorksheetFunction.CountIf(Sheets("Arbeit1").Columns(100), Wert) > 0 Then GoTo Clr
If Application.WorksheetFunction.CountIf(Sheets("Arbeit2").Columns(100), Wert) > 0 Then GoTo Clr
If Application.WorksheetFunction.CountIf(Sheets("Arbeit3").Columns(100), Wert) > 0 Then GoTo Clr
If Application.WorksheetFunction.CountIf(Sheets("Arbeit4").Columns(100), Wert) > 0 Then GoTo Clr
If Application.WorksheetFunction.CountIf(Sheets("Arbeit5").Columns(100), Wert) > 0 Then GoTo Clr
If Application.WorksheetFunction.CountIf(Sheets("Arbeit6").Columns(100), Wert) > 0 Then GoTo Clr
If Application.WorksheetFunction.CountIf(Sheets("Arbeit7").Columns(100), Wert) > 0 Then GoTo Clr
If Application.WorksheetFunction.CountIf(Sheets("Arbeit8").Columns(100), Wert) = 0 Then GoTo Nxt
Clr: .Cells(k, "CV").Value = Empty ' oder "###" in Spalte CV einfügen
Nxt: 'weiter ohne löschen
Next k

For k = lz1 To 2 Step -1
If .Cells(k, "CV").Value = Empty Then
.Rows(k).Delete shift:=xlUp
End If
Next k
End With
End Sub
Anzeige
AW: Makro effizienter machen
14.11.2023 17:44:58
Piet
Nachtrag

wenn es mit WorkshhetFunction klappt kannst du mir For k = lz1 to 2 Step-1 direkt löschen, statt meinen Umweg zu nehmen.

mfg Piet
Noch 'ne Idee
15.11.2023 11:30:24
Yal
Hallo Julian,

hast Du schon mal geschaut, ob diese Verfahren mit Power Query gelöst werden kann?

Einerseits deine Quelle, das Blatt "Arbeit", Menge A,
andersseits die "schon da", die Blätter "Arbeit x", Menge B.
Es geht darum aus der Quelle alles wegzunehmen, was schon vorhanden ist, also eine left outer join: https://blog.codinghorror.com/a-visual-explanation-of-sql-joins/

Mit Power Query wird es nur zusammengeklickt. Siehe Punkt 4 in https://excelhero.de/power-query/power-query-ganz-einfach-erklaert (wobei die andere Videos auch sehr sinnvoll sind)

VG
Yal

Anzeige
AW: Makro effizienter machen
13.11.2023 19:24:13
daniel
Da muss man im Einzelfall prüfen, was schneller ist.
Um das Dictionary zu verstehen, braucht man schon etwas Abstraktionsvermögen.
Ich baue ja Dictionary im Prinzip im neuen Tabellenblatt nach, und verwende nur Methoden, die man in Excel ohne Makro auch anwenden kann.
Ich zeige halt gerne auf, dass man auch mit geringen Programmierkenntnissen schnelle und effiziente Makros schreiben kann, wenn man etwas Excel beherrscht.
I
Gruß Daniel
AW: Makro effizienter machen
14.11.2023 09:09:25
Julian
Vielen Dank an euch beide! Ich werde es mal ausprobieren und melde mich möglichst zeitnah

LG Julian
AW: Makro effizienter machen
13.11.2023 13:35:09
Julian
Ein Array, in dem alle Blätter, bis auf "Arbeit" drin sind. Und dieses Array dann mit dem Blatt "Arbeit" vergleichen. Sorry für das Missverständnis.

LG
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige