Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1908to1912
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
Doppelte Zeilen löschen
09.12.2022 12:54:57
Hilmar
Hallo liebes Forum, ich brauche bitte euere Hilfe. Ich habe ein Makro, welchen auch das macht, was es soll. Ich möchte es aber gerne erweitern. Beim löschen der doppelten Einträge möchte ich nicht nur den doppelten, sondern auch den ersten Eintrag löschen. Kann mir jemand helfen? Vielen Dank im voraus.
Hier mein Makro

Sub DoppelteZeilenEntfernen_D()
Dim LetzteZeile As Long
Dim Zeile As Long
LetzteZeile = Range("D" & Rows.Count).End(xlUp).Row
For Zeile = LetzteZeile To 1 Step -1
If WorksheetFunction.CountIf(Range("D1:D" & Zeile), Range("D" & Zeile)) > 1 Then
Rows(Zeile).EntireRow.Delete
End If
Next
End Sub

24
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Doppelte Zeilen löschen
09.12.2022 13:04:18
Daniel
Hi
wenn du alle Duplikatszeilen löschen willst inklusive der ersten, dann musst du zuerst die Duplikate markieren und erst danach löschen.
kombinerst du Suchen mit Löschen zu einem Vorgang, ist ja die letzte Zeile kein Duplikat mehr.
so für kleine Datenmengen:

with activeSheet.Usedrange
with .columns(.columns.count + 1)
.FormulaR1C1 = "=IF(CountIf(C4,RC4)>1;1;"""")"
.Formula = .Value
if Worksheetfunction.Sum(.Cells) > 0 then .SpecialCells(xlcelltypeconstants, 1).EntireRow.Delete
end with
end with
solltest du sehr viele Zeilen haben (ab 5-stellig), kann man den Vorgang auch etwas anders durchführen, dies erfordert aber eine Umsortierung der Daten.
Gruß Daniel
Anzeige
AW: Doppelte Zeilen löschen
09.12.2022 13:29:05
Hilmar
Danke für die schnelle Antwort. Leider funktioniert es nicht. Hab es kopiert und eingefügt.
AW: Doppelte Zeilen löschen
09.12.2022 13:54:03
Daniel
kopieren und einfügen ist immer schlecht.
da übernimmst du meine Fehler (die ich häufig mache, weil ich den Code direkt ins Forum schreibe und nicht erst in eine Exceldatei) und du kannst dabei noch eigene Fehler zusätzlich einbauen.
Daher ist der bessere Weg immer:
1. Lesen
2. Verstehen (ggf Punkt 1 hierzu mehrfach wiederholen)
3. Selber programmieren
und wenns dann nicht funktioniert, dann hier nochmal nachfragen.
Beachte aber zwei Punkte, wenn du von uns Hilfe möchtest.
1. Zeige uns, was du gemacht hast. Wenn wir dir sagen sollen. was falsch ist, müssen wir genau wissen, was du gemacht hast. Wenn wir das sehen, wissen wir es genau. Wenn du nur sagst, "ich habe es so gemacht, wie du es beschrieben hast", dann ist das zu ungenau. Das ist so wie in der Seefahrt der Unterschied zwischen Navigation mit GPS und Koppelnavigation mit Kompass und geschätzter Gewschwindigkeit
2. wenns nicht funktionert, dann muss sich das irgendwie bemerkbar machen (Fehlermeldung, falsches Ergebnis). Beschreibe uns dies bitte so genau wie möglich.
"Funktioniert nicht" ist für uns bei der Problemlösung ungefähr so hilfreich wie für dich "dann machs anders" als Hilfestellung.
Gruß Daniel
Anzeige
AW: Doppelte Zeilen löschen
09.12.2022 14:05:05
Hilmar
Sorry wenn ich mich nicht richtig ausgedrückt habe, keine Absicht. Ich habe mal die Datei hochgeladen. Es sollen im Makro die roten und identischen grünen Zeilen gelöscht werden. Vielleicht kommt ihr der Lösung so näher. Danke
https://www.herber.de/bbs/user/156625.xlsm
AW: Doppelte Zeilen löschen
09.12.2022 14:11:59
Daniel
also ein Fehler, den ich so in meinem Beitrag gesehen habe ist, dass ich in der Formel ein Paar mal das deutsche Parametertrennzeichen verwendet habe (;) und nicht durchgängig das englischen (,). Da die Formel hier auf Englisch angegeben werden muss, muss man natürlich auch immer das Komma verwenden.
vielleicht korrierst du das noch.
Außerdem sehe ich in der Datei nur deinen alten Code, aber noch nicht den, den du mit meiner Hilfe versucht hast.
Wie kannst du dann wissen, dass es nicht funktioniert, wenn du es noch gar nicht programmiert hast?
(nur so als Tipp: Helfer achten schon darauf, ob das, was sie sagen zumindest mal ausprobiert und nicht ignoriert wird)
Gruß Daniel
Anzeige
AW: Doppelte Zeilen löschen
09.12.2022 14:27:41
Hilmar
Entschuldigung, selbstverständlich habe ich es ausprobiert und nicht ignoriert. Ich werde es erneut mit den Änderungen ausprobieren.
Hilmar
AW: Doppelte Zeilen löschen
09.12.2022 15:01:39
Hilmar
Daniel, es funktioniert. Ich hatte Deinen Teil einfach an die falsche Stelle kopiert. Ich entschuldige mich nochmals. Vielen vielen Dank.
Hilmar
AW: Doppelte Zeilen löschen
09.12.2022 15:20:36
Daniel
Schön, danke für die Rückmeldung.
Ich hoffe du verstehst, dass ich diesen Fehler nicht erkennen kann, wenn du mir nicht die Datei mit dem Makro zeigst.
Gruß Daniel
AW: Doppelte Zeilen löschen
16.12.2022 09:59:31
Hilmar
Hallo Daniel, ich habe noch eine Bitte zu dem Makro, wobei Du mir geholfen hast. Es funktioniert genau so, wie es soll. Jetzt habe ich aber festgestellt, dass Einträge nicht nur doppelt, sondern mehrfach vorkommen. Z.B. 4x. Ich möchte dann alle mehrfachen Einträge löschen. Kannst Du bitte noch mal helfen? Brauchst Du weitere Informationen?
Gruß
Hilmar
Hier das Makro

Sub DoppelteZeilenEntfernen_D()
With ActiveSheet.UsedRange
With .Columns(.Columns.Count + 1)
.FormulaR1C1 = "=IF(CountIf(C4,RC4)>1,1,"""")"
.Formula = .Value
If WorksheetFunction.Sum(.Cells) > 0 Then .SpecialCells(xlCellTypeConstants, 1).EntireRow.Delete
End With
End With
Dim LetzteZeile As Long
Dim Zeile As Long
LetzteZeile = Range("D" & Rows.Count).End(xlUp).Row
For Zeile = LetzteZeile To 1 Step -1
If WorksheetFunction.CountIf(Range("D1:D" & Zeile), Range("D" & Zeile)) > 1 Then
Rows(Zeile).EntireRow.Delete
End If
Next
End Sub

Anzeige
AW: Doppelte Zeilen löschen
16.12.2022 17:52:40
Hilmar
Vielen Dank Yal, damit komme ich klar.
AW: Doppelte Zeilen löschen
09.12.2022 13:31:58
Steffen
Hallo,
um den ersten Eintrag ebenfalls zu löschen, kannst du den Schleifenrückwärtszähler (Variable "Zeile") auf 2 setzen. Dann wird die Schleife erst bei Zeile 2 gestartet und somit wird auch der erste Eintrag überprüft und gegebenenfalls gelöscht:

Sub DoppelteZeilenEntfernen_D()
Dim LetzteZeile As Long
Dim Zeile As Long
LetzteZeile = Range("D" & Rows.Count).End(xlUp).Row
For Zeile = LetzteZeile To 2 Step -1 'hier wurde der Schleifenrückwärtszähler auf 2 gesetzt
If WorksheetFunction.CountIf(Range("D1:D" & Zeile), Range("D" & Zeile)) > 1 Then
Rows(Zeile).EntireRow.Delete
End If
Next
End Sub

Anzeige
AW: Doppelte Zeilen löschen
09.12.2022 14:30:02
Hilmar
Danke für Deine Antwort. Leider ist zu meinem Makro trotz Änderung der Schleife kein unterschied.
Hilmar
Das ist nicht nur nicht richtig; es ist ...
09.12.2022 15:48:21
EtoPHG
nicht einmal falsch! Wolfgang Pauli
Es gibt in der realen Welt offensichtlich eine Steigerungsform von falsch
Gruess Hansueli
AW: Doppelte Zeilen löschen
09.12.2022 16:21:46
Daniel
das ändert nichts am Grundproblem.
wenn du alle Zeilen einer Duplikatsgruppe löschen willst, darfst du nicht jede Zeile einzeln prüfen und dann sofort löschen.
Denn wenn du das vorletzte Element einer Gruppe gelöscht hast, ist das letzte Element kein Duplikat mehr, bzw kann nicht mehr als solches erkannt werden und wird dann nicht mehr gelöscht.
Hier hilft nur, die beiden Vorgänge "Duplikat erkennen" und "Zeilen löschen" zu trennen und erst alle Duplikate zu suchen und zu markieren, um anschließend dann das Löschen durchzuführen.
Gruß Daniel
Anzeige
AW: Doppelte Zeilen löschen
09.12.2022 17:17:13
Yal
Hä! ich möchte auch mitmachen ;-)
Schon mehrfach beantwortet, aber ich hatte schon was entworfen, wurde aber unterbrochen:

Sub DoppelteZeilen_entfernen()
Dim Dic As Object
Dim Z 'Z wie Zelle
Dim Elt
Dim Liste
Set Dic = CreateObject("Scripting.Dictionary")
'Sammeln, von unten anfangen (wie Bodenwischen: zurück zum Tür)
For Z = Cells(Rows.Count, "D").End(xlUp).Row To 1 Step -1
If Dic.exists(Cells(Z, "D").Value) Then
Dic(Cells(Z, "D").Value) = Dic(Cells(Z, "D").Value) & " " & Z
Else
Dic(Cells(Z, "D").Value) = CStr(Z)
End If
Next
'löschen, wenn mehr als Zwei Einträge gibt
For Each Elt In Dic.Items
Liste = Split(Elt)
If UBound(Liste) >= 1 Then
For Each Z In Liste
Cells(Z, 1).EntireRow.Delete
Next
End If
Next
Set Dic = Nothing
End Sub
VG
Yal
Anzeige
Gerne
09.12.2022 17:35:24
Daniel
Aber vielleicht könntest du kurz erläutern, warum man deinen Code verwenden sollte, wenn sich die Aufgabe auch mit 3 kurzen, auch für den VBA-Anfänger verständlichen, Codezeilen (effektiver code) lösen lässt?
Wenn mehrere Wege zum Ziel führen, ist es ja immer hilfreich zu wissen, wann, in welcher Situation und warum die eine Lösung besser ist als die andere.
Gruß Daniel
AW: Gerne
09.12.2022 18:12:12
Yal
Hallo Daniel,
da hast Du recht. Mein Code ist weder besser noch geeigneter, noch "muss" er genutzt werden. Mehr als die Lösung selbst geht es mir um irgendeine Beschäftigung, um die Zeit einigermassen spassig zu vertreiben. Es ist nur eine Spielerei mit Excel-Möglichkeiten, die vielleicht den Fragenden überfordert, aber vielleicht einige Leute, die irgendwann auf diesem Beitrag zustossen (das Netz vergisst nie) inspirieren könnte.
Was ich gemacht habe: ich sammle die Einträge in einem Dictionary, das die Besonderheit hat, dass die Schlüssel eindeutig sein muss: kommt eine Werte in Spalte D ein zweite mal vor, muss die Zeilennummer an der Liste der vorhandenen hinzugefügt.
Anschliessend wird geprüft, in welche gesammelten mehr als ein Zeile vorkommt, dann jede Zeile gelöscht.
Auf einer Hilfspalte wird damit verzichtet.
Es wird "von unten" aufgebaut, weil beim Zeilen/Spalten-Löschen kann man nicht die 10te nach der 9te löschen, weil es dann nicht mehr die 10te ist. Mein erster Versuch von oben aufzubauen und dafür das Dictionary rückwärts zu lesen, war grauenhaft.
VG
Yal
Anzeige
AW: Gerne
09.12.2022 18:31:31
Daniel
"Fingerübung, um den Umgang mit Dictionarys an einem einfachen Beispiel zu zeigen" ist doch ein guter Grund, einen Code zu schreiben ;-)
ja, viele möchten Hilfsspalten gerne vermeiden.
Allerdings sind sie oft sehr hilfreich, wenn es darum geht, Codes bei großen Datenmengen zu beschleunigen.
Ohne Hilfsspalte musst du jede Zeile einzeln löschen.
Das Löschen einer einzelnen Zeile ist für Excel ein sehr zeitaufwendiger Vorgang (da hilft auch kein "GetMoreSpeed", weil dahinter Aktionen stecken, die sich nicht ausschalten lassen, sondern auf anderen Wegen vermieden werden müssen)
Wenn also viele Zeilen einzeln gelöscht werden, dauert das sehr lang.
Vorteilhaft ist, wenn man Zeilen nicht einzeln löscht, sondern als Block, denn das löschen von 1000 Zeilen als lückenloser Block in einem Schritt (Rows("1:1000")) dauert genauso lange wie das Löschen einer einzigen Zeile, weil Excel die Hintergrundaufgaben dann für alle Zeilen gemeinsam abarbeiten kann (ist wie beim Brötchen kaufen, ob du ein Brötchen oder eine Tüte mit 10 Brötchen kaufst, ist kein Unterschied, aber wenn du 10x zum Bäcker fährst um 10 Brötchen zu kaufen, dann schon.
ein Hilfsspalte würde dir die Möglichkeit geben, die Tabelle vor dem Löschen der Zeilen so umzusortieren, dass alle zu löschenden Zeilen direkt untereinander stehen, so dass du alle gemeinsam löschen kannst, was die sache extrem beschleunigt wenn die Liste lang ist.
Es spricht aber nichts dagegen, beispielsweise Hilfsspalte und Dictionary zu kombinieren und die Duplikatsprüfung über das Dictionary zu machen und dann die Hilfsspalte zum markieren und sortieren über das Dictionary zu erzeugen, denn das wiederum sollte wesentlich schneller sein als eine Duplikatsprüfung mit ZählenWenn.
klar, bei kleinen Listen ists egal, aber wenn die Zeilenanzahl mal 6-Stellig wird, muss man zu solchen Tricks greifen, damit der Excelprofi nicht denkt: "das mach ich von Hand schneller als dein Makro"
Gruß Daniel
Anzeige
AW: Gerne
09.12.2022 18:52:30
Yal
Ich hätte selber den Zählenwenn per Hand getippt, die Zeilen gefiltert, gelöscht, entfiltert. Fertig.
Aber wie der Programmierer sagt: nicht selber machen, was der Computer besser machen kann.
VG
Yal
AW: Gerne
09.12.2022 19:08:53
Daniel
ja, kann man machen.
bei großen Datenmengen ist aber ZählenWenn zu langsam, weil jeder Wert mit jedem anderen Wert verglichen werden muss, dh Aufwand = Anzahl * Anzahl
hier muss man mindestens einmal sortieren, nämlich nach der Spalte mit den Duplikaten, so dass gleichen Werte direkt untereinander stehen
dann reicht für die Duplikatsprüfung die Abfrage, ob der Wert gleich dem Wert obendrüber oder gleich dem Wert unten drunter ist, dh man muss ihn nicht mehr mit allen anderen Werten der Liste vergleichen sondern nur mit seinen beiden Nachbarn, dh Aufwand = Anzahl*2
außerdem hat man das ganze dann schon mal so vorsortiert, so dass sich die Anzahl der zu löschenden Einzelzeilen reduziert und man mehr zusammenhängende Blöcke hat.
wenns ganz ohne Umsortierung sein soll (was für mache wichtig ist), dann könnte man, so wie ich beschrieben habe, Dictionarys einsetzen um die Duplikate zu identifizieren und dann das Duplikate entfernen, um die Duplikate zu löschen.
hier mal ein Codebeispiel dafür:

Sub Doppelte_Ganz_Löschen()
Dim arr
Dim dic As Object
Dim z As Long
Set dic = CreateObject("Scripting.dictionary")
arr = ActiveSheet.UsedRange.Columns(4)
'--- Duplikate finden
For z = 1 To UBound(arr, 1)
dic(arr(z, 1)) = dic(arr(z, 1)) + 1
Next
'--- Duplikate zum löschen markieren
For z = 1 To UBound(arr, 1)
arr(z, 1) = IIf(arr(z, 1) = 1, z, 0)
Next
'--- Duplikate in Tabelle löschen
arr(1, 1) = 0
With ActiveSheet.UsedRange
With .Columns(.Columns.Count + 1)
.Value = arr
.EntireRow.RemoveDuplicates .Column, xlNo
.ClearContents
End With
End With
End Sub
um Zeilen mit Duplikate Entfernen zu löschen, ist es erforderlich, dass die erste Zeile eine Überschriftenzeile ist und keine Datenzeile, da die erste Zeile prinzipbedingt nicht gelöscht werden kann.
Gruß Daniel
upsi fehler gemacht
09.12.2022 19:14:19
Daniel
eigentlich hatte ich zum markieren einen richtigen IF-Block, den ich dann durch ein IIF ersetzt habe (Weniger Zeilen)
der muss natürlich so lauten:

'--- Duplikate zum löschen markieren
For z = 1 To UBound(arr, 1)
arr(z, 1) = IIf(dic(arr(z, 1)) = 1, z, 0)
Next
Gruß Daniel
AW: Gerne
11.12.2022 13:03:54
Yal
Hmm... Hat man hier nicht das Problem, dass der Zugriff auf einem Dictionary-Eintrag dessen Schlüssel nicht existiert einen Fehler verursacht?

 '--- Duplikate finden
For z = 1 To UBound(arr, 1)
dic(arr(z, 1)) = dic(arr(z, 1)) + 1
Next
Darum habe immer zuerst getestet, ob der Schlüssel existiert.
VG
Yal
AW: Gerne
11.12.2022 13:22:59
Daniel
Hi
Nein, das Problem hat man hier nicht.
Ein Dictionary-Element muss nicht explizit angelegt werden, dass passiert automatisch bei der ersten Verwendung.
Die Abfrage auf If dic(key).Exists braucht man dann nur, wenn man prüfen will, ob der Key vorhanden ist ohne ihn dabei zu anzulegen, oder wenn der beim automatischen Anlegen erzeugte Item-Wert (als zahl 0, als Text "") die Auswertung verfälschen könnte.
Dh wenn man beispielsweise MinWenn durch ein Dictionray berechnen will, dann sollte man das tun, weil sonst immer die 0 das Ergebnis sein wird (nur positive Werte in der Gruppe)
Will man ein SummeWenn oder ZählenWenn mit Dictionary darstellen, dann braucht man das nicht, weil die 0 des automatisch erstellten Erstwertes nicht stört.
Daher kann man das hier weglassen.
Gruß Daniel

300 Forumthreads zu ähnlichen Themen

Anzeige
Anzeige
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige