[VBA] String suchen mit Mehrfachvorkommen eines Kennzeichens

Harry2k

Ensign
Registriert
Jan. 2017
Beiträge
151
Hallo CB Community,

stehe grad vor einer Kopfnuss,

ich suche einen Teilstring der als Kennzeichen 2x ein / enthält (in 8/10 Fällen)

z.B. KundenAuftragEinsatzart: 698874/6387/01

Allerdings ist dieser String manchmal mit anderen Sachen vermischt, also

Buxtehude /1234 KundenAuftragEinsatzart 698874/6387/01
KundenAuftragEinsatzart 698874/6387
Musterstadt /1234 KundenAuftragEinsatzart 698874/6387/01
KundenAuftragEinsatzart 698874/6387/01
KundenAuftragEinsatzart 698874/6387/01

Frage 1 Wie kann ich prüfen ob KundenAuftragEinsatzart am Anfang der Zelle steht? (da if Bedingung evtl als Lösung)
Frage 2 ist wie kann ich das sauber raustrennen sodass ich alles ab "KundenAuftragEinsatzart" erhalte?

Vermutlich noch nicht ganz die Lösung die ich brauche aber danach evtl hilft mir das schon soweit das ich damit eine Gesamtlösung finde

Gruß

Harry2k
 
Was brauchst du denn in welcher Form genau?
In vbs gibt es die Split-Funktion (müsste in vba eigentlich auch vorhanden sein).
Da gibst du das "/" als Delimiter an und bekommst ein array mit den durch "/" getrennten strings.
Das array kannst du dann auswerten, neu zusammen würfeln etc. wie du willst ;)
 
Ich denke Regex ist das Stichwort.

https://regex101.com/r/UAT3GI/1
Habe eine Regex erstellt zu dem was ich jetzt aus deinem Beitrag lesen konnte.
Um die Daten zu exportieren, rechts auf "Export Matches" drücken. Dann kannst du als CSV exportieren und bspw. in Excel importieren. Dort hast du dann eine Spalte mit deinen gewünschten Daten.

Geht bestimmt einfacher mit Regex, indem man alles was nicht zutrifft rausschmeisst.
 
@tollertyp : Kommt drauf an, was er vom string genau auswerten will. Das hatte ich ja beim TE auch angefragt. Ich finde split extrem einfach zu handhaben und man hat gleich alle Daten in einem array zur Weiterverarbeitung bzw. Aufbereitung. Und es erhöht die Lesbarkeit des Codes.
 
https://regex101.com/r/UAT3GI/2

Input:
Buxtehude /1234 KundenAuftragEinsatzart1 698874/6387/01
KundenAuftragEinsatzart 698874/6387
Musterstadt /1234 KundenAuftragEinsatzart2 698874/6387/01
KundenAuftragEinsatzart3 698874/6387/01
KundenAuftragEinsatzart4 698874/6387/01
Output:
match,group,is_participating,start,end,content
1,1,yes,16,55,KundenAuftragEinsatzart1 698874/6387/01
1,2,yes,16,40,KundenAuftragEinsatzart1
2,1,yes,110,149,KundenAuftragEinsatzart2 698874/6387/01
2,2,yes,110,134,KundenAuftragEinsatzart2
3,1,yes,150,189,KundenAuftragEinsatzart3 698874/6387/01
3,2,yes,150,174,KundenAuftragEinsatzart3
4,1,yes,190,229,KundenAuftragEinsatzart4 698874/6387/01
4,2,yes,190,214,KundenAuftragEinsatzart4
 

Anhänge

  • 2021-02-17 10_59_10-Window.png
    2021-02-17 10_59_10-Window.png
    15,3 KB · Aufrufe: 174
  • Gefällt mir
Reaktionen: Lukas'
regex ist leider keine lösung da es 5700 Einzeldatensätze sind, die in Excel weiterverarbeitet werden sollen, daher auch vba Ansatz. Hätte deutlicher sagen müssen das es innerhalb von Excel sein sollte, damit der Arbeitslauf nicht unterbrochen wird vom jeweiligen Sachbearbeiter..habe es bisher auf 2 Knöpfe reduziert bekommen, leider wird durch die unterschiedliche Formateingabe der Mitarbeiter der Automatismus gestört.
Da die Herren und Damen allerdings die Vorgaben nicht eingehalten haben bei der Datenerfassung nun das o.g. Problem.

...und nach Split google ich mal, evtl hilft mir das ja irgendwie
 
Nun, Regular Expressions sind dann doch erst recht eine Lösung, weil du sie eben in Excel nutzen kannst. Sonst hätte man dir das wohl nicht vorgeschlagen;) Und @Augen1337 hat, finde ich, eine beeindruckende Lösung "mal eben" bereitgestellt, welche du auch in VBA nutzen kannst.

Um zu testen, ob ein String mit ein KundenAuftragEinsatzart beginnt, kannst du das hier nutzen.
 
  • Gefällt mir
Reaktionen: Augen1337
Absolut, REGEX Engines sind von Grund auf optimiert und fast nur durch schlechte Regex‘ klein zu bekommen, der Aufruf simpel, kaum etwas zu programmieren. 5600 Treffer..... wo ist das Problem?
Hättest du jetzt etwas im Millionenbereich gesagt, ok.. da wäre dann eher Excel der Flaschenhals.
 
  • Gefällt mir
Reaktionen: tollertyp
Ach ja, wenn es nur darum geht, dass es auch am Anfang des Ausdrucks stehen darf, wäre das hier der passende RegEx:
^((\S+)\s\d+\/\d+\/\d+)

Also ^ ergänzt für den Beginn.
Und wenn es nur KundenAuftragEinsatzart sein soll z.B. so:
^(KundenAuftragEinsatzart\s\d+\/\d+\/\d+)

@Demon_666:
Zugegeben, ein RegEx ist selten direkt auf Anhieb zu verstehen, und oftmals ist es gut, wenn man Beispiele dazu schreibt, was er finden soll (mal von ganz einfachen RegExen abgesehen oder einem RegEx-String der den Namen EMAIL_REGEX trägt).

Aber die Behauptung, Split würde die Lesbarkeit des Codes erhöhen, halte ich für ziemlich haltlos und dafür würde ich gerne Beispiele sehen, anhand derer du das belegst.

Also einmal die Version mit Split und einmal mit RegEx.

Ich habe eher das Gefühl, dass du schlicht das verteidigst, was du kennst, und gar nicht die Eleganz von regulären Ausdrücken kennst. Und nicht falsch verstehen: Die anderen Befehle haben genauso ihre Berechtigung und nicht alles was man mit RegEx lösen kann, löst man am besten mit einem RegEx.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Augen1337
Also ich habe auch zwei schöne Funktionen in VB(S/A), die Regex in dieser Sprache sehr erträglich machen ;-)

Ich benötige nur von dir:
-Weitere Beispiele, was gefunden werden soll oder
-genaue Regeln und
-zu einem Beispiel die entsprechenden Treffer, die getroffen und Strings, die nicht getroffen werden sollen.

Dann schreibe ich dir gerne die Regex und gebe dir zwei VB(S/A) Funktionen. Dann ist die ganze Chose in 4-5 Zeilen Code erledigt :)
( sage ich immer, werden dann wahrscheinlich 10 :D )
 
Demon_666 schrieb:
Ich finde split extrem einfach zu handhaben ....
@tollertyp : Lies doch nochmal die ersten beiden Worte meines Zitats. ;)
Ich habe zudem nichts gegen regex gesagt. Wenn Du das irgendwie persönlich nimmst bzw. dich angegriffen fühlst, nur weil ich einen anderen Weg als den deinen vorschlage/favorisiere, kann ich da wenig dran ändern. Nur bringt das dem TE herzlich wenig.
Jeder hat seine persönlichen Programmiervorlieben und das ist auch gut so.
Er hat von uns verschiedene Lösungsmöglichkeiten bekommen. Welche er für sein Problem anwendet, bleibt ihm überlassen.
 
Ich bevorzuge es eigentlich, den gesamten Beitrag zu lesen.
Demon_666 schrieb:
[...] Und es erhöht die Lesbarkeit des Codes.
Ich bat dich um Beispiele, wo split die Lesbarkeit des Codes im Vergleich zu einem RegEx erhöht.

Und wenn er im RegEx die einzelnen Werte von 698874/6387/01 braucht (also 698874, 6387, 01), dann kann er sich im RegEx überlegen ob er den Block "698874/6387/01" einmal als Gruppe rauszieht und dann splittet, oder man lässt sich die einzelnen Werte direkt als einzelne Gruppen geben (sorry, an die RegEx-Experten, falls ich hier die Bezeichnung Gruppen nicht ganz richtig verwende).

Der RegEx kann hier aber gleich ganz viele Rahmenbedingungen sicher stellen, z.B.:
  • dass nur Ziffern vorkommen (-> \d)
  • dass die Anzahl der Ziffern jeweils in einem gültigen Bereich ist (hier mindestens 1, könnte man aber auch noch anders festlegen)
  • ...

Natürlich kann man das alles auch ohne einen RegEx machen. Aber man sollte das Rad nicht grundlos neu erfinden.

Wenn du jetzt nur einen Vorteil nennen könntest, den man hätte, wenn man keinen RegEx verwendet, wäre ich dir dankbar. Nicht alles was funktioniert ist eine vernünftige Lösung.

Ich bin bei dir, der TE könne ruhig noch etwas mehr sagen, was er genau braucht.
 
  • Gefällt mir
Reaktionen: Augen1337
genauer wirds schwer, im Grunde würde es mir erstmal reichen ohne umweg über regex, am besten per vba immer den wert nach KundenAuftragEinsatzart zu bekommen, sofern in der gleichen zelle nach dem KundenAuftragEinsatzart Zahlen vorkommen. Das müsste mir schon reichen also wenn in einer zeile der Begriff KundenAuftragEinsatzart UND Zahlen die nachfolgend vorhanden sind erkannt werden dann alles nach KundenAuftragEinsatzart in variable oder zelle (was einfacher ist).

Hilft das so formuliert?
 
"KundenAuftragEinsatzart UND Zahlen" -> genau das schreit ja gerade zu nach RegEx.

Ich verstehe dich nicht, warum "ohne Umweg über RegEx, am besten per VBA". - Es hört sich für mich so an, als würdest du beides immer noch in Konflikt zueinander sehen?

Und ja, man kann alles auch mit einfachen String-Operationen machen.
 
Dann will ich mal eine Frage stellen…
Selbst wenn ich mit SPLIT oder REGEX etwas zerteile - wie soll der Befehl wissen was er da vor sich hat? Wie viele Schnipsel es ergibt?
Zwar habe ich ein evtl. Muster, aber wie zuverlässig ist das?
Mir kommen die gebotenen Lösungen nicht zielführend vor. Wo ist denn ein bisschen Code das aus den Beispielen stets das Richtige zurückgibt?

CN8
 
Das ist nur mal hingefrickelt... weil es nicht mein Problem ist und ich nach wie vor nicht genau weiß, was der TE will...
Code:
Public Sub test()

    Dim text As String
    Dim regEx As Object
    Dim objMatches As Object
    Dim allMatches As Object
    Dim a
  
    Set regEx = CreateObject("Vbscript.regexp")

    With regEx
        .IgnoreCase = False
        .Global = True
        .Pattern = "^KundenAuftragEinsatzart\s(\d+)\/(\d+)\/(\d+)"
    End With

    For i = 1 To 10
      
        text = Cells(i, 1)
      
        If regEx.test(text) Then
            Cells(i, 2) = "ja"
            Set allMatches = regEx.Execute(text)
            For Each Match In allMatches
                a = Match.submatches.Count
                For j = 0 To a - 1
                    Cells(i, 2 + j) = Match.submatches.Item(j)
                Next
            Next
        Else
            Cells(i, 2) = text + " kein Match"
            Cells(i, 3) = ""
            Cells(i, 4) = ""
        End If
      
    Next i
End Sub

1613682276231.png


Aber bin offen für zielführendere Lösungen.

(Die fehlenden Trumps, äh führenden Nullen liegt an der Zell-Formatierung von Excel, bei Standart/Zahlen werden die halt in der Darstellung entfernt
1613682854940.png
)
 
Zuletzt bearbeitet:
mhhh ich teste es am Montag direkt mal, vielen Dank das du dich da drangesetzt hast.
BEi den Beispielen würde die Lösung so aussehen:

Buxtehude /1234 KundenAuftragEinsatzart 698874/6387/01
KundenAuftragEinsatzart 698874/6387
Musterstadt /1234 KundenAuftragEinsatzart 698874/6387/01
KundenAuftragEinsatzart 698874/6387/01
KundenAuftragEinsatzart 698874/6387/01
=Lösung:
698874/6387/01
698874/6387
698874/6387/01
698874/6387/01
698874/6387/01
 

Ähnliche Themen

Zurück
Oben