Das Notes Forum

Domino 9 und frühere Versionen => ND9: Entwicklung => Thema gestartet von: Jürgen Schomann am 24.03.16 - 16:19:47

Titel: Fehler bei Split bzw. StrToken mit leeren Werten
Beitrag von: Jürgen Schomann am 24.03.16 - 16:19:47
Ich habe folgenden Agenten:

Dim v As Variant
Dim s$
Dim d$
   
s = "1~~2~~3"
v = Split(s, "~~")
ForAll e In v
   d = d & Chr(10) & e
End ForAll
MsgBox d

Dieser liefert richtig

1
2
3

wenn oben s = "1~~~~3" ist aber falsch

1
~~3
~3
3

Das passiert nur wenn die Trennzeichen mehrere gleiche Zeichen, wie hier '~~', sind.
Die betrifft außerdem nur Werte innerhalb, '~~2~~3' oder '1~~2~~' verhalten sich bezüglich 1. bzw. 3. Wert richtig

Analog verhält sich auch StrToken, z. B. liefert StrToken("1~~~~3", "~~", 2) die Zeichenfolge '~~3'.
@Word dagegen arbeitet richtig und liefert in dem Fall eine leere Zeichenkette.
@Explode ist ja leider nicht für Separatoren mit mehr als einem Zeichen möglich.

Noch problematischer wird es z. B. mit '1~~~~~~4'
Gibt es eine Idee für eine Umgehung des Problems, ggf. wohl nur über Instr?
Titel: Re: Fehler bei Split bzw. StrToken mit leeren Werten
Beitrag von: cebolina am 24.03.16 - 16:54:04
versuch mal

Code
...
v = Fulltrim(Split(s, "~"))
...

Gruß Stefan
Titel: Re: Fehler bei Split bzw. StrToken mit leeren Werten
Beitrag von: Jürgen Schomann am 24.03.16 - 18:33:02
Vielen Dank für deine Antwort, aber das bringt mir nichts, denn dann gehen die leeren Werte verloren.
Ich brauche aber auch die leeren Werte für weitere Auswertungen.
Titel: Re: Fehler bei Split bzw. StrToken mit leeren Werten
Beitrag von: Jürgen Schomann am 25.03.16 - 12:25:01
Noch eine Ergänzung
Folgendes Beispiel liefert sogar den Fehler 'String too large'

Dim v As Variant
Dim s$
   
s = "1~~~~~~3"
v = Split(s, "~~~")

Sowie das Trennzeichen aus mehreren gleichen Zeichen > 2 besteht kommt dieser Fehler, so z. B. auch bei '~~~~'.
Zur Vermeidung, dass ein gewähltes Trennzeichen selbst in den Werten vorkommt, werden oftmals Trennzeichenfolgen mit Sonderzeichen und Länge > 1 gewählt.
Das ist in vielen Fremdanwendungen bei uns der Fall. Oftmals sind in diesen Werte optional und dadurch leer.
Titel: Re: Fehler bei Split bzw. StrToken mit leeren Werten
Beitrag von: Jürgen Schomann am 25.03.16 - 14:07:46
Und noch eine Ergänzung

StrToken("12", "+", 1) ergibt '12'
StrToken("1", "+", 1) ergibt '1'
StrToken("12", "+=", 1) ergibt '12'
aber StrToken("1", "+=", 1) ergibt leer obwohl die Trennzeichenkette aus verschiedenen Zeichen besteht.

Die Funktionen Split und StrToken arbeiten beide sehr unzuverlässig sowie die Trennzeichenkette eine Länge > 1 hat.
Es bleibt wohl leider nur der mühsamere Weg selbst in einer Schleife mit der InStr-Funktion die Zeichenketten zu analysieren, oder?
Titel: Re: Fehler bei Split bzw. StrToken mit leeren Werten
Beitrag von: jBubbleBoy am 25.03.16 - 16:35:45
Verwende vorher ein Replace:

Code
Dim s$, v	
s = "1~~~~~~3"
s = Replace(s,"~~","#")		
v = Split(s,"#")

s = ""
ForAll x In v
	s = s + Chr(10) + x 
End ForAll
	
MsgBox s

dann klappt es
Titel: Re: Fehler bei Split bzw. StrToken mit leeren Werten
Beitrag von: Jürgen Schomann am 25.03.16 - 19:16:23
Vielen Dank für den Hinweis. diese Idee hatte ich auch schon aber dann wieder verworfen.
Z. B. wird dies dann falsch:

s = "1~~~~#3"

nach Replace(s, "~~", "#") wird s = "1###3"
und Split(s, "#") liefert dann 1, leer, leer, 3 statt richtig 1, leer, #3
Titel: Re: Fehler bei Split bzw. StrToken mit leeren Werten
Beitrag von: jBubbleBoy am 25.03.16 - 19:22:26
# war nur ein Beispiel, ich verwende gern seltene, vom User & System so gut wie nie verwendete Zeichen, z.B. die Schildkröte: ¤
Und die ist noch unwahrscheinlicher als die Tilde ~  ;)
Aber ein Restrisiko gibt es immer, wenn alle Zeichen vorkommen können.
Titel: Re: Fehler bei Split bzw. StrToken mit leeren Werten
Beitrag von: jBubbleBoy am 25.03.16 - 19:50:59
Ergänzend möchte ich noch erwähnen, das man dem Problem vorbeugen kann indem man keine einfache Trennzeichenfolge wählt, z.B:
Code
Dim s$, v
s = "1~¤~¤~¤3"
v = Split(s,"~¤")

