TIA String zerlegen- Aufruf im OB?

donkey

Member
Beiträge
24
Punkte Reaktionen
0
Zuviel Werbung?
->Hier kostenlos registrieren
Hallo zusammen,

ich hatte vor Kurzem schon einmal eine Frage zu dem gleichen "Test-Projekt". An dieser Stelle nochmal vielen Dank an alle, die geholfen haben :)

Nun zum neuen "Problem". Die Lösung ist bestimmt super einfach, nur komme ich nicht darauf (bin noch nicht so lange im Thema):

Ich habe einen String, der zerlegt wird. Mithilfe von Find/Left/ Delete finde ich zuerst das Semikolon, kopiere den Wert mit Left um und lösche diesen dann aus dem String, um wieder von Neuem nach einem Semikolon zu suchen. Soweit so gut...

Um den String zu simulieren, habe ich einfach einen Startwert im DB festgelegt (siehe Bild 1). Problem ist nun, dass ich ohne eine erneute Zuweisung des Startwertes im FB ("String_Test".Test_String := '001;Kunde;Hersteller'; siehe Bild 2) kein Ergebnis bekomme: Die einzelnen Werte im DB werden nicht angezeigt.
Ich vermute, dass es am zyklischen Aufruf im OB1 liegt ? Ich habe in einem anderen Beitrag gelesen, dass ein Aufruf im OB100 Abhilfe schaffen soll - das hat leider nicht funktioniert.

Hat jemand eine Lösung?

Vielen Dank!
 

Anhänge

  • Bild 1.PNG
    Bild 1.PNG
    22,2 KB · Aufrufe: 36
  • Bild 2.PNG
    Bild 2.PNG
    5,7 KB · Aufrufe: 39

SPS-freak1

Well-known member
Beiträge
379
Punkte Reaktionen
45
Hi,

Das Problem liegt wie du schon vermutet hast an der Zyklischen Abarbeitung einer SPS.
Denk doch Mal über dein Programm nach: wenn du mit Delete die gefundenen Zeichen löscht, dann hast du ja nach der Abarbeitung keine Zeichen mehr in deinem Test String stehen. Wird der Baustein im nächsten Zyklus wieder aufgerufen, dann musst du diesen String ja wieder Daten zuweisen um wieder was zu zerlegen.
Der deklarieren Stratwert ist ja nur im allerersten Zyklus nachdem der Baustein geladen wurde aktiv danach wird der zur Laufzeit veränderte String gespeichert.
Oder habe ich das Problem nicht so ganz verstanden?!
Wenn es an der Beobachtung im DB liegt, kann wahrscheinlich der Beobachtungszeitpunkt ein Problem sein, da ja kurz nach der Zuweisungen die Daten schon wieder gelöscht werden.

Gesendet von meinem M2007J3SG mit Tapatalk
 
OP
D

donkey

Member
Beiträge
24
Punkte Reaktionen
0
Zuviel Werbung?
->Hier kostenlos registrieren
Danke für deine Antwort.
So weit war ich gedanklich auch schon... ich bin derzeit auf der Suche nach einer Lösung ohne meinen kompletten Ansatz mit Find/Left/Delete zu verwerfen. Ich möchte halt diese Zuweisung im FB (Bild 2) anders realisieren. Mit dieser Zuweisung hat es bisher ja funktioniert, nur bringt es mir nichts, wenn ich den Wert so zuweise, wie ich es bisher gemacht habe. Schließlich weiß ich letztendlich nicht, welche genauen Daten im String stehen...
Ein wenig verwirrend alles :D
 

JSEngineering

Well-known member
Beiträge
908
Punkte Reaktionen
198
Da das Programm zyklisch arbeitet und Du aber nur "ab und zu" eine Zuweisung des Strings machst in der realen Anlage (z.B. durch einen übertragenen Datensatz oder einen Scanner), dann mußt Du einen Trigger setzen, mit dem Du diese Verarbeitung genau ein Mal machst und danach wartest, daß der String wieder befüllt wurde.

Ist ja auch verschwendete Rechenzeit, ein und den selben String in jedem Zyklus neu zu zerlegen...
 

Heinileini

Well-known member
Beiträge
3.729
Punkte Reaktionen
717
Hattest Du denn mal dies probiert?
Dadurch wird der ursprüngliche String nicht nach und nach verändert/gekürzt und die Zerlegung findet in 1 Zyklus statt.
 

Marvm

Member
Beiträge
6
Punkte Reaktionen
5
Zuviel Werbung?
->Hier kostenlos registrieren
Zum testen kannst du doch erstmal deinen Teststring in einen Zwischenspeicher kopieren, dann mit dem Zwischenspeicher weiter arbeiten.
Dann wird in jedem SPS Zyklus dein Teststring in den Zwischenspeicher kopiert und aus dem Zwichenspeicher gesucht und gelöscht, dein Originalstring ändert sich nicht.

OB1:
Suchen := ';';
#Zwischenspeicher := "String_Test".Test_String;
#Sem1 := FIND(IN1:= #Zwischenspeicher, IN2:= #Suchen)
usw.
 

Larry Laffer

Supermoderator
Teammitglied
Beiträge
12.961
Punkte Reaktionen
2.677
Danke für deine Antwort.
So weit war ich gedanklich auch schon... ich bin derzeit auf der Suche nach einer Lösung ohne meinen kompletten Ansatz mit Find/Left/Delete zu verwerfen. Ich möchte halt diese Zuweisung im FB (Bild 2) anders realisieren. Mit dieser Zuweisung hat es bisher ja funktioniert, nur bringt es mir nichts, wenn ich den Wert so zuweise, wie ich es bisher gemacht habe. Schließlich weiß ich letztendlich nicht, welche genauen Daten im String stehen...
Ein wenig verwirrend alles :D

Der Fehler, den du gemacht hast, ist die Zerlegung mit deinem Original-String zu machen.
Nimm den Original-String und kopiere ihn vor der Be-Ver-Arbeitung in einen temporären (Hilfs-)String um. Den zerlegst du dann - das kannst du dann auch in jedem Zyklus machen (was allerdings nicht sehr professionell ist) und wirst dann immer das gleiche Ergebnis bekommen. Das hatte ich dir aber in dem anderen Thread auch so vorgeschlagen ...

Gruß
Larry
 
OP
D

donkey

Member
Beiträge
24
Punkte Reaktionen
0
Hallo Larry,

erstmal vielen Dank für deine Antwort.

Ich habe deinen Lösungsvorschlag letztes Mal schon probiert und gerade noch einmal. Ich scheine grundlegend irgendwas falsch zu machen...

Im Bild 1 kann man sehen, dass ich versucht habe den Wert vom String in einen Zwischenspeicher zu kopieren. Ergebnis: Beobachtungswert im FB und im DB = 0.

Bild 2: Daraufhin habe ich wie zuvor auch (was ich ja eigentlich vermeiden wollte) dem String wieder einen Wert zugewiesen und wieder in einen Zwischenspeicher kopiert. Ergebnis: Im DB wird wieder nichts nagezeigt, der FB zeigt an, dass dem Original-String einen Wert zugewiesen wurde, dem Zwischenspeicher jedoch nicht.

Liegt es vielleicht an dem Startwert? In der realen Anlage kommt der String ja von "außen".

@HeiniLeini ich habe es mir letztens angeschaut. Ich schaue es mir morgen mal genauer an. Ist wahrscheinlich eine schönere Lösung als meine bisherige. Danke dafür :)

Gruß, Donkey


Bild 1.jpg Bild 2.jpg
 

Marvm

Member
Beiträge
6
Punkte Reaktionen
5
Zuviel Werbung?
->Hier kostenlos registrieren
Bei Bild 1 und bei Bild 2 speicherst du den Zwischenspeicher in der "String_Test".Test_String Variable.
Du müsstest die "String_Test".Test_String Variable in dem Zwischenspeicher speichern und mit dem Zwischenspeicher weiterarbeiten.
Bei dir ist es aktuell falsch herum.
 

Larry Laffer

Supermoderator
Teammitglied
Beiträge
12.961
Punkte Reaktionen
2.677
Ich kann daraus so gar nichts ersehen - sorry ...
Wie wäre es, wenn du deinen bisherigen Code hier einstellst ? Dann kann man ganz konkret genau darauf eingehen ...
Aber grundsätzlich : in deinem ersten Beitrag hier weißt du dem "String_Test".Test_String einen festen Inhalt zu und arbeitest dann mit genau dieser Variable weiter - und genau das ist eben falsch.
Wenn "String_Test".Test_String deine Ausgangs-Variable sein soll dann musst du diese in den Hilfs-String kopieren (in SCL wäre das dann HilfsString := "String_Test".Test_String ;) und alles Weitere muss dann mit HilfsString passieren ...
Mach das mal so ...

Gruß
Larry
 
OP
D

donkey

Member
Beiträge
24
Punkte Reaktionen
0
Guten Morgen,

ich habe die Tipps umgesetzt und sende mal den Code. Irgendwas scheint immer noch falsch zu sein :/
Außerdem lade ich noch Screenshots von der Bausteinschnittstelle und dem DB hoch.
Vielen Dank euch allen!


#Suchen := ';';


"String_Test".Test_String_Zwischenspeicher := "String_Test".Test_String;


// 1. Semikolon suchen
#Sem1 := FIND(IN1 := "String_Test".Test_String_Zwischenspeicher, IN2 := #Suchen);


// 1. Zeichen
"String_Test".Daten.Nummer := LEFT(IN := "String_Test".Test_String_Zwischenspeicher, L := #Sem1 - 1);
"String_Test".Test_String_Zwischenspeicher := DELETE(IN := "String_Test".Test_String_Zwischenspeicher, L := #Sem1, P := 1);


//2 .Semikolon suchen
#Sem2 := FIND(IN1 := "String_Test".Test_String_Zwischenspeicher, IN2 := #Suchen);


//2. Zeichen
"String_Test".Daten.Kunde := LEFT(IN := "String_Test".Test_String_Zwischenspeicher, L := #Sem2 - 1);
"String_Test".Test_String_Zwischenspeicher := DELETE(IN := "String_Test".Test_String_Zwischenspeicher, L := #Sem2, P := 1);


// 3. Zeichen
"String_Test".Daten.Hersteller := LEFT(IN := "String_Test".Test_String_Zwischenspeicher, L := 12);
#LängeZeichen3 := LEN("String_Test".Test_String_Zwischenspeicher);
"String_Test".Test_String_Zwischenspeicher := DELETE(IN := "String_Test".Test_String_Zwischenspeicher, L := #LängeZeichen3, P := 1);


Bausteinschnittstelle FB1.PNG DB.PNG
 

Marvm

Member
Beiträge
6
Punkte Reaktionen
5
Zuviel Werbung?
->Hier kostenlos registrieren
Ich habe es mal nachgebaut, bei mir funktioniert es.
Du hast bei deinem angehangenen Bildern in dem Datenbaustein keinen Inhalt in dem Test_String.
Den hast du warscheinlich gelöscht oder beim testen überschrieben.

OB1.JPG DB.JPG
 

Marvm

Member
Beiträge
6
Punkte Reaktionen
5
Ansonten wäre es bei einer S7-1500 SPS auch so möglich:
mit der Funktion String_to_Char die einzelnen Zeichen in ein Array kopieren
mit der Funktion Split werden die Zeichen zwischen den Semikolons herauskopiert und als einzelne Strings gespeichert.

OB1.JPG DB.JPG
 
OP
D

donkey

Member
Beiträge
24
Punkte Reaktionen
0
Hallo Marvm,

vielen Dank für deine Bemühungen!

ich habe beides mal ausprobiert: Funktioniert beides :) Beim Ersten habe ich die Startwerte als Aktualwerte geladen. Dann passte es...

Mit deiner Split-Funktion hat es auch funktioniert. Ich suche gleich mal nach einer Möglichkeit, die einzelnen Werte, die nun untereinander im "Charray" stehen, zusammen zu bringen.
 

Marvm

Member
Beiträge
6
Punkte Reaktionen
5
Zuviel Werbung?
->Hier kostenlos registrieren
Die Funktion "Join" macht genau das gegenteil von Split, also die einzelnen Zeichenketten mit einen Auswählbaren trennzeichen (";") zusammensetzen.
Die Funktion "Chars_TO_Strg" macht genau das gegenteil von "Strg_TO_Chars", also aus dem Array of Char wieder eine Zeichenkette.
 
Oben