Prüfe ob Werte Identisch sind, WENN WAHR dann lösche Zeile...

  • Excel

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von ereza.

    Prüfe ob Werte Identisch sind, WENN WAHR dann lösche Zeile...

    Hallo liebe Community...

    Ich möchte gerne folgendes machen...

    Excel soll folgendes tun:

    1.) Prüfe ob Zelle leer ist
    2.) Wenn Zelle leer ist führe Aktionen ab 3.) aus, Wenn Zelle NICHT leer ist, beende IF-Abfrage
    3.) (Bedinung: Zelle ist leer) Prüfe ob aktuelle Zeile und darauffolgende Zeile IDENT sind, vom Inhalt her.
    4.) Wenn Zeilen komplett ident sind, gehe von aktueller Zeile zu der darauffolgenden Zeile, und Lösche diese Zeile / Wenn nicht IDENT, beende IF-Abfrage...


    also im code sollte das nun so aussehen (Code + Pseudocode...):


    Visual Basic-Quellcode

    1. Dim a As Long
    2. Dim b As Long
    3. For a = 2 To Cells(Rows.Count, 1).End(xlUp).Row
    4. b = a+1
    5. IF Cells(a, 5).Value = "" THEN
    6. IF Cells(a,1).Value = Cells(b,1).Value AND Cells(a,2).Value = Cells(b,2).Value AND Cells(a,3).Value = Cells(b,3).Value AND Cells(a,4).Value = Cells(b,4).Value AND Cells(a,5).Value = Cells(b,5).Value AND Cells(a,5).Value = Cells(b,5).Value AND Cells(a,5).Value = Cells(b,5).Value AND Cells(a,6).Value = Cells(b,6).Value AND Cells(a,7).Value = Cells(b,7).Value AND Cells(a,9).Value = Cells(b,9).Value AND Cells(a,11).Value = Cells(b,11).Value AND Cells(a,13).Value = Cells(b,13).Value THEN
    7. .Rows(b).Delete
    8. ELSE END IF
    9. Else
    10. End If
    11. Next
    12. End Sub



    Kann das so funktionieren??

    Vor allem... es soll irrelevant sein ob der Inhalt einer Zelle ein Text oder eine Zahl ist... die einzige Gegebenheit bzw.Vorkommen ist, dass der Inhalt einer Zelle (x,y) immer gleich vom Format her ist, wie die darauffolgende Zelle (x+1,x+1)!

    Könnt ihr mir bitte mit der Synthax a bissl helfen, dass mein Code richtig ist und funktioniert...??

    Vielen Dank!

    LG Tim
    Das macht man wenn dann in einer Schleife:

    Visual Basic-Quellcode

    1. IF Cells(a, 5).Value = "" THEN
    2. dim col as integer, del as boolean
    3. del = True
    4. For col = 1 To 13
    5. If cells(a,col).value <> cells(b,col).value then
    6. del = False
    7. exit for
    8. End if
    9. Next
    10. If del then .Rows(b).Delete
    11. End if


    Die Frage ist nur, kann es auch 3 oder 4 idente Zeilen geben ? Das wäre dann nicht berücksichtigt.
    Das ist meine Signatur und sie wird wunderbar sein!

    ereza schrieb:

    For a = 2 To Cells(Rows.Count, 1).End(xlUp).Row
    wird nicht funktionieren, da du nach dem ersten Löschen den Zeilenindex durcheinander wirbelst.
    In dem Fall rückwarts laufen:
    For a = Cells(Rows.Count, 1).End(xlUp).Row To 2 Step -1

    ereza schrieb:

    Prüfe ob aktuelle Zeile und darauffolgende Zeile IDENT sind
    Meinst du die ganze Zeile oder nur bestimmte Zellen in der Zeile.
    Falls du die ganze Zeile meinst, hätte ich einen Vorschlag:

    Visual Basic-Quellcode

    1. Sub DeleteDuplicates()
    2. Dim r As Long
    3. For r = Cells(Rows.Count, 1).End(xlUp).Row To 2 Step -1
    4. If Cells(r, 5).Value = "" Then If CompareRows(Rows(r), Rows(r - 1)) Then Rows(r).Delete
    5. Next
    6. End Sub
    7. Function CompareRows(ByVal Range1 As Range, ByVal Range2 As Range) As Boolean
    8. CompareRows = Join(Application.Transpose(Application.Transpose(Range1.Value)), Chr(0)) = Join(Application.Transpose(Application.Transpose(Range2.Value)), Chr(0))
    9. End Function
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Hi Petaod.

    In VBA in Excel läuft er trotzdem bis zur letzten Zeile, auch wenn du zwischendrin eine löschst. Der Wert wird anfangs berechnet und dann ist er fix. Und deine Lösung ist elegant aber ohne Erklärung?
    In jedem Fall ist Sie höchstwahrscheinlich deutlich unperformanter als eine kleine Schleife ^^
    Als Test:

    Visual Basic-Quellcode

    1. Sub ForTest()
    2. Dim a As Integer, f As Integer, g As Integer
    3. f = 3
    4. g = 4
    5. Debug.Print ("Start: " & CStr(f + g))
    6. For a = 0 To f + g
    7. If a = 1 Then g = 1
    8. Debug.Print ("Schleifezähler: " & CStr(a))
    9. Debug.Print ("End: " & CStr(f + g))
    10. Next
    11. End Sub

    LG
    Das ist meine Signatur und sie wird wunderbar sein!
    Das Problem ist, dass sich beim Delete die Tabelle verschiebt.

    Wenn du die Zellen A1:A10 mit Zahlen von 1 bis 10 füllst und dann folgenden Code ausführst:

    Visual Basic-Quellcode

    1. Sub ForTestMitDelete()
    2. For i = 1 To 10
    3. Rows(i).Delete
    4. Next
    5. End Sub
    siehst du, was ich meine.
    Jede zweite Zahl bleibt stehen.
    Weil nach dem Löschen der ersten Zeile die zweite nach oben rutscht, dein Schleifenzähler aber weiterläuft.

    Das stört nicht, wenn man rückwärts zählt, weil dann nur die bereits verarbeiteten Zeilen verschoben werden.

    Mono schrieb:

    höchstwahrscheinlich deutlich unperformanter als eine kleine Schleife
    Da magst du recht haben.
    Ich hab's nicht gemessen.

    Mono schrieb:

    ohne Erklärung
    Zugegeben.
    Ist halt auch ein wenig ein Hack.
    Range.Value gibt blödsinnigerweise ein zweidimensionales Array of Array zurück, das man erst mal kompliziert Transposen muss, um es als Vergleichsarray verwenden zu können.
    Der eigentliche Grund für den Ansatz war, dass durch die Joinerei die Bedingung "es soll irrelevant sein ob der Inhalt einer Zelle ein Text oder eine Zahl ist" nebenbei mit erschlagen wird.
    Aber es stimmt schon: Mun muss es nicht so machen, übersichtlich ist anders.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „petaod“ ()

    @ereza
    Warum nutzt du nicht die Funktion "Duplikate entfernen" die Excel mitbringt?

    Visual Basic-Quellcode

    1. ​Sub Makro1()
    2. ActiveSheet.Range("$A$1:$C$3").RemoveDuplicates Columns:=Array(1, 2, 3), _
    3. Header:=xlNo
    4. End Sub
    There is no CLOUD - just other people's computers

    Q: Why do JAVA developers wear glasses?
    A: Because they can't C#

    Daily prayer:
    "Dear Lord, grand me the strength not to kill any stupid people today and please grant me the ability to punch them in the face over standard TCP/IP."
    @petaod daher ja meine Frage: Die Frage ist nur, kann es auch 3 oder 4 idente Zeilen geben ? Das wäre dann nicht berücksichtigt.

    Denn so wie es ist wird ja immer die nächste Zeile gelöscht, dann würde es wieder passen, auch wenn die Schleife dann ein bissl übers Ziel läuft. Also im Grunde ist rückwärts da schon besser ;)

    @Schamash Die Methode leert aber nur die Zellen und löscht nicht die komplette Zeile.
    Das ist meine Signatur und sie wird wunderbar sein!

    Mono schrieb:

    Die Methode leert aber nur die Zellen und löscht nicht die komplette Zeile.


    OK weil es so schwer ist in Excel anschließend ein "sort" einzufügen.
    There is no CLOUD - just other people's computers

    Q: Why do JAVA developers wear glasses?
    A: Because they can't C#

    Daily prayer:
    "Dear Lord, grand me the strength not to kill any stupid people today and please grant me the ability to punch them in the face over standard TCP/IP."
    Hallo!

    und Danke für eure Antworten....

    Ich habe nun meinen Code, momentan mal so:

    Visual Basic-Quellcode

    1. Private Sub CommandButton1_Click()
    2. Dim a As Long
    3. Dim b As Long
    4. Dim col As Integer, del As Boolean
    5. For a = 2 To Cells(Rows.Count, 1).End(xlUp).Row
    6. b = a + 1
    7. If Cells(a, 5).Value = "" Then
    8. del = True
    9. For col = 1 To 13
    10. If Cells(a, col).Value <> Cells(b, col).Value Then
    11. del = False
    12. Exit For
    13. End If
    14. Next
    15. If del Then
    16. Tabelle7.Rows(b).Delete
    17. End If
    18. End If
    19. Next
    20. End Sub



    Um nochmals klarzustellen, was ich genau als Bedingung fürs löschen der folgenden Zeile habe...:

    Annahme:
    es gibt jz in Zeile 15 und 16, die komplett gleichen, identen, Einträge. Ersichtlich bzw. markantes Merkmal, welche Zeilen überhaupt "betrachtet" werden sollen... ist... die Betrachtung der Spalte 5. Wenn dieses Feld leer ist... soll weiters analysiert und fortgesetzt werden... etc.
    Wenn also Zeile 15 komplett die gleichen Einträge hat wie Zeile 16 und bei beiden Zeilen (15 und 16) die Spalte 5 leer ist, dann soll Zeile 16 entfernt werden...


    Jedoch das mit dem Zeilenindex durcheinander wirbeln ist natürlich blöd!! ABER... ich habe es gerade so, mit dem genannten Code, probiert... und da funktioniert das interessanter Weise... obwohl er die Zeilen löscht... Irgendwie löscht er dann die richtigen Zeilen... weil genau die entfernt werden, die entfernt werden sollen... also alle Doppelten Zeilen werden entfernt....

    Jetzt denke ich mir, dass das einfach daran liegt... dass er durch den Rowcount eine gewisse Zeilennummer, ermittelt. Sagen wir es gibt gesamt 50 Einträge. Also ist 50 dann die Zahl, die ermittelt wird. Da ja aber eigentlich fürs löschen, ja nur die Bedingung gilt:

    Schau dir alle Einträge an und bleibe bei dem Eintrag hängen... wo... --> Wenn Zelle in Spalte 5 leer ist, dann... überprüfe ob Inhalte ungleich sind oder nicht... --> wenn NICHT UNGLEICH, dann wird das Löschmerkmal auf TRUE gesetzt, und die darunter folgende Zeile wird gelöscht...

    So, jz denke ich mir... wenn der dann die Zeile löscht, dann verschiebt sich ja die Zeile nach oben... heißt also... wenn man zuvor 50 Einträge hatte, hat man nun eben 49. - ABER, Excel, wird dann ja trotzdem zum nächsten Eintrag springen, der wieder die Bedingung erfüllt, Zelle in Spalte 5 leer....
    Somit denke ich, dass das der Grund ist, warum hier trotzdem richtig gearbeitet wird....

    Das einzige, dass sich mir jz aus der Logik und aus petaod's Erklärung ergibt, wäre nun, dass es eben dann so ist, dass zwar weniger Einträge vorhanden sind, als der ursprüngliche Rowcount vorgibt... Also wenn Anfangs 50 Einträge waren, und durch das Löschen dann, sagen wir zb. 10 wegfallen, dann schaut sich Excel, die Einträge trotzdem bis Zeile 50 an, obwohl es ab 40, nur mehr alles leere Zeilen sind... - Aber in dem Fall ist das nicht weiter tragisch, da diese Einträge eh nicht relevant sind... und selbst wenn, die Bedingung (Zeileneinträge von Zeile und darunter stehender Zeile sind gleich ? bzw. sind ungleich?) greifen würde... dann würden eben diese leeren Zellen auch gelöscht werden...! - Wäre zwar unnötig... aber stört mich keineswegs!


    So, das ist nun mal meine Vermutung! - Aber ich weiß natürlich nicht, ob meine Annahme so, wirklich richtig ist....!

    Also, vl. auch speziell an petaod gerichtet...:
    Meinst du, dass das so korrekt ist, wie ich mir das vorstelle, oder hab ich da doch einen "Denkfehler" drinnen, oder habe da was nicht bedacht??

    Vielen Dank!

    LG Tim

    ereza schrieb:

    Meinst du, dass das so korrekt ist
    Ganz sauber ist dein Ansatz nicht.
    Vergleiche die Diskussionen in Post#5 und #7.

    In deinem speziellen Fall mag das zwar genau funktionieren, weil die übersprungene Zeile das bereits verglichene Duplikat ist.
    Und es danach nicht mehr juckt, wenn noch ein paar Zeilen überflüssigerweise durchlaufen.
    Die universellere und saubere Variante ist, die Zeilennummern rückwärts laufen zu lassen wie in Post #3.
    Wenn dir dort die Vergleichsfunktion zu kryptisch ist, kannst du sie ja durch die Variante mit der Spaltenschleife ersetzen.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --