# SCL Stringzerlegung



## merlin (29 November 2007)

Hallo

Ich bekomme aus einer Presse einen verketteten Ergebnissstring:
"123.4$r$l3456.78$r$l-T -Z"

Die Trennzeichen ($r$l) können an ihrer Position variieren je nachdem wieviele Stellen die Zahle davor hat.
Ich muss nun den verketteten String so zerlegen, das am Ende die Einzelnen Zahlen in REAL ausgegeben werden und der letzte Block als String.

Ich hätte an SCL gedacht bin aber auf SCL absoluter Neuling. Kann mir da wer weiterhefen?

Besten Dank
Thomas


----------



## hugo (29 November 2007)

du findest alle hierzu nötigen bausteine in der open source library oscat
die funktion find_nun and find_nonum dienen dazu zahlen und nicht zahlenzeichen zu suchen.
die lib kannst du downloaden unter www.oscat.lib


----------



## zotos (29 November 2007)

Oh das macht keinen Spaß ;o(

Ich habe eben mal kurz versucht was zu bauen und bin über das $ gestolpert das ist bei den String-Konstanten ein Escape Zeichen und und hat mein Experiment vereitelt. Aber ansich ist die Aufgabe nicht wild. Kannst auch in der Hilfe von SCL unter FIND, LEN, LEFT, RIGHT nachlesen.


----------



## Larry Laffer (29 November 2007)

Hallo,
ich hoffe das zumindestens Grundkenntnisse vorhanden sind.

Du brauchst dafür nicht die Oscat-Lib, Siemens kann das alles auch ...
Ich würde grundsätzlich so vorgehen:
Hilfs-Strings für den Gesamt-String und alle Teil-Variablen anlegen.
Quell-String in Hilfs-String 1 kopieren.
Diesen mittels FIND nach dem 1. "$"-Zeichen durchsuchen.
Ab der zurück-gelieferten Position den linken Teil des Strings mit LEFT abschneiden und in die 1. Teil-Variable kopieren und den rechten Teil des Strings in eine neue Hilfs-Variable kopieren.
Mit dieser dann verfahren wie vorher ...

Das ist auf jeden Fall ein bißchen Probiererei, aber durchaus zu schaffen ...

Gruß
LL


----------



## volker (29 November 2007)

> rechten Teil des Strings in eine neue Hilfs-Variable kopieren.
> Mit dieser dann verfahren wie vorher ...


nicht ganz. das erste zeichen ist dann ja das $.
also 4 zeichen später beginnen (gibts unter scl mid ? )bzw right(reststring,stringlaenge-4)


----------



## Larry Laffer (29 November 2007)

volker schrieb:


> nicht ganz. das erste zeichen ist dann ja das $.
> also 4 zeichen später beginnen (gibts unter scl mid ? )bzw right(reststring,stringlaenge-4)


 
Ein bißchen Spaß mußt du Merlin natürlich auch noch lassen ...


----------



## zotos (29 November 2007)

Also ich stell mal einen Ansatz hier rein. 

Ich behaupte nicht das es der einfachste Weg ist und an den kniffligen Stellen fehlen auch noch Kommentare ;o( Aber gerade das Wandeln von STRING nach Real habe ich mit den Step7 Boardmitteln auf die Schnelle nicht besser hinbekommen.


```
FUNCTION FC10 : VOID
VAR_INPUT
  S             :STRING[40];
  Token         :STRING[5];
END_VAR

VAR_OUTPUT
  T1_real       :REAL;
  T2_real       :REAL;
  T3_string     :STRING[40];
END_VAR

VAR_TEMP
  myString      :STRING[40];
  myToken       :STRING[5];
  myPos         :INT;
  myTeil_1      :STRING[40];
  myTeil_2      :STRING[40];
  myTeil_3      :STRING[40];  
  myINT_1       :INT;  
  myINT_2       :INT;    
END_VAR
  (* Strings Initialisieren *)
  myString      :='';
  myToken       :='';
  myTeil_1      :='';
  myTeil_2      :='';
  myTeil_3      :='';

  (* Eingangs Variablen in Temp Kopieren *)
  myString := S;      //'555.4_r_l3456.78_r_l-T -Z';
  myToken  := Token;  //'_r_l';

  (* Erste Zahl ausschneiden / String *)
  myPos := FIND(IN1:=myString, IN2:=myToken);
  myTeil_1 := LEFT(IN:=myString, L:=myPos - 1);  
  
  myString := RIGHT(IN:=myString, L:=LEN(myString) - myPos - LEN(S:=myToken) + 1);

  (* Erste Zahl ausschneiden / String *)
  myPos := FIND(IN1:=myString, IN2:=myToken);
  myTeil_2 := LEFT(IN:=myString, L:=myPos - 1);  

  (* Rest des Strings Abschneiden *)
  myTeil_3 := RIGHT(IN:=myString, L:=LEN(myString) - myPos - LEN(S:=myToken) + 1);  
  T3_string := myTeil_3;
  
  (* Erste Zahl *)
  (* Teil vor dem Dezimalpunkt Kopieren und in INT wandeln *)
  myPos := FIND(IN1:=myTeil_1, IN2:='.');
  myString := LEFT(IN:=myTeil_1, L:=myPos - 1);  
  myINT_1 := STRNG_I(myString);
  (* Teil nach dem Dezimalpunkt Kopieren und in INT wandeln *)
  myString := RIGHT(IN:=myTeil_1, L:= LEN(myTeil_1) - myPos);  
  myINT_2 := STRNG_I(myString);
  (* Aus den zwei INT teilen einen Real basteln *)
  T1_real := ((INT_TO_REAL(myINT_1) * EXPD(LEN(myString)))  +  INT_TO_REAL(myINT_2)) / EXPD(LEN(myString)) ;

  (* Zweite Zahl *)
  (* Teil vor dem Dezimalpunkt Kopieren und in INT wandeln *)
  myPos := FIND(IN1:=myTeil_2, IN2:='.');
  myString := LEFT(IN:=myTeil_2, L:=myPos - 1);  
  myINT_1 := STRNG_I(myString);
  (* Teil nach dem Dezimalpunkt Kopieren und in INT wandeln *)
  myString := RIGHT(IN:=myTeil_2, L:= LEN(myTeil_2) - myPos);  
  myINT_2 := STRNG_I(myString);
  (* Aus den zwei INT teilen einen Real basteln *)  
  T2_real := ((INT_TO_REAL(myINT_1) * EXPD(LEN(myString)))  +  INT_TO_REAL(myINT_2)) / EXPD(LEN(myString)) ;
END_FUNCTION
```


----------



## jck0815 (9 November 2010)

Hallo,

bin gerade auf den Thread gestoßen, um ihn für Nachfolgende zu vervollständigen:



zotos schrieb:


> Aber gerade das Wandeln von STRING nach Real habe ich mit den Step7 Boardmitteln auf die Schnelle nicht besser hinbekommen.



*IEC-Standardfunktionen für STRING-Variable:*
Mit den IEC-Standardfunktionen FC5, FC16, FC30, FC37, FC38 und FC39  können Sie Variablen im DINT-Format in eine Zeichenkette und umgekehrt  umwandeln.  

FC5 DI_STRNG: Umwandlung einer Variable vom Typ DINT in eine Variable vom Typ STRING,
FC16 I_STRNG: Umwandlung einer Variable vom Typ INT in eine Variable vom Typ STRING,
FC30 R_STRNG: Umwandlung einer Variable vom Typ REAL in eine Variable vom Typ STRING,
FC37 STRNG_DI: Umwandlung einer STRING-Variablen in eine Variable vom Typ DINT,
FC38 STRNG_I: Umwandlung einer STRING-Variablen in eine Variable vom Typ INT,
FC39 STRNG_R: Umwandlung einer STRING-Variablen in eine Variable vom Typ REAL.
 Weitere Informationen finden Sie auch in unserem Beitrag "Welche  Standardfunktionen von STEP 7 gibt es bezüglich Umwandlung und Vergleich  von STRING-Variablen bzw. ASCII-Zeichen?" unter der Beitrags-ID: 10913338.


Grüße


----------



## Aslof (3 Mai 2011)

zotos schrieb:


> Also ich stell mal einen Ansatz hier rein.
> 
> Ich behaupte nicht das es der einfachste Weg ist und an den kniffligen Stellen fehlen auch noch Kommentare ;o( Aber gerade das Wandeln von STRING nach Real habe ich mit den Step7 Boardmitteln auf die Schnelle nicht besser hinbekommen.
> 
> ...



Moin,

Ich hätte eine Frage zu dem LEFT. 

Ich versuche gerade xml file (SAP IDOC) nach einem XML Tag zu durchsuchen. 

Was würde mypos dann  ausgeben ist das die Anfangs oder Endposition?

Das was dort zwischen den Tags steht ist dann z.B. "03-04" wie krieg ich jeweils die ersten beiden Zeichen also 03 und 04 getrennt in zwei Variablen?

Wäre euch wirklich dankbar wenn Ihr einem Noob wie mir helfen könntet :-D


----------



## Ralle (3 Mai 2011)

Aslof schrieb:


> Moin,
> 
> Ich hätte eine Frage zu dem LEFT.
> 
> ...



Deine Frage ist nicht ganz verständlich, da wir deinen XML-code ja nicht kennen.

mypos gibt gar nichts aus, sondern find sucht nach einem bestimmten Zeichen oder einer Zeichenkette und gibt dann mit mypos das erste Auftreten dieser Zeichenkette an. Das findest du, wenn du, wenn du in der Standard-Library unter IEC-Functions die Funktion Find markierst und dann "F1" drückst.



> Die Funktion FC 11 liefert die Position der zweiten Zeichenkette (IN2) innerhalb der ersten Zeichenkette (IN1). Die Suche beginnt links; es wird das erste Auftreten der Zeichenkette gemeldet. Ist die zweite Zeichenkette in der ersten nicht vorhanden, wird Null zurückgemeldet. Die Funktion meldet keine Fehler.



PS: und hier noch Left:



> Die Funktion FC 20 liefert die ersten L Zeichen einer Zeichenkette. Ist L größer als die aktuelle Länge der STRING*Variable, wird der Eingangswert zurückgeliefert. Bei L = 0 und bei einem Leerstring als Eingangswert wird ein Leerstring zurückgeliefert. Ist L negativ wird ein Leerstring ausgegeben und das BIE*Bit auf "0" gesetzt.


----------



## Aslof (3 Mai 2011)

Ralle schrieb:


> Deine Frage ist nicht ganz verständlich, da wir deinen XML-code ja nicht kennen.
> 
> mypos gibt gar nichts aus, sondern find sucht nach einem bestimmten Zeichen oder einer Zeichenkette und gibt dann mit mypos das erste Auftreten dieser Zeichenkette an. Das findest du, wenn du, wenn du in der Standard-Library unter IEC-Functions die Funktion Find markierst und dann "F1" drückst.
> 
> ...



Das XML file sieht so aus:

<?xml version="1.0" encoding="UTF-8"?><WMTOID01><IDOC BEGIN="1"><EDI_DC40 SEGMENT="1"><TABNAM>EDI_DC40</TABNAM><MANDT>901</MANDT><DOCNUM>0000000000653782</DOCNUM><DOCREL>640</DOCREL><STATUS>30</STATUS><DIRECT>1</DIRECT><OUTMOD>2</OUTMOD><IDOCTYP>WMTOID01</IDOCTYP><MESTYP>WMTORD</MESTYP><STDMES>WMTORD</STDMES><SNDPOR>SAPG73</SNDPOR><SNDPRT>LS</SNDPRT><SNDPRN>G73CLNT901</SNDPRN><RCVPOR>HRL_660</RCVPOR><RCVPRT>LS</RCVPRT><RCVPRN>HTWAA_680</RCVPRN><CREDAT>20110414</CREDAT><CRETIM>150538</CRETIM><SERIAL>20110213184129</SERIAL></EDI_DC40><E1LTORH SEGMENT="1"><LGNUM>680</LGNUM><TANUM>0000000132</TANUM><BWLVS>601</BWLVS><TRART>A</TRART><BETYP>L</BETYP><BENUM>0000000000</BENUM><BNAME>INABAP-06</BNAME><PERNR>00000000</PERNR><SOLWM>         0.000</SOLWM><SOLEX>         0.000</SOLEX><ISTWM>         0.000</ISTWM><STDAT>00000000</STDAT><ENDAT>00000000</ENDAT><STUZT>000000</STUZT><ENUZT>000000</ENUZT><SWABW>0000</SWABW><VBTYP>J</VBTYP><TAPRI>02</TAPRI><E1LTORI SEGMENT="1"><TAPOS>0001</TAPOS><MATNR>MAOAM-6801-COLA</MATNR><WERKS>1000</WERKS><MEINS>ST</MEINS><LETYP>E1</LETYP><WDATU>20080825</WDATU><WENUM>4900033558</WENUM><WEPOS>0005</WEPOS><VLTYP>682</VLTYP><VLBER>001</VLBER><VLPLA>04-04</VLPLA><VSOLM>1.000</VSOLM><NLTYP>683</NLTYP><NLBER>001</NLBER><NLPLA>WA-ZONE</NLPLA><NSOLM>1.000</NSOLM><MAKTX>Kaubonbon MAOAM Cola</MAKTX><QPLOS>000000000000</QPLOS><QPLOA>000000000000</QPLOA><LGORT>6800</LGORT><SOLPO>         0.000</SOLPO><VOLUM>         0.000</VOLUM><VOLEH>CCM</VOLEH><NWIRM>         0.000</NWIRM><VBELN>0080015424</VBELN></E1LTORI><E1LTORI SEGMENT="1"><TAPOS>0002</TAPOS><MATNR>MAOAM-6801-COLA</MATNR><WERKS>1000</WERKS><MEINS>ST</MEINS><LETYP>E1</LETYP><WDATU>20080825</WDATU><WENUM>4900033558</WENUM><WEPOS>0005</WEPOS><VLTYP>682</VLTYP><VLBER>001</VLBER><VLPLA>03-04</VLPLA><VSOLM>1.000</VSOLM><NLTYP>683</NLTYP><NLBER>001</NLBER><NLPLA>WA-ZONE</NLPLA><NSOLM>1.000</NSOLM><MAKTX>Kaubonbon MAOAM Cola</MAKTX><QPLOS>000000000000</QPLOS><QPLOA>000000000000</QPLOA><LGORT>6800</LGORT><SOLPO>         0.000</SOLPO><VOLUM>         0.000</VOLUM><VOLEH>CCM</VOLEH><NWIRM>         0.000</NWIRM><VBELN>0080015424</VBELN></E1LTORI><E1LTORI SEGMENT="1"><TAPOS>0003</TAPOS><MATNR>MAOAM-6801-ORANGE</MATNR><WERKS>1000</WERKS><MEINS>ST</MEINS><LETYP>E1</LETYP><WDATU>20080825</WDATU><WENUM>4900033558</WENUM><WEPOS>0006</WEPOS><VLTYP>682</VLTYP><VLBER>001</VLBER><VLPLA>05-01</VLPLA><VSOLM>1.000</VSOLM><NLTYP>683</NLTYP><NLBER>001</NLBER><NLPLA>WA-ZONE</NLPLA><NSOLM>1.000</NSOLM><MAKTX>Kaubonbon MAOAM Orange</MAKTX><QPLOS>000000000000</QPLOS><QPLOA>000000000000</QPLOA><LGORT>6800</LGORT><SOLPO>         0.000</SOLPO><VOLUM>         0.000</VOLUM><VOLEH>CCM</VOLEH><NWIRM>         0.000</NWIRM><VBELN>0080015424</VBELN></E1LTORI></E1LTORH></IDOC></WMTOID01>

Ist ein typischer Sap Transportauftrag, aus dem ich die Lagerplatznummern raussuchen möchte.

Der Lagerplatz steht zwischen <VLPLA> und </VLPLA>

Wäre also in diesem Beispiel: <VLPLA>05-01</VLPLA>


----------



## Larry Laffer (3 Mai 2011)

OK ...
dann würde ich es so machen :
- mit FIND nach <VLPLA> suchen und Position merken
- mit FIND nach </VLPLA> suchen und Position merken
- den zwischen den gemerkten Positionen liegenden String mit MID ausschneiden.
- in dem ausgeschnittenen String mit FIND nach '-' suchen und nun wieder mit MID in die beiden Teile zerlegen.

Gruß
Larry


----------



## Ralle (3 Mai 2011)

> Wäre also in diesem Beispiel: <VLPLA>05-01</VLPLA>



Dann würde ich nach <VLPLA> suchen dir würde dann in mypos das erste Auftreten von <VLPLA> und da das erste Zeichen ausgegeben.
Dann kannst du noch nach </VLPLA> suchen, auch hier bekommst du die Position des ersten Zeichens ausgegeben.

Mit diesen Angaben kannst du gezielt *05* und *01* ausschneiden, im Prinzip benötigst du die Suche nach </VLPLA> nicht einmal, das wäre nur zur Sicherheit und Kontrolle, ob die Daten die korrekte Länge haben.

05: ist das 8.+9. Zeichen + mypos
01: ist das 11.+12. Zeichen + mypos

du könntest also mit der Funktion mid 

pos --> (mypos + 8 ) Länge --> 2 Zeichen auschneiden
pos --> (mypos + 11 ) Länge --> 2 Zeichen ausschneiden


----------



## Aslof (3 Mai 2011)

Erst mal Danke für die Tipps, das hat mir enorm geholfen. Eine Frage hab ich noch:

In dem Idoc stehen mehrere Lagerplätze, kann ich um die anderen (also alle nach dem ersten) zu finden einfach nochmal einen Find machen oder muss ich dazu den ersten Treffer löschen?

Mfg Alex


----------



## Ralle (3 Mai 2011)

Aslof schrieb:


> Erst mal Danke für die Tipps, das hat mir enorm geholfen. Eine Frage hab ich noch:
> 
> In dem Idoc stehen mehrere Lagerplätze, kann ich um die anderen (also alle nach dem ersten) zu finden einfach nochmal einen Find machen oder muss ich dazu den ersten Treffer löschen?
> 
> Mfg Alex



Du mußt die ersten dazu löschen. Ich hab das immer per Delete gemacht, etwas so:



```
Pos :=                  FIND(IN1 := Auftrag, IN2 := SuchString);
Car_id_No :=            MID(IN := Auftrag ,L := Pos-1 ,P := 1);
Auftrag :=          DELETE(IN := Auftrag, L := Pos + Length, P := 1);

Pos :=                  FIND(IN1 := Auftrag, IN2 := SuchString);
Kind_of_production :=   MID(IN := Auftrag ,L := Pos-1 ,P := 1);
Auftrag :=          DELETE(IN := Auftrag, L := Pos + Length, P := 1);

Pos :=                  FIND(IN1 := Auftrag, IN2 := SuchString);
IO_Flag :=              MID(IN := Auftrag ,L := Pos-1 ,P := 1);
Auftrag :=          DELETE(IN := Auftrag, L := Pos + Length, P := 1);
```


----------



## Larry Laffer (3 Mai 2011)

FIND sucht immer nur bis zur ersten Übereinstimmung. Du müßtest also dann bis Ende </VLPLA> den String löschen und dann wieder suchen. Der Befehl dafür wäre dann DELETE.
Beachte aber bitte :
Der String kann nicht unbegrenzt lang sein ...


----------



## Larry Laffer (3 Mai 2011)

Heh Ralle - das klappt heute aber wieder mit uns ...


----------



## Aslof (3 Mai 2011)

Und wie krieg ich die dann am besten in einen DB?

ich hab jetzt einen Aufgemacht mit 2 Arrays
einmal die Spalte für die ersten beiden Zahlen
und einmal die Zeile für die letzten beiden


----------



## Larry Laffer (3 Mai 2011)

... die Frage verstehe ich gerade nicht ... wo hängt es da ?


----------



## Ralle (3 Mai 2011)

Larry Laffer schrieb:


> Heh Ralle - das klappt heute aber wieder mit uns ...



Yep, geht wie Butter! 

@Aslof
Oh oh, dein XML ist 2663 Zeichen lang, wenn ich das richtig sehe.
S7-Strings sind max. 255 Zeichen lang, also mußt du das ankommende Paket sinnvoll zerlegen, um mit den Stringfunktionen zu arbeiten.

Es gibt noch eine Alternative, die habe ich mal irgendwann genutzt.
Die Daten kommen ja sicher per Ethernet oder so in einem DB bei dir an. Dort liegt dann ein Array of Byte o.ä.

Nun könnte man diese Array nach dem ersten Vorkomen von "<" durchsuchen, hat man das, schaut man, ob das zweite Zeichen "V" ist, wenn ja, das dritte Zeichen und so weiter, wenn nein, dann wieder nach "<" suchen. Das ist kein so großes Problem in SCL. So findest du ebenfalls deine Werte und kannst dann die betreffenden Byte ausschneiden.


----------



## Aslof (3 Mai 2011)

Ralle schrieb:


> Yep, geht wie Butter!
> 
> @Aslof
> Oh oh, dein XML ist 2663 Zeichen lang, wenn ich das richtig sehe.
> ...



Ich dachte das kann man umgehen indem man z.B. sagt Test : String[30000]?


----------



## Aslof (3 Mai 2011)

Larry Laffer schrieb:


> ... die Frage verstehe ich gerade nicht ... wo hängt es da ?



Die Frage ist wie das funktioniert.

Ich muss die Daten aus dem XML File ja auch irgendwie speichern.


----------



## Larry Laffer (3 Mai 2011)

Nein ...
der String hat einen Header, der die deklarierte und die tatsächliche Länge beinhaltet - für jede der Positionen ist ein Byte reserviert und so hast du dann auch die Stringgröße. Die Routinen FIND, DELETE, MID etc. arbeiten alle mit diesem Header.
Willst du das anders machen so wäre die Alternative (wie schon von Ralle erwähnt) das Array of Byte (oder Char). Da müßtest du dir deine Teilstrings dann aber selber bilden und auch die Such-Routinen selber erschaffen.

Wenn du dir mit deiner Routine Daten erzeugst so könntest du sie, vorausgesetzt du hast vor einen FB zu bauen, auch im STAT-Bereich desselben speichern. Ich denke mal, dass du damit ja ggf. noch weitere Dinge vorhast.

Gruß
Larry


----------



## Aslof (3 Mai 2011)

Larry Laffer schrieb:


> Nein ...
> der String hat einen Header, der die deklarierte und die tatsächliche Länge beinhaltet - für jede der Positionen ist ein Byte reserviert und so hast du dann auch die Stringgröße. Die Routinen FIND, DELETE, MID etc. arbeiten alle mit diesem Header.
> Willst du das anders machen so wäre die Alternative (wie schon von Ralle erwähnt) das Array of Byte (oder Char). Da müßtest du dir deine Teilstrings dann aber selber bilden und auch die Such-Routinen selber erschaffen.
> 
> ...



Was wäre deiner Meinung nach Einfacher, einen Char Array zu Initialisieren (In der Form liegt das XML File in dem DB vor) und den dann in lauter kleine Strings umzuwandeln (falls das den geht?). Oder aber eigene Suchroutinen schreiben und die dann auf den Char Arrays ausüben.

Zu der Funktion des Systems. Ich krieg die Daten über einen CP vom SAP System und soll dann da die Lagerplätze raussuchen und die dann in einem "Hochregallager" anfahren.
Deshalb muss ich die Daten also alles was zwischen <VLPLA> und </VLPLA> finde raussuchen und in einem DB speichern, so dass Ich die nacheinander aus dem System ziehen kann und dann dem System angeben kann welche Teile ausgelagert werden sollen.

Thx


----------



## Larry Laffer (3 Mai 2011)

Ich glaube ich würde auch so vorgehen, wie schon von Ralle skizziert :
Ich würde das komplette Char-Array durchsuchen und mir dann passende Einzel-Strings bilden. Das ist allerdings nicht un-aufwändig. Einen Vergleich auf Inhalte kannst du hier dann nur Byteweise durchführen - also wenn akt_Char = '<' dann Beginn_einer_Sequenz und dann weiterprüfen ob die weiteren Zeichen auch passen. Hier kannst du dir dann natürlich das MID und auch das DELETE etc. sparen und einfach ab dem Ende von <VLPLA> die nächsten Zeichen (soviel es maximal sein können - vielleicht kann es ja auch 1001-09 heißen) in einen Hilfsstring schreiben und den dann schließen (oder auch gleich) weiter verarbeiten.
Wie schon geschrieben würde ich hier mit einem FB arbeiten - somit würde ich hier auch erstmal alle sinnvoll gefundenen Einzel-Ergebnisse in diesem abbilden und ggf. am Schluß alles in Summe nach irgendwohin zur Verfügung stellen.

Gruß
Larry


----------



## Aslof (3 Mai 2011)

Ok hört sich vernünftig an.

Ich hab jetzt also ein Array z.B.

IDOC : ARRAY[0..3000] OF Char;

Wie weise ich dem jetzt den Array aus dem Datenbaustein zu (ist auch ein Char array & gleich groß).

Wenn ich jetzt sage

IDOC := DB50.Lagerplatz;

Dann schreit der Compiler jedes mal "Ungültiger Datentyp"

Habt Ihr da einen Tipp für mich?


----------



## Ralle (3 Mai 2011)

Ich hänge dir mal 2 Quellen an. Das .txt mußt du löschen, dann kannst du das in ein Step7-Projekt importieren. In dem SCL-Code (Weiß nicht mehr, ob ich das war oder mir den mal jemand gegeben hat, schon zu lange her  ) werden bestimmte Zeichen gesucht und dann die folgenden Zeichen verkettet und abgelegt. So ähnlich würde das bei dir auch laufen, aber im vorliegenden Code wird immer nur ein "Trennzeichen" verwendet und folglich gesucht. Bei dir müßte die Suche ja nach dem ersten gefundenen Zeichen noch mit den weiteren Zeichen fortgesetzt werden. Aber als Beispiel zeigt es schon einiges. Du brauchst nichts in Statische Daten umzukopieren, es wird direkt mit einem Quell- und einem Ziel-DB gearbeitet. Leider ohne Kommentare ...

PS: Wenn 3000 Byte durchsucht werden und das Ganze zu lange dauert (SPS-Zykluszeit!!!), dann kann es sein, dass man das später auch noch in mehrere "Durchläufe" aufteilen muss!


----------



## Ralle (3 Mai 2011)

Ich hab das Beispiel mal so abgeändert, dass es mit deinen Daten funktioniert.
Was noch offen ist, es werden nur 200 Byte durchsucht, das kann man ja vergrößern, aber wie gesagt u.U. wirkt sich das auf die Zykluszeit negativ aus. Wenn das so ist, muss man das so machen, dass man z.Bsp. je Zyklus 200 oder 500 Byte durchsuchen läßt, dann die Schleife verläßt und beim nächsten Mal dort wieder einsetzt, wo man aufgehört hat. Dann wäre es wohl sinnvoll, das Ganze in einem FB zu machen und die Variablen die jetzt Temp sind im Stat-Bereich anzulegen. Es ist weiterhin noch keinerlei Fehlerprüfung realisiert, Also z.Bsp., wenn die XML-Datei Fehler enthält. Auch ist natürlich der Ergebnis-DB im Moment auf 100 Fundstellen begrenzt. Er sollte so groß sein, dass alle Fundstellen hineinpassen u.U. ist eine Abbruchbedingung inkl. Fehlermeldung bei möglichen Überschreitungen sinnvoll.


----------



## Aslof (3 Mai 2011)

Gehört es zu den Don'ts die Zyklen der CPU zu verlängern?
Der Packt so nur 2850 Zeichen pro Zyklus.

Ansonsten fällt mir nur noch ein die derzeite Position des For index in ner DB zu speichern und dann anschließend im nächsten Zyklus wieder auszulesen.
Hat jemand ne andere Idee?

Bzw. Ich hab gerade erst deinen Beitrag gelesen Ralle, wie funktioniert das mit den statischen Variablen in den FBs? und thx für die Lösung aber ich muss noch dazu sagen, das Xml File von mir war nur für 3 Produkte. Um das für meine Zwecke zu missbrauchen brauch ich c.a. Platz für 10 Produkte d.h. ~10000Zeichen  zu verarbeiten.
mfg Alex


----------



## Ralle (3 Mai 2011)

Aslof schrieb:


> Gehört es zu den Don'ts die Zyklen der CPU zu verlängern?
> Der Packt so nur 2850 Zeichen pro Zyklus.
> 
> Ansonsten fällt mir nur noch ein die derzeite Position des For index in ner DB zu speichern und dann anschließend im nächsten Zyklus wieder auszulesen.
> ...



Die Zwischenergebnisse sind ja bei einem FC Temporäre Variablen. Wenn man z.Bsp. nach 500 Zeichen die For-Schleife verläßt ist es am Besten, es bleibt alles erhalten, dann muß man nicht zu viel nachdenken. 
Du erzeugst eine neue SCL-Datei und fügst dort einen Rumpf für FB ein. Dann kannst du das Meißte aus dem FC in den FB kopieren, die Temp-Variablen kommen aber in den Stat-Bereich. 
Ich würde mit Start eine Flanke erzeugen (auch hier stat-Vat nutzen) und mit der Flanke die Variablen auf Null setzen, z.Bsp. den Index.
Dann Die For-Schleife, aber immer mit dem erhöhten Index neu einsteigen.
Bei Erreichen des endgültigen Endes (evtl. eine LEN-Variable an den FB) ein Fertig-Bit ausgeben. Dann kann der Start zurückgenommen werden und alles kann von vorne beginnen.

Zykluszeit: Du kannst das austesten, es ist abhängig von der Gesamtanwendung. Die Zykluszeit darf sich schon verlängern, aber es gibt Anwendungen, das sind 50ms schon zu viel. Am Besten, du nimmst einmal deine Daten in den DB, setzt den Wert in der For-Schleife dann Schrittweise hoch und schaust dir die Zykluszeit an. Für 10 Produkte wäre der Db ja dann mit 100 lang genug oder?


----------



## Aslof (3 Mai 2011)

Ralle schrieb:


> Die Zwischenergebnisse sind ja bei einem FC Temporäre Variablen. Wenn man z.Bsp. nach 500 Zeichen die For-Schleife verläßt ist es am Besten, es bleibt alles erhalten, dann muß man nicht zu viel nachdenken.
> Du erzeugst eine neue SCL-Datei und fügst dort einen Rumpf für FB ein. Dann kannst du das Meißte aus dem FC in den FB kopieren, die Temp-Variablen kommen aber in den Stat-Bereich.
> Ich würde mit Start eine Flanke erzeugen (auch hier stat-Vat nutzen) und mit der Flanke die Variablen auf Null setzen, z.Bsp. den Index.
> Dann Die For-Schleife, aber immer mit dem erhöhten Index neu einsteigen.
> ...



Klar 100 Stellen würden gut ausreichen, vielen Dank für eure Hifle


----------