s = ""
ForAll x In v
	s = s + Chr(10) + x 
End ForAll
	
MsgBox s
Also ~¤ anstatt ~~ und auch das, nur ein Beispiel, der Key kann beliebig lang sein.
Das sollte man machen, wenn wirklich alles an Zeichen vorkommt. Kann auch für ein Replace genutzt werden, wenn ~~ eine feste Vorgabe ist.
Titel: Re: Fehler bei Split bzw. StrToken mit leeren Werten
Beitrag von: Peter Klett am 26.03.16 - 15:50:24
Zwei gleiche Zeichen als Trennzeichen zu verwenden, um das Vorhandensein eines Zeichens in den Daten zu ermöglichen, ist m.E. nicht wirklich eine gute Idee. Was sollte bei

Split ("1~~~~~3", "~~") herauskommen?

1

~3

und

1
~
3

sind beides gültige Ergebnisse und zeigen, dass es nicht funktionieren kann.
Titel: Re: Fehler bei Split bzw. StrToken mit leeren Werten
Beitrag von: Jürgen Schomann am 26.03.16 - 21:59:13
Nochmals vielen Dank für die Hinweise.

Ich hatte schon erwähnt, das dies in Fremandwendungen so vorkommt.
Natürlich muss eine Trennzeichenfolge möglichst falsche Treffer vermeiden und ich würde auch nicht mehrfach gleiche Zeichen verwenden.
Aber trotzdem arbeiten StrToken und Split nicht korrekt.

Peter zu Split("1~~~~~3, "~~")
hier gibt es nur ein richtiges Ergebnis nämlich 1, leer, ~3 wenn von links nach rechts durchsucht wird.
Nach der 1 wird ~~ gefunden, also 1. Wert 1.
Dann wird ab 1~~ das nächste ~~ gesucht und gleich anschließend gefunden, also 2. Wert leer.
Schließlich wird ab 1~~~~ das nächste ~~ gesucht und nicht mehr gefunden, also 3. Wert ~3.

Übrigens hatte ich schon in einer vorhergehenden Antwort den Fall StrToken("1", "+=", 1) ergibt leer erwähnt., der auch falsch ist.

Titel: Re: Fehler bei Split bzw. StrToken mit leeren Werten
Beitrag von: Peter Klett am 26.03.16 - 23:19:30
Und wie würdest Du dann die Daten

1
~
3

mit Trennzeichen "~~" schreiben?

Damit beweist Du ja, dass meine Aussage zutrifft, dass bei 1~~~~~3 keine korrekte Entschlüsselung möglich ist.

Bei solchen Funktionen verlassen wir uns nicht auf die standardmäßig gelieferten, sondern bauen diese selbst und stellen die über eine Scriptbibliothek in allen Anwendungen zur Verfügung. Vorteil ist, dass man das Verhalten selbst im Griff hat. Allerdings kann man damit auch das o.g. Problem nicht lösen.

Neulich musste ich große Datenmengen auf diese Weise zerlegen. Mit unseren eigenen Methoden brauchte das Script 5 Minuten, habe es dann testweise auf Split umgestellt und brauchte danach 10... Kein weiterer Kommentar.

Titel: Re: Fehler bei Split bzw. StrToken mit leeren Werten
Beitrag von: Jürgen Schomann am 27.03.16 - 13:45:07
Du hast ja Recht, wir haben auch eigene Funktionen, meine Beispiele sind auch bewusst konstruiert gewesen.

Ich wollte damit ja nur zum Ausdruck bringen, dass die Standardfunktionen nicht korrekt arbeiten.

Replace("1~~~~~3", "~~", "#") egibt ja auch 1##~3, also korrekt von links nach rechts nur Split/StrToken arbeiten eben konsequenter Weise nicht analog. Wenn ja wäre es ja ok.
Und wozu Standardfunktionen, wenn diese doch nicht angewandt werden sollten. Man muss ja nicht jede Standardfunktion selbst nachempfinden.
Dann könnte man ja gleich auf Betriebssystemebene allles bitweise selbst machen.

So nichts für ungut und ein schönes Osterfest.
Titel: Re: Fehler bei Split bzw. StrToken mit leeren Werten
Beitrag von: Peter Klett am 27.03.16 - 17:19:16
...
Ich wollte damit ja nur zum Ausdruck bringen, dass die Standardfunktionen nicht korrekt arbeiten.
...
Das ist auch ein wirklich wertvoller Hinweis. Habe das gerade mal nachgebaut und komme zum selben Ergebnis. Unsere eigene Funktion hat damit keine Probleme. Wenn man bedenkt, dass unsere Funktion mit ein bißchen Kommentar etwa 40 Zeilen lang ist, ist es schon peinlich, dass die Standardfunktion nicht korrekt arbeitet, das ist ja nun wirklich kein Hexenwerk.

Vor Jahren hatte ich schon mal darüber nachgedacht, die eigenen Funktionen, die teilweise noch aus Notes-4-Zeiten stammen, weil es damals noch kein Split usw. gab, durch die Standardfunktionen zu ersetzen, sehe mich nun aber bestätigt, dass es eine gute Idee war, das zu lassen.