Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
976to980
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
976to980
976to980
Aktuelles Verzeichnis
Verzeichnis Index
Verzeichnis Index
Übersicht Verzeichnisse
Inhaltsverzeichnis

Doppelte löschen - klappt nicht

Doppelte löschen - klappt nicht
09.05.2008 23:43:00
Peter
Guten Tag
Ich habe in einem Spaltenbereich rund 400 Zahleneinträge, wovon fast die Hälfte zweimal vorkommt. Ich hatte mal von jemandem eine Hilfestellung erhalten, dass ich die Doppelten löschen kann. Jetzt habe ich versucht, den Code auf die aktuelle Sitation anzupassen, mit dem Ergebnis, dass die Doppelten nicht vollständig gelöscht werden.
Die Tabelle mit den Zahleneinträgen hat den Namen "Vergleich"; der Spaltenbereich, in dem diese stehen ist mit "vValoren" benannt.
Ich habe eine Beispieldatei hochgeladen: https://www.herber.de/bbs/user/52274.xls
Dort ist in der Tabelle "Test" auch ersichtlich, dass bei vollständiger Löschung noch 201 Einträge bleiben würden.
Wer kann mir weiterhelfen?
Danke, Peter
Option Explicit

Public Sub DeleteDuplicatesFilter()
Dim wksData As Worksheet
Dim rngData As Range
Dim nColsCnt As Integer
Dim nRowsCnt As Long
Dim nRow As Long
Dim nRowsDel As Long
Application.ScreenUpdating = False
Set wksData = Sheets("Vergleich")
With wksData
nColsCnt = Range("vValoren").Columns.Count
nRowsCnt = Range("vValoren").Rows.Count
Set rngData = _
.Range(.Cells(Range("vstart").Row, Range("vstart").Column), .Cells(nRowsCnt, nColsCnt))
End With
rngData.AdvancedFilter Action:=xlFilterInPlace, Unique:=True
nRowsDel = 0
For nRow = nRowsCnt To 2 Step -1
With wksData
If .Rows(nRow).Hidden = True Then
.Rows(nRow).EntireRow.Delete
nRowsDel = nRowsDel + 1
End If
End With
Next nRow
If wksData.FilterMode = True Then
wksData.ShowAllData
End If
Application.ScreenUpdating = True
MsgBox "Es wurden " & nRowsDel & " doppelte " & _
"Datensätze gelöscht!", vbOKOnly + vbInformation, _
Title:="Doppelte Datensätze löschen"
Set rngData = Nothing
Set wksData = Nothing
End Sub


9
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Doppelte löschen - klappt nicht
09.05.2008 23:55:00
Heinz
Hi,
in deiner Liste gibt es genau 199 Unikate(Spezialfilter).
mfg Heinz

AW: Doppelte löschen - klappt nicht
10.05.2008 00:00:39
Peter
Hallo Heinz
Das hilft mir leider nicht weiter. Ich sollte wissen, wie mein Code angepasst werden muss, damit zuletzt nur noch Unikate vorhanden sind.
Gruss, Peter

AW: Doppelte löschen - klappt nicht
10.05.2008 00:04:12
Heinz
Hi,
der Makrorekorder hilft dir da weiter, allerdings will der Spezialfilter Überschriften,
damit er richtig funktionieren kann.
mfg Heinz

AW: Doppelte löschen - klappt nicht
10.05.2008 11:14:59
Peter
Guten Tag
Vielleicht bin ich mit meinem Spezialfilter auf der falschen Fährte. Ich habe nun dem Spaltenbereich mit lauter Zahlen, davon eben viele Doppelte eine Überschrift angefügt. Dies hat jedoch auch nicht bewirkt, dass alle doppelten Einträge eliminiert werden. Ich habe dies probiert mir vorhierger Sortierung oder ohne Sortierung. Und die verbleibenden Duplikate sind wirklich gleich. Steht beispielsweise in Zelle B200 und B201 ein zwei gleiche Zahlen, kann ich dies mit =B200=b201 kontrollieren (ergibt Wahrheitswert WAHR). Ein Link zur Beispieldatei steht im Thread mit der ursprünglichen Fragestellung.
Daher nochmals die Frage: Wie kann ich mit VBA am effizientesten bei einem Spaltenbereich mit lauter Zahlen, der beispielsweise mit "AAAA" benannt ist, bei doppelten oder mehrfachen Einträgen soviele entfernen, damit jeder Eintrag nur noch einmal vorkommt? Die erste Zelle von "AAAA" ist keine Überschrift, da der Bereich jedoch auf Zeile 5 beginnt, könnte ich temporär eine überschrift in Zeile 4 vergeben.
Danke für jede Hilfe.
Peter

Anzeige
AW: Doppelte löschen - klappt nicht
10.05.2008 12:57:00
fcs
Hallo Peter,
hier eine etwas andere Lösung.
Gruß
Franz

Public Sub DeleteDuplicates()
Dim wksData As Worksheet
Dim rngData As Range
Dim nRow As Long
Dim nRowsDel As Long
Application.ScreenUpdating = False
Set wksData = Sheets("Vergleich")
Set rngData = wksData.Range("vValoren")
'Inhalte von Zellen mit doppelten Einträge in Spalte 1 des Bereichs löschen
nRowsDel = 0
For nRow = 1 To rngData.Rows.Count
If Application.WorksheetFunction.CountIf(rngData.Columns(1), _
rngData(nRow, 1)) > 1 Then
rngData(nRow, 1).ClearContents
nRowsDel = nRowsDel + 1
End If
Next nRow
'Zeilen mit leeren Zellen im Datenbereich Spalte 1 löschen
rngData.Columns(1).SpecialCells(xlCellTypeBlanks).EntireRow.Delete Shift:=xlShiftUp
'Tabellen-Zeilen nach Datenbereich Spalte 1 sortieren
rngData.EntireRow.Sort key1:=rngData(1, 1), Order1:=xlAscending, header:=xlNo
Application.ScreenUpdating = True
MsgBox "Es wurden " & nRowsDel & " doppelte " & _
"Datensätze gelöscht!", vbOKOnly + vbInformation, _
Title:="Doppelte Datensätze löschen"
Set rngData = Nothing
Set wksData = Nothing
End Sub


Anzeige
AW: Doppelte löschen - die Effizienteste Methode
10.05.2008 13:50:56
Daniel
Hallo
die effizienteste Methode, Doppelte aus eine Datenreihe zu eleminieren ist folgende:
1. Datenreihe sortieren, so daß Doppelte direkt untereinander stehen
2. in Hilfsspalte per Wennformel die zu löschenendn Daten kennzeichnen (zu löschende erhalten einen Wahrheitswert, die anderen eine Zahl, z.B. die Zeilennr
3. Daten nach Hilfsspalte sortieren
4. in der Hilfsspalte per BEARBEITEN - GEHE ZU - INHALTE - KONSTANTEN - WAHRHEITSWERTE die zu löschenden Datensätze markieren und löschen.
im Prinzip würde das ganze auch ohne Sortieren funktionieren, aber dann gäbe es irgendwann bei grossen Datenmengen Probleme und vorallem ist die Verarbeitungsgeschwindigkeit in sortierten Daten erheblich grösser, weil schnellere Formeln verwendet werden können (Zellvergleich anstelle von ZählenWenn) und auch das Löschlen eines zusammenhängenen Zellblocks schneller ist als das Löschen von vereinzelten Zellen.
so hier jetzt der Code für dein Beispiel:
ich habe noch eine Weitere Hilfsspalte eingefüht, so daß die Daten wieder in die Original-Reihenfolge zurücksortiert werden.

Sub Doppelte_Löschen()
Dim Z1 As Long, Z2 As Long, SP As Long
Z1 = Range("vstart").Row
Z2 = Range("vende").Row
SP = Range("vstart").Column
'--- Hilfsspalten einfügen und Original-Reihenfolge sichern
Range("A:B").Insert
With Range(Cells(Z1, 1), Cells(Z2, 1))
.FormulaR1C1 = "=Row()"
.Formula = .Value
End With
'--- Doppelte kennzeichnen und löschen
With Range(Cells(Z1, 2), Cells(Z2, 2))
.EntireRow.Sort key1:=Cells(Z1, SP + 2), order1:=xlAscending, header:=xlNo
.FormulaR1C1 = "=IF(RC[" & SP & "]=R[-1]C[" & SP & "],TRUE,RC[-1])"
.Formula = .Value
.EntireRow.Sort key1:=Cells(Z1, 2), order1:=xlAscending, header:=xlNo
.SpecialCells(xlCellTypeConstants, 4).EntireRow.Delete
End With
'--- Aufräumen
Range("A:B").Delete
End Sub


Gruß, Daniel
btw bei grossen Datenmengen (so 10.000 Zeilen und mehr), ist man mit der oben beschriebenen Methode von Hand (dh. ohne Makrounterstützung) u.U. schneller als ein ineffizient geschriebenes Makro (z.B. eines, das die Daten per Schleife von Hand einzeln prüft und löscht)

Anzeige
AW: Doppelte löschen - die Effizienteste Methode
11.05.2008 12:51:00
fcs
Hallo Daniel,
deine Prozedur ist wirklich superschnell.
Bei ca. 10000 Datenzeilen mit 98 % doppelten Einträgen benötigt mein Vorschlag auf meinem 8 Jahre alten Notebook (Win98, Office97, Pentium 3, 128 MB Arbeitsspeicher) ca. 100 Sekunden, deine Prozedur ca. 2 bis 3 .
Ich hatte dann meine Prozedur etwas optimiert:
Daten sortieren und dann in einer Schleife Werte vergleichen und doppelte Zellinhalte löschen.
Zum Schluss in einer Anweisung die Zeilen mit leeren Zellen löschen.
Das brachte mich je nach Anzahl der Doppelten runter auf 2 bis 10 Sekunden.
Ich hab dann von dir die Strategie übernommen, alle Hilfsberechnungen direkt in der Tabelle zu machen, und das Ganze zu einer Function umgebaut, die mit Parametern aufgerufen wird. Das funktioniert jetzt super.
Gruß
Franz

Sub DoppelteLoeschen_vValoren()
Dim varMeldung As Variant
varMeldung = DuplikateLoeschen(objWks:=Worksheets("Vergleich"), _
strBereich:="vValoren", bolSort:=True, bolMeldung:=True)
If varMeldung = "" Then
'do nothing
Else
MsgBox varMeldung
End If
End Sub
Sub DoppelteLoeschen_Selektion()
'Zeilen mit doppelten Einträgen in linker Spalte des selektierten Bereichs löschen
Dim varMeldung As Variant, bolSort As Boolean
varMeldung = MsgBox(Prompt:="Soll die vorhandene Sortierung der Zeilen " _
& "beibehalten werden?" _
& vbLf & vbLf & "Bei NEIN wird nach der Spalte mit den Duplikaten sortiert.", _
Buttons:=vbYesNoCancel + vbQuestion, _
Title:="Doppelte Datensätze löschen - in Selektion")
Select Case varMeldung
Case vbYes:     bolSort = True
Case vbNo:      bolSort = False
Case vbCancel:  GoTo Weiter01
End Select
varMeldung = DuplikateLoeschen(objWks:=ActiveSheet, _
strBereich:=Selection.Address, _
bolSort:=bolSort, _
bolMeldung:=True)
If varMeldung  "" Then
MsgBox varMeldung
End If
ActiveCell.Select
Weiter01:
End Sub
Public Function DuplikateLoeschen(objWks As Worksheet, strBereich As String, _
Optional bolSort As Boolean = False, _
Optional bolMeldung As Boolean = False) As String
'Tabellen-Zeilen mit Duplikaten in der 1. Spalte des Bereiches entfernen
'objWks     = Tabellenblatt in dem die Doppelten entfernt werden sollen
'strBereich = Bereichsname oder Zellbereich
'bolSort    = True:  Sortierung der Daten in der Tabelle bleibt erhalten _
False: Tabelle wird nach der Duplikate-Spalte sortiert
'bolMeldung = True:  Meldung über Anzahl gelöschte Zeilen wird angezeigt _
False: Meldung wird nicht angezeigt
Dim rngData As Range
Dim rngSort As Range
Dim rngVergleich As Range
Dim nRowsDel As Long
Application.ScreenUpdating = False
On Error GoTo Fehler
With objWks
'Duplikate-Bereich setzen
Set rngData = .Range(strBereich)
If rngData.Rows.Count = 1 Then
MsgBox "Der Datenbeich enthält nur eine Zeile, keine Doppelten möglich."
GoTo Beenden
ElseIf Application.WorksheetFunction.CountA(rngData.Columns(1)) = 0 Then
MsgBox "Der Datenbereich enthält keine Daten!"
GoTo Beenden
End If
'2 Hilfs-Spalten links von Spalte A einfügen
.Range(.Columns(1), Columns(2)).Insert shift:=xlShiftToRight
End With
If bolSort = True Then
Set rngSort = rngData.Columns(1).Offset(0, -rngData.Column + 1)
'Formel für Zeilenummer in Sotierbereich einfügen
rngSort.Formula = "=ROW()"
'Formel duch Werte ersetzen
rngSort.Value = rngSort.Value
End If
'Tabellen-Zeilen nach Duplikatespalte sortieren
With rngData
.EntireRow.Sort key1:=.Cells(1, 1), order1:=xlAscending, header:=xlNo
End With
'Bereich in 2. Spalte für Vergleich definieren
Set rngVergleich = rngData.Columns(1).Offset(0, -rngData.Column + 2)
'Formel für Zeilenvergleich einfügen, dann durch Werte ersetzen
With rngVergleich
If rngData.Row = 1 Then
'Sonderfall Datenbereich beginnt in 1. Zeile, Vergleichsformel nicht möglich
.Cells(1, 1).Value = rngSort.Cells(1, 1).Value
With objWks.Range(objWks.Cells(2, .Column), objWks.Cells(.Rows.Count, .Column))
.FormulaR1C1 = "=IF(RC" & rngData.Column & "=R[-1]C" _
& rngData.Column & ",TRUE,RC[-1])"
End With
Else
.FormulaR1C1 = "=IF(RC" & rngData.Column & "=R[-1]C" _
& rngData.Column & ",TRUE,RC[-1])"
'Sonderfall Zelle oberhalb Selektion ist identisch mit 1. Wert der Selektion
If rngData.Cells(1, 1).Value = rngData.Cells(1, 1).Offset(-1, 0).Value Then
.Cells(1, 1).Value = rngSort.Cells(1, 1).Value
End If
End If
.Value = .Value
'Anzahl Zeilen vor dem Löschen
nRowsDel = objWks.Cells(objWks.Rows.Count, .Column).End(xlUp).Row
'Zeilen mit Wert WAHR in Vergleichsspalte löschen
'Tabellenzeilen nach Vergleichsspalte sortieren (Sortiert zu löschende ans Ende)
.EntireRow.Sort key1:=.Cells(1, 1), order1:=xlAscending, header:=xlNo
'Letzten Eintrag in Vergleichsspalte prüfen und ggf. Zeilen löschen
If objWks.Cells(objWks.Rows.Count, .Column).End(xlUp).Value = True Then
.SpecialCells(xlCellTypeConstants, 4).EntireRow.Delete shift:=xlShiftUp
End If
'Anzahl gelöschte Zeilen
nRowsDel = nRowsDel - objWks.Cells(objWks.Rows.Count, .Column).End(xlUp).Row
End With
If bolSort = True Then
'Tabellen-Zeilen wieder in alte Reihenfolge sortieren
With rngSort
.EntireRow.Sort key1:=.Cells(1, 1), order1:=xlAscending, header:=xlNo
End With
Else
'Tabellen-Zeilen nach Duplikate-Spalte sortieren
With rngData
.EntireRow.Sort key1:=.Cells(1, 1), order1:=xlAscending, header:=xlNo
End With
End If
'Hilfsspalten wieder löschen
With objWks
.Range(.Columns(1), .Columns(2)).Delete shift:=xlShiftToLeft
End With
If bolMeldung = True Then
MsgBox Prompt:="Es wurden " & nRowsDel & " doppelte Datensätze gelöscht!", _
Buttons:=vbOKOnly + vbInformation, _
Title:="Doppelte Datensätze löschen"
End If
DuplikateLoeschen = ""
GoTo Beenden
Fehler:
DuplikateLoeschen = "Fehler bei Ausführung der Prozedur ""DuplikateLöschen""" _
& vbLf & vbLf _
& "Fehler Nummer: " & Err.Number & vbLf & Err.Description
If Not rngSort Is Nothing Then
'Hilfsspalten wieder löschen
With objWks
.Range(.Columns(1), .Columns(2)).Delete shift:=xlShiftToLeft
End With
End If
Beenden:
Set rngData = Nothing: Set rngSort = Nothing: Set rngVergleich = Nothing
Application.ScreenUpdating = True
End Function


Anzeige
AW: Doppelte löschen - klappt nicht
10.05.2008 23:01:53
Peter
Hallo Franz und Daniel
Ganz grossen Dank für eure Hilfe. Ich habe beide Lösungsvorschläge ausgetestet und es hat auf Anhieb geklappt! Bei meiner Datenmenge ist im Moment noch kein Zeitunterschied bei der Ausführung erkennbar.
Freundlicher Gruss, Peter

Doppelte Werte per VBA löschen
11.05.2008 09:58:52
NoNet
Hallo Peter,
eigentlich finde ich die Idee, dafür den Spezilfilter einzusetzen gar nicht schlecht.
Wenn dies aus irgendeinem Grund nicht funktioniert, dann teste doch mal folgende einfache Variante :


Sub DoppelteWerteLoeschen()
    'Löscht doppelteWerte aus einem Bereich mit Namen "Zahlen"
    '11.0.2008, NoNet - www.excelei.de
    Dim rngZelle As Range
    For Each rngZelle In Range("Zahlen")
        If Application.WorksheetFunction.CountIf(Range("Zahlen"), rngZelle.Value) > 1 Then
            rngZelle.EntireRow.Delete
        End If
    Next
End Sub

Der Bereich "Zahlen" sollte sich dabei nur auf 1 Spalte beziehen.
Diese Variante ist zwar nicht die Schnellste aber eine der einfachsten und sie sollte funktionieren.
Gruß, NoNet
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige