Zeichenfolge zwischen zwei Unterstrichen in neue Zelle kopieren

Pr3d4tor

Mitglied
Guten Morgen zusammen,

ich könnte mal wieder Hilfe von den Profis hier gebrauchen.

Über eine Userform lassen ich unteranderem auch CSV Datei in ein Tabellenblatt einlesen und mir gleichzeichtig, zwecks weiterverarbeitung,
den Dateinamen in eine Zelle schreiben. Dieser ist im Grunde immer gleich "Aufgebaut" und da ich nur ein Teilstück davon benötige wollte ich mir diesen nun per
Instr, Instrev und Mid aus der Zelle rausholen.

Der Dateiname sieht wie folgt aus: (was mir auch in der ersten MsgBox wiedergegeben wird)
1. cito001_LULUXCACN_PZ46_DI_SA_DRITTLAND_20210422074609.csv
2. cito001_GBCVTBACN_DRITTLAND_033_Di_Fr_20210422051506.csv
3. adwfwm_NLHAGIACE_Export_028_DI_SA_20210422074803.csv

Und der Code zum Testen über einen Button sieht so aus:
Visual Basic:
Private Sub CommandButton13_Click()
 Worksheets("Tabelle2").Select
    Dim pstrInt As Variant
    Dim l As Long
    Dim r As Long
    Dim pstrX As String
 
    pstrInt = Cells(1, 5).Value
MsgBox pstrInt  '# Kontrolle ob Zelle richtig erkannt wurde
        If pstrInt > 0 Then
        l = InStr(1, pstrInt, "_") + 1
        r = InStrRev(pstrInt, "_")
        pstrX = Mid(pstrInt, r - l)
    End If
    
MsgBox pstrX    '# Kontrolle von ausgeschnittener Zeichenfolge
End Sub

In der Zweiten MsgBox erhalte ich allerdings immer nur:
Zu 1. bekomme ich allerdings immer nur "DRITTLAND_20210422074609.csv"
Zu 2. "033_Di_Fr_20210422051506.csv"
Zu 3. "028_DI_SA_20210422074803.csv"

Ich dachte schon daran das es vielleicht an einem anderen Teil im gesamt Code liegt aber auch nur mit dem CommandButton
und einem von Hand kopierten Dateinamenn in die Zelle erhalte ich die selben Ergebnisse.

Was übersehe ich? oder wo liegt mein Fehler?
Das l = InStr(1, pstrInt, "_") + 1 anscheinend nicht das erste "_" erkennt sondern immer 2 bis 3 "-" überspringt?
Ich habe auch schon etliche verschiedene Möglichkeiten versucht aber die Lösung war noch nicht dabei.

Wäre schon wenn mir jemand Sagen könnte worans liegt.



VG und nen schönen Start in die neue Woche.
 

Yaslaw

n/a
Moderator
Wie ich das sehe, willst du alles zwischen dem Ersten und dem letzten _
Grundsätzlich, schau mal den Mid Befehl an. Mid(Text, Start, Länge)
Du verwendest aber Mid(Text, Länge)

Grundsätzlich rate ich aber immer von solchen Konstruktionen ab und empfehle RegEx zu lernen. Den kann man in diversen Sprachen brauchen und auch gute Texteditoren erlauben das Suchen mit RegEx

Etwa so (ungetesteter Code)
Visual Basic:
Function getMiddlePart(ByVal iString As String) As String
  Dim rx As Object
  Set rx = CreateObject("VBScript.RegExp")
  rx.Pattern = "^[^_]+_(.*)_[^_]+$"   'Pattern Test: https://regex101.com/r/kbBlZS/1
  If rx.test(iString) Then getMiddlePart = rx.execute(iString)(0).SubMatches(0)
End Function

regex101: build, test, and debug regex

Erläuterungen zum Pattern
^ TextAnfang
[^_]+ Alle Zeichen ausser _ und das ganze mindestens einmal
_ Das Zeichen _
() Den Teil in der Klammer wollen wir haben
.* Jedeszeichen - wiederholend
_[^_]+ Analog zum Anfang. Also ein _ gefolgt von diversen Zeichen die kein _ sind
$ Textende
 

Zvoni

Erfahrenes Mitglied
Oder du machst es ohne RegEx, aber dafür sollten wir wissen, was du überhaupt zurück erwartest (von 1, 2 und 3)
Also:
Ist
Soll

Einfach von Hand hier reinschreiben: Was schickst du in die Funktion, und was erwartest du zurück?
Weil ich habe da eine Vermutung.....

EDIT: Falls es so ist, wie Yaslaw vermutet....
Visual Basic:
Private Function MyJoin(ByRef AString As String, Optional ByVal ADelimiter As String = "_") As String
Dim aTmp() As String
Dim aTempArray() As String
Dim i As Long
Dim s As String
Dim l As Long
    l = InStrRev(AString, ".")
    aTmp = Split(AString, ADelimiter)
    ReDim aTempArray(0 To UBound(aTmp) - 2)
    For i = 1 To UBound(aTmp) - 1
        aTempArray(i - 1) = aTmp(i)
    Next
    s = Join(aTempArray, ADelimiter)
    MyJoin = s & "." & Right$(AString, Len(AString) - l)
End Function

Aufruf dann mit
pstrX = MyJoin(Cells(1, 5).Value)

1)
Ist: cito001_LULUXCACN_PZ46_DI_SA_DRITTLAND_20210422074609.csv
Ergibt: LULUXCACN_PZ46_DI_SA_DRITTLAND.csv
2)
Ist: cito001_GBCVTBACN_DRITTLAND_033_Di_Fr_20210422051506.csv
Ergibt: GBCVTBACN_DRITTLAND_033_Di_Fr.csv
3)
Ist: adwfwm_NLHAGIACE_Export_028_DI_SA_20210422074803.csv
Ergibt: NLHAGIACE_Export_028_DI_SA.csv

EDIT2:
Wie ich das sehe, willst du alles zwischen dem Ersten und dem letzten _
Grundsätzlich, schau mal den Mid Befehl an. Mid(Text, Start, Länge)
Du verwendest aber Mid(Text, Länge)
Stimmt.
Wenn, dann müsste es eher so sein (ungetestet):
pstrX = Mid(pstrInt, l, r - l)
 
Zuletzt bearbeitet:

Pr3d4tor

Mitglied
Nabend zusammen,

erst einmal Sorry wegen der Verwirrung und dem vergessen Teilstück das gesucht wird.
Vielleicht sollte nach einer Nachtschicht doch besser keine Beiträge verfassen :)

@Yaslaw
Danke für die Erklärung von RegEx, kann man bestimmt nochmal gebrauchen.

@Zvoni
Danke für den Hinweis bezüglich Mid

Nachdem ich mich dann nochmals auf die Suche nach einer, für mich verständlichen und ausführlichen Beschreibung, von Mid gesucht habe bin ich auf eine Seite gestoßen in der Instrrev ebenfalls deutlich besser erklärt wurde.
Ich brauche aus dem jeweiligen Dateinamen nur den Teil zwischen dem ersten "_" von Links und dem letzten "-" von Rechts nach Links also LULUXCACN, GBCVTBACN usw.

Was ich bis gerade eben aber wirklich nicht wusste und bisher auch irgendwie nie wirklich so Erklärt wurde wie gerade eben ist die Tatsache das ich bei Instrrev auch angeben kann ab wie vielen Zeichen von Links aus er Anfangen soll zu suchen.

Und nachdem ich nun den Code umgestellt habe:
Visual Basic:
        l = InStr(pstrInt, "_") + 1
        r = InStrRev(pstrInt, "_", 20)
        pstrX = Mid(pstrInt, l, r - l)

klappt es bisher bei jedem Versuch.


VG
 

Neue Beiträge