Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1924to1928
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

VBA - Texte zählen und 2 Texte vergl.

VBA - Texte zählen und 2 Texte vergl.
30.03.2023 08:25:41
Christian

Hallo, ich bitte um eure Hilfe, auch wenn ich wahrscheinlich nur den Wald vor lauter Bäumen nicht sehe.

Es geht um den letzten Teil des Makros, wo eine bestimmte Zelle in Spalte A ausgewählt wird.

Ich wollte hier zwei Bedingungen aufführen, die erfüllt sein müssen, damit diese Zelle ausgewählt wird, nämlich dass der soeben in Spalte A eingegebene Text bereits in der Spalte A steht, egal wie oft, was ich mit der Prüfung

If Application.WorksheetFunction.CountIf(Worksheets("Ergebnis").Range("A2:A" & lLastRow), Target.Value) > 0


prüfen wollte

und die Bedingung dass der letzte Text in Spalte A ungleich dem vorletzten Text in Spalte A ist. Was ich mit der Prüfung

And Target.Value > Range("A" & lLastRow - 1).Value Then


prüfen wollte.

Doch wenn die zweite Prüfung nicht erfüllt ist, also die beiden letzten Texte identisch sind, wird trotzdem die letzte Zeile gelöscht. Warum?

Danke für die Hilfe
Christian

Hier noch das ganze Makro:

Private Sub Worksheet_Change(ByVal Target As Range)
   Dim lRowFind&, lLastRow&
   
   If Target.Count > 1 Then GoTo ende
   
   With Selection
    .Font.Bold = False
      .Font.Name = "Calibri"
      .Font.Size = 11
      .Font.ColorIndex = xlAutomatic
      .Hyperlinks.Delete
      .HorizontalAlignment = xlCenter
      .Font.Italic = True
   End With
   
   Cells.EntireColumn.AutoFit
   
   '* letzte belegte Zeile ermitteln
      lLastRow = Cells(Rows.Count, "A").End(xlUp).Row - 1
   
   '* wenn Zeile gelöscht oder Text kopiert werden soll, dann hier Abbruch
      If Target.Row > lLastRow + 1 Then GoTo ende
      
   '* rechtes Leerzeichen (Blank) entfernen
      If Right(Selection, 1) = " " Then Target.Value = Left(Target.Value, Len(Target.Value) - 1)
      
   Application.EnableEvents = False
      '* erste Zelle mit dem Suchbegriff anspringen
         If Application.WorksheetFunction.CountIf(Worksheets("Ergebnis").Range("A2:A" & lLastRow), Target.Value) > 0 And Target.Value > Range("A" & lLastRow - 1).Value Then
            lRowFind = Application.Match(Target.Value, Range("A2:A" & lLastRow), 0) + 1
            Rows(Target.Row).EntireRow.Delete
            Cells(lRowFind, "A").Select
         End If
ende:
   Application.EnableEvents = True
End Sub




23
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: VBA - Texte zählen und 2 Texte vergl.
30.03.2023 09:39:49
onur
Alles HINTER
If Target.Row > lLastRow + 1 Then GoTo ende
ist belanglos, da es nur ausgeführt wird, wenn Target in der letzten Zeile war.


schon aber...
30.03.2023 09:55:34
Christian
das war ja auch der Zweck der Sache. Das soll nur ausgeführt werden wenn es sich um die letzte Zeile handelt. Es soll ja geprüft werden ob ein soeben am Ende der Spalte A eingefügter Text bereits vorhanden ist und wenn ja diese Zeile wieder gelöscht und in die Zeile gesprungen werden, in der dieser Text bereits steht. (Soweit funktioniert es ja auch).

Mit einer Ausnahme halt, der gerade eingefügte Text ist identisch mit dem obendrüber. (Diese Prüfung funktioniert nicht).

Aber wie gesagt, das ist so gewollt, die Formatierungen am Anfang sollen sich auf die ganze Tabelle beziehen, das leerzeichen entfernen auf die letzte Zeile und das was ganz unten steht auf Eingaben am Ende von Spalte A.


Anzeige
oder vielleicht so verständlicher...
30.03.2023 10:00:13
Christian
Hallo Onur,
sorry hätte dich eben schon begrüßen sollen, danke für deine Hilfe.

ich möchte den letzten Text in Spalte A eine Zeile nach unten kopieren können, ohne dass das Makro eingreift. Das Makro soll nur eingreifen, wenn ich in erste freie Zeile einen Text kopiere, der nicht identisch ist mit dem obendrüber.

Gruß
Christian


AW: schon aber...
30.03.2023 10:11:43
onur
Durch
lLastRow = Cells(Rows.Count, "A").End(xlUp).Row - 1
ist lLastRow die LETZTE BENUTZTE Zeile - oder ????
If Target.Row > lLastRow + 1 Then GoTo ende
KANN NICHT zutreffen, wenn du greade eine neue Zeile eingefügt hast, da dann lLastRow ja die AKTUELLE Zeile wäre.


Anzeige
AW: schon aber...
30.03.2023 10:15:56
onur
Lass einfach "+ 1" weg.


AW: schon aber...
30.03.2023 10:53:06
Christian
und das ist ja genau das was ich wollte, ich habe mit
lLastRow = Cells(Rows.Count, "A").End(xlUp).Row - 1
die letzte benutzte Zeile bestimmt,

füge dann eine Zeile drunter einen neuen Text ein.

prüfe dann mit
If Application.WorksheetFunction.CountIf(Worksheets("Ergebnis").Range("A2:A" & lLastRow), Target.Value) > 0
, ob der gerade eingefügte Text schon in Spalte A steht

die Zeile
If Target.Row > lLastRow + 1 Then GoTo ende
hat den Zweck, dass ich zwischendrin Zeilen einfügen und mit Inhalt füllen kann, ohne dass das Makro die folgenden Prüfungen vornimmt.

aber ich denke ich habe meinen Fehler gefunden.

And Target.Value > Range("A" & lLastRow -1).Value
vergleicht das Target nicht mit der letzten sondern der vorletzten Zeile, also muss das -1 weg.

Jetzt funktioniert es.

Danke
Christian


Anzeige
AW: schon aber...
30.03.2023 17:46:39
Yal
Warum prüfst Du die ganze Spalte, wenn relevant nur die vorletzte ist?


AW: schon aber...
30.03.2023 18:31:21
Yal
Hallo Christian,

aus deinem Code ist es schwer herauszulesen, was Du machen möchtest.
Ich habe viel Kommentar reingebracht. So kannst Du entdecken, wo meine Gedanken von deinem Vorhaben abweichen.
(Ich habe die Schönmacherei "Font..." ausgelassen. Eigentlich wenn die gesamte Spalte oder gar Blatt schon eingerichtet ist, braucht man es nicht pro Eingabe)

Private Sub Worksheet_Change(ByVal Target As Range) 'reagiert bei Eingabe in einer Zelle
Dim lRowFind As Long
Dim LetzteInA As Range
   
    Application.EnableEvents = False
    If Target.Count > 1 Then GoTo Ende 'nur wenn eine Zelle geändert wurde
    If Target.Column = 1 Then GoTo Ende 'nur wenn diese Zelle in Spalte A steht
    Set LetzteInA = Cells(Rows.Count, "A").End(xlUp) 'letzte belegte Zelle in Spalte A ermitteln
    Target.Value = RTrim(Target.Value) 'rechtes Leerzeichen (Blank) entfernen
' zwei Fälle: Eingabe in der "neueste" letzter Eintrag in Spalte A oder nicht
    If Target.Row = LetzteInA.Row Then
        lRowFind = Application.Match(Target.Value, Range(Range("A2"), LetzteInA.Offset(-1)), 0) 'gesamte Spalte A bis Vorletzte
    Else
        lRowFind = Application.Match(Target.Value, Range(Range("A2"), Target.Offset(-1)), 0) 'vor der Eingabe
        If IsError(lRowFind) Then lRowFind = Application.Match(Target.Value, Range(Target.Offset(1), LetzteInA), 0) 'nach der Eingabe
    End If
    If Not IsError(lRowFind) Then 'exisiert bereits
        Cells(lRowFind, "A").Select ' erste Zelle mit dem Suchbegriff anspringen (zuerst, falls Target.Row  LRowFind)
        Rows(Target.Row).EntireRow.Delete ' neueste ist doppelt, also vernichten
    End If
Ende:
    Application.EnableEvents = True
End Sub
VG
Yal


Anzeige
AW: schon aber...
30.03.2023 21:36:37
Christian
Hallo Yal,

vielen Dank für deine Mühe.

zuerst, es handelt sich ausnahmslos um aus dem Internet kopierten Text und Zahlen, aus verschiedenen Quellen in unterschiedlichen Formatierungen. Ohne die Anpassungen wäre das einfach nur Kraut und Rüben.
Klar könnte man auch erst alles in die Mappe bringen und dann zum Schluss die Formatierung anpassen, aber wenn dann plötzlich die einen Zeilen maximal Schriftgröße 11 haben, die anderen SG 24, das verwirrt mich nur, daher habe ich mich dazu entschieden, das Makro das übernehmen zu lassen.

Ich versuche es mal zu erklären, was ich machen will, gut die Inhalte, die ich jetzt schreibe, sind erfunden, entsprichen nicht den Originaldaten, aber so ist es vielleicht besser verständlich.

Stell dir vor, es würde sich um eine Art Telefonbuch handeln, Spalte A die Adressen, Spalte B die Namen usw.

Ich möchte jetzt eine Person der Liste hinzufügen und gebe in Spalte A dessen Adresse ein. Das Makro prüft jetzt, ob an dieser Adresse schon Einträge vorhanden sind und wenn ja springt es zu dem ersten Eintrag.

Jetzt kann ich an dieser Stelle prüfen, ob auch die Person, die ich eintragen wollte, bereits in der Liste steht, oder lediglich andere Personen, die imselben Haus wohnen.

Wenn die Person bereits existiert, brauche ich gar nichts mehr machen, wenn sie noch nicht existiert, füge ich sie direkt an Ort und Stelle in einer neuen Zeile ein, anstatt am Ende der Tabelle, damit was zu einer Adresse gehört, auch in aufeinanderfolgenden Adressen bleibt, ohne dass ich danach jedesmal anfangen muss die Tabelle zu sortieren.

Was dafür aber von Nöten ist, ist dass ich eine Zeile mittendrin in der Tabelle einfügen kann, in der nicht überprüft wird, ob der Text in Spalte A bereits vorhanden ist,

daher die Zeile

If Target.Row > lLastRow + 1 Then GoTo ende


damit nicht weitergemacht wird wenn es sich nicht um die letzte Zeile handelt.

Außerdem brauche ich dann ja nicht mehr den Eintrag in Spalte A den ich ursprünglich am Ende gemacht habe, ich habe den Eintrag den ich machen wollte ja entweder gar nicht gemacht, weil er ja schon vorhanden war oder mitten in der Tabelle

daher die Zeile

Rows(Target.Row).EntireRow.Delete
Jetzt habe ich aber noch das Problem, einen Text, den ich aus dem Internet kopiert habe, kann ich nicht in mehrere Zellen gleichzeitig einfügen.
Wenn ich jetzt aber mehrere Personen eintragen will, die an der selben (bislang unbekannten) Adresse wohnen.
Dann bleibt mir nur die Möglichkeit, die Adresse erstmal in eine Zelle einzufügen, diese Zelle nochmal zu kopieren und in soviele weitere Zellen einzufügen, wie ich sie dann brauche.
Und genau bei diesem Einfügen in eine weitere Zeile passiert es dann, dass die Adressen in den letzten beiden Zeilen identisch sind und das Makro würde die gerade eingefügte Zeile wieder löschen, da es die Adresse dann ja bereits gibt.

Daher dann die Ausnahme mit
Target.Value > Range("A" & lLastRow).Value
damit die letzte Zeile nicht gelöscht wird, wenn die letzten beiden Zeilen identisch sind.

Ich hoffe das war jetzt was verständlicher.

Wenn nicht, ich habe ja jetzt ein Makro auf jeden Fall das funktioniert. Dein Makro werde ich morgen in Ruhe testen, mir fallen jetzt leider die Augen zu.

Viele Grüße
Christian


Anzeige
bislang noch ungetestet...
30.03.2023 21:46:36
Christian
eins fällt mir ungetestet schon auf.
die rechten Leerzeichen treten in den Spalten B und E auf, es bringt nichts, diese zu entfernen, nachdem geprüft wurde, ob es sich um eine Eingabe in Spalte A handelt.
Gut zugegebenermaßen ich habe es in meinem Makro offen gelassen und gesagt überprüfe es bei jeder Eingabe, ich war zu faul, das in meinem Makro auf Spalte B und E zu beschränken.


AW: bislang noch ungetestet...
31.03.2023 07:40:03
Yal
Hallo Christian,

wo ist in deiner gesamten, bisherigen Beschreibung die Rede von Spalten B und E?
Programmieren bedeutet, Ideen in Aktionen umzuwandeln. Da Computer sehr dumm sind, muss man jede kleinste Teil der Gedanken spezifizieren. Wir Helfer sind zwar weniger dumm, aber ein mindest Maß an Detail und Genauigkeit brauchen wir schon.
Außerdem beschränkt sich das Coding auf der Spalte A, wie kommentiert.

VG
Yal


Anzeige
AW: bislang noch ungetestet...
31.03.2023 08:44:24
Christian
Hallo Yal, es war nie die Rede von Spalte B und E bislang, weil ich ein konkretes Problem geschildert habe, welches nichts mit dem Entfernen des letzten Zeichens zu tun hatte.

Ich finde es sehr nett von dir, dass du dir die Mühe machst, das ganze Makro zu überarbeiten, obwohl ich sagte, dass ich den Fehler in meinem Makro gefunden habe, aber auf der anderen Seite, warum soll ich in der Problembeschreibung auf Dinge wie Spalte B und E eingehen, obwohl sie das Problem gar nicht betreffen.

Wenn wir dann hingehen und dann doch Dinge am Makro ändern, die über meine Fragestellung hinausgehen, ist es doch logisch, dass dann auch Sachen zu Tage treten können, die nichts mit der ursprünglichen Fragestellung zu tun haben und daher bislang unerwähnt blieben.

Mache mich dann jetzt mal ans Testen deines Makros.

Christian


Anzeige
Testergebnis
31.03.2023 08:53:57
Christian
ich habe es ein wenig umgestellt, damit sich das Trim auf alle Spalten bezieht. Jetzt bekomme ich in der Zeile weit unten

 If IsError(lRowFind) Then lRowFind = Application.Match(Target.Value, Range(Target.Offset(1), LetzteInA), 0) 'nach der Eingabe 
die Meldung Typen unverträglich. Hoffe, ich habe jetzt nicht durch meine Umstellungen einen Fehler eingebaut.

Private Sub Worksheet_Change(ByVal Target As Range) 'reagiert bei Eingabe in einer Zelle
    Dim lRowFind As Long
    Dim LetzteInA As Range
    
    Application.EnableEvents = False
    
    If Target.Count > 1 Then GoTo Ende 'nur wenn eine Zelle geändert wurde
   
   With Selection
    .Font.Bold = False
      .Font.Name = "Calibri"
      .Font.Size = 11
      .Font.ColorIndex = xlAutomatic
      .Hyperlinks.Delete
      .HorizontalAlignment = xlCenter
      .Font.Italic = True
   End With
   
   Cells.EntireColumn.AutoFit
   
   Target.Value = RTrim(Target.Value) 'rechtes Leerzeichen (Blank) entfernen
   
   Set LetzteInA = Cells(Rows.Count, "A").End(xlUp) 'letzte belegte Zelle in Spalte A ermitteln
   
   If Target.Column = 1 Then GoTo Ende 'nur wenn diese Zelle in Spalte A steht
   
  If Target.Row = LetzteInA.Row Then
            lRowFind = Application.Match(Target.Value, Range(Range("A2"), LetzteInA.Offset(-1)), 0) 'gesamte Spalte A bis Vorletzte
        Else
            lRowFind = Application.Match(Target.Value, Range(Range("A2"), Target.Offset(-1)), 0) 'vor der Eingabe
            If IsError(lRowFind) Then lRowFind = Application.Match(Target.Value, Range(Target.Offset(1), LetzteInA), 0) 'nach der Eingabe
        End If
        If Not IsError(lRowFind) Then 'exisiert bereits
            Cells(lRowFind, "A").Select ' erste Zelle mit dem Suchbegriff anspringen (zuerst, falls Target.Row  LRowFind)
            Rows(Target.Row).EntireRow.Delete ' neueste ist doppelt, also vernichten
        End If
Ende:
        Application.EnableEvents = True
    End Sub


Anzeige
AW: Testergebnis
31.03.2023 14:36:19
Yal
Hallo Christian,

trage
Dim lRowFind As Variant
anstatt
Dim lRowFind As Long

Es liegt daran, dass wenn Application.Match nicht findet ein "Fehler 2042" zurückgegeben wird, die nicht in einer "long" Variable passt.

VG
Yal


AW: Testergebnis
01.04.2023 07:58:09
Christian
Hallo Yal,

jetzt ist die Fehlermeldung weg. Aber ich habe jetzt testweise den Text aus A913 nach A925 (Ende) kopiert und es hat sich nichts getan, es wurde weder nach A913 gesprungen, noch wurde die Zeile 925 gelöscht...

Gruß
Christian


AW: Testergebnis
03.04.2023 09:46:49
Yal
Hallo Christian,

es fehlt mir schwer, über eine Datei zu sprechen, die ich nicht sehen darf.
Auch die Anforderungen sind weder genauer spezifiziert, noch bestätigt oder widerlegt.

Anders gesagt: es verhält sich nicht wie Du es erwartest, aber ich weiß immer noch nicht genau, was Du erwartest und ich habe keine Datei, wo ich A913 oder A925 sehen kann (zum Test wurde auch A5 und A12 reichen)

VG
Yal


Anzeige
dann hier die Datei
03.04.2023 16:53:08
Christian
https://www.herber.de/bbs/user/158577.xlsm

Hallo Yal,

ich fürchte wenn ich dir versuche nochmal den kompletten Sinn und Zweck zu erklären wird das nur noch verwirrender.

Daher erkläre ich es einfach was passieren soll, ohne den Sinn und Zweck dahinter.

1. ich kopiere einen Text aus dem Internet in die erste leere Zelle in Spalte A (A21).
2. Gibt es ihn bereits in Spalte A, soll zu dieser Zelle gesprungen werden und Zeile 21 gelöscht werden.
Ausnahme A20=A21. (letzter vorhander = gerade eingegebener Text)
3. Gibt es ihn noch nicht, soll außer dem Formatieren nichts geschehen. Auch wenn A20=A21 soll lediglich formatiert werden.
4. Gebe ich in eine andere Zelle außer der ersten leeren in Spalte A (A21) etwas ein, soll auch lediglich formatiert werden.
5. Keine Fehlermeldung, wenn ich mitten in der Tabelle händig Zeilen hinzufüge oder lösche.

Hoffe es ist jetzt klarer.

Christian

PS: Wundere dich nicht über den Namen wer die Datei erstellt hat, wenn Microsoft schon Daten sammelt dürfen sie es wenigstens unter falschem Namen tun.


ein Punkt fehlt noch
03.04.2023 17:00:03
Christian
Wenn ich mittendrin eine Zeile von Hand zufüge und dann etwas dorthinein in Spalte A kopiere, soll auch nichts weiter geschene als Formatieren.

Die Suche nach bereits vorhandenen Texten in Spalte A soll wirklich nur dann geschehen wenn ich ganz am Ende in Spalte A was einfüge und der eingefügte Text ungleich dem obendrüber ist.

Aber um es nochmal zu erwähnen, ich habe ja bereits ein funktionierendes Makro, der Fehler, weshalb ich mich gemeldet habe ist längst behoben.
Wenn dir das zu kompliziert hier wird, bin ich dir auch nicht böse, wenn wir es dabei belassen.


AW: dann hier die Datei
04.04.2023 13:48:21
Yal
Hallo Christian,

unklar ist, ob diese Text der aus Internet kopiert wird, aus eine einzige Zelle oder mehrere besteht.

Denn:
    If Target.Count > 1 Then GoTo Ende 'nur wenn eine Zelle geändert wurde
hier wird nur reagiert, wenn nur eine Zelle geändert wurde. Beim "paste" über mehrere Zellen, ist Target mehrzellig.

VG
Yal


AW: dann hier die Datei
04.04.2023 13:54:07
Yal
Private Sub Worksheet_Change(ByVal Target As Range) 'reagiert bei Eingabe in einer Zelle
Dim lRowFind As Variant
Dim LetzteInA As Range
Dim Z As Range
    
    Application.EnableEvents = False
    Debug.Print Target.Address
    If Target.Cells(1).Column > 1 Then GoTo Ende 'nur die Änderung die Spalte A auch trifft
   
    With Selection
        .Font.Bold = False
        .Font.Name = "Calibri"
        .Font.Size = 11
        .Font.ColorIndex = xlAutomatic
        .Hyperlinks.Delete
        .HorizontalAlignment = xlCenter
        .Font.Italic = True
    End With
   
    Cells.EntireColumn.AutoFit
    For Each Z In Target.Cells
        Z.Value = Trim(Z.Value) 'Leerzeichen vor & nach (Blank) entfernen
    Next
    Set LetzteInA = Cells(Rows.Count, "A").End(xlUp) 'letzte belegte Zelle in Spalte A ermitteln
    Set Target = Target.Cells(1)
    If Target.Row = LetzteInA.Row Then
        lRowFind = Application.Match(Target.Value, Range(Range("A2"), LetzteInA.Offset(-1)), 0) 'gesamte Spalte A bis Vorletzte
        If Not IsError(lRowFind) Then 'exisiert bereits
            Cells(lRowFind, "A").Select ' erste Zelle mit dem Suchbegriff anspringen (zuerst, falls Target.Row  LRowFind)
            Rows(Target.Row).EntireRow.Delete ' neueste ist doppelt, also vernichten
        End If
    End If
Ende:
    Application.EnableEvents = True
End Sub


AW: dann hier die Datei
04.04.2023 16:42:19
Christian
Hallo Yal,

danke für die Hilfe, um erstmal deine Frage zu beantworten, es besteht immer nur aus Zelle, wenn ich etwas aus dem Internet kopiere.

Anders ist es, wenn ich etwas aus der Datei woanders hin in der Datei kopiere, dann können es auch mehrere Zellen sein, aber da gibt es nur 2 Wege, wann ich das mache. Entweder nachdem ich mittendrin eine Zeile eingefügt habe, um diese dann zu füllen, oder in dem ich Inhalte aus der letzten Zeile in weitere Zeilen untendrunter kopiere.
Jedoch im ersten Fall soll ja lediglich formatiert werden, weil es sich nicht um die letzte Zelle in Spalte A handelt und im zweiten Fall soll ja lediglich formatiert werden, weil die letzten beiden Einträge in Spalte A identisch sind.

Ich werde dann jetzt mal testen.

Danke
Christian


.. immer nur aus einer Zelle
04.04.2023 16:43:11
Christian
.


Testergebnis
04.04.2023 16:59:44
Christian
Hallo Yal, leider sind mir 3 Dinge aufgefallen, die nicht funktionieren.

1. Die Formatierungen hätten bei allen Eingaben ins Blatt ausgführt werden sollen, unabhängig der Spalte sowie der Zeile.

2. Wenn ein Text gefunden wird, wird nicht in die Zeile mit dem Text sondern eine Zeile obendrüber gesprungen. Z.b. wenn ich A15 nach A21 kopiere, springt Excel nach A14 statt A15.

3. wenn ich A20 nach A21 kopiere, wird Zeile 21 gelöscht, obwohl die beiden in diesem Moment letzten Einträge in Spalte A identisch sind.

Gruß
Christian

305 Forumthreads zu ähnlichen Themen

Anzeige
Anzeige
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige