String zusammen setzen und als Array of Char abspeichern - ohne SCL

Eigentl alles beim Alten geblieben:

Ich hab in einem FB in TEMP meine ganzen Variablen, angefangen mit dem ANY-Pointer, DATE_and_TIME, etlichen Strings mit Größenangabe usw. Die Geschichte mit dem Auslagern in einen extra FB habe ich mal wieder Rückgängig gemacht.

Erst wenn ich jetzt in diesem folgenden FB eine neue Variable in TEMP anlege und wieder lösche, geht es. Beim Anlegen kommt übrigens die Warnmeldung 34:162
(Ihre eingegebene Deklarationszeile aus dem VAR_TEMP kollidiert mit einem absoluten Zugriff auf den L-Stack im Programmrumpf des aktuellen Bausteins. In Ansicht AWL könnte das bedeuten, daß vom KOP/FUP Compiler angelegte compiler-interne Lokaldaten zu Anwender-Lokaldaten werden. Dann ist die Umschaltung in Sicht KOP/FUP nicht mehr möglich.)



Dann im Programm:

Code:
//DB Öffnen
      L     #Src_DB_Nr
      T     #DB_Nr_Word      
      AUF   DB [#DB_Nr_Word]

//Pointer bauen
      L     0
      SLD   3
      LAR1  

//Zuweisungen in der Art
      UN    DBX [AR1,P#100.0]


//Systemzeit auslesen
SFC1



//> Date_And_Time auslesen und zerlegen
//>> Zeit
//>>> Stunden (LB13)
      L     LB    13
      BTI   
      T     #Stunden_I

      L     #Stunden_I
      L     100
      +I    
      T     #Stunden_I


//>>> Minuten (LB14)
      L     LB    14
      BTI   
      T     #Minuten_I

      L     #Minuten_I
      L     100
      +I    
      T     #Minuten_I


//>>> Sekunden (LB15)
      L     LB    15
      BTI   
      T     #Sekunden_I

      L     #Sekunden_I
      L     100
      +I    
      T     #Sekunden_I


//>> Datum
//>>> Jahr
      L     LB    10
      BTI   
      T     #Jahr_I

      L     #Jahr_I
      L     100
      +I    
      T     #Jahr_I


//>>> Monat
      L     LB    11
      BTI   
      T     #Monat_I

      L     #Monat_I
      L     100
      +I    
      T     #Monat_I


//>>> Tag
      L     LB    12
      BTI   
      T     #Tag_I

      L     #Tag_I
      L     100
      +I    
      T     #Tag_I
//;


//> String-Header vorbelegen
//>> Zeit
//>>> Stunden
      LAR1  P##Stunden_Str_4
      L     4
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]

      LAR1  P##Stunden_Str_2
      L     2
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]


//>>> Minuten
      LAR1  P##Minuten_Str_4
      L     4
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]

      LAR1  P##Minuten_Str_2
      L     2
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]


//>>> Sekunden
      LAR1  P##Sekunden_Str_4
      L     4
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]

      LAR1  P##Sekunden_Str_2
      L     2
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]


//>>> Sekunden_Minuten
      LAR1  P##Sekunden_Minuten_Str
      L     4
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]


//>>> Zeit_Komplett_Str
      LAR1  P##Zeit_Komplett_Str
      L     6
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]


//>> Datum
//>>> Jahr_Str_4
      LAR1  P##Jahr_Str_4
      L     4
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]


//>>> Jahr_Str_2
      LAR1  P##Jahr_Str_2
      L     2
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]


//>>> Monat_Str_4
      LAR1  P##Monat_Str_4
      L     4
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]


//>>> Monat_Str_2
      LAR1  P##Monat_Str_2
      L     2
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]


//>>> Tag_Str_4
      LAR1  P##Tag_Str_4
      L     4
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]


//>>> Tag_Str_2
      LAR1  P##Tag_Str_2
      L     2
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]


//>>> Tag_Monat_Str
      LAR1  P##Tag_Monat_Str
      L     4
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]


//>>> Datum_Komplett_Str
      LAR1  P##Datum_Komplett_Str
      L     6
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]


//>>> Zeit_Datum_Str
      LAR1  P##Zeit_Datum_Str
      L     12
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]


//>>> Trennzeichen
      LAR1  P##Trennzeichen_Str_3
      L     3
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]

      L     95
      T     LB [AR1,P#3.0]


      LAR1  P##Trennzeichen_Str_1
      L     1
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]


      LAR1  P##Zeit_Trennzeichen_1_Str
      L     7
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]


      LAR1  P##Zeit_Trennzeichen_2_Str
      L     8
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]


      LAR1  P##Datum_Trennzeichen_Str
      L     7
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]


      LAR1  P##Zeit_Datum_Trennzeichen
      L     15
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#2.0]
//;


//Es folgen Int2String sowie MID-Funktionen (Vorzeichen und führende 1 "Abschneiden")


//Es folgen CONCAT-Funktionen


//Pointer bauen - habe hier zum Test mal von 8 Word auf 15 Byte abgeändert (korrekte Länge der Variable)

      LAR1  P##StringOhneHeader_ANY
      L     B#16#10                     //Syntax-ID
      T     LB [AR1,P#0.0]

      L     B#16#2                      //Datentyp WORD 4, Byte 2
      T     LB [AR1,P#1.0]

      L     15                          //8 WORD, 15 Byte
      T     LW [AR1,P#2.0]

      L     0
      T     LW [AR1,P#4.0]

      L     184                         //Lokaldaten ab xxx
      SLD   3
      T     LD [AR1,P#6.0]

      L     B#16#87                     //vorherige Lokaldaten
      T     LB [AR1,P#6.0]


//DB erneut öffnen
      L     #Src_DB_Nr
      T     #DB_Nr_Word
      AUF   DB [#DB_Nr_Word]

//Pointer bauen
      L     0
      SLD   3
      LAR1  


//BLKMOV SRCBLK ist der #StringOhneHeader_ANY
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Naja ... die Krux ist ja schon der erste Bereich.
Der SFC1 liest seinen Kram in eine im Lokalbereich deklarierte Variable ein, die ab LB10 ff. steht.
Darauf greifst du dann absolut zu.

Das könnte so besser werden :
Code:
    LAR1  P##myDateTime
 
//> Date_And_Time auslesen und zerlegen
//>> Zeit
//>>> Stunden (LB13)
      L     LB    [ar1 , p#3.0]
      BTI   
       L     100
      +I    
      T     #Stunden_I


//>>> Minuten (LB14)
      L     LB     [ar1 , p#4.0]
      BTI   
      L     100
      +I    
      T     #Minuten_I


//>>> Sekunden (LB15)
      L     LB    [ar1 , p#5.0]
      BTI   
       L     100
      +I    
      T     #Sekunden_I


//>> Datum
//>>> Jahr
      L     LB     [ar1 , p#0.0]
      BTI   
      L     100
      +I    
      T     #Jahr_I


//>>> Monat
      L     LB    [ar1 , p#1.0]
      BTI   
      L     100
      +I    
      T     #Monat_I


//>>> Tag
      L     LB   [ar1 , p#2.0]
      BTI   
      L     100
      +I    
      T     #Tag_I
//;
... ist aber ungetestet ...

Gruß
Larry
 
Code:
//> String-Header vorbelegen
//>> Zeit
//>>> Stunden
      LAR1  P##Stunden_Str_4
      L     4
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#[COLOR=#ff0000]1[/COLOR].0]

      LAR1  P##Stunden_Str_2
      L     2
      T     LB [AR1,P#0.0]
      T     LB [AR1,P#[COLOR=#ff0000]1[/COLOR][COLOR=#ff0000][/COLOR].0]

usw.

Ich denke, du willst die Stringheader vorbelegen, dann mußt du Byte 0 und 1 mit max.Länge und Länge beschreiben.
 
Danke, werde ich beides testen. Erklärt aber für mich noch immer nicht, warum das Ganze nach einem Stop->Run der CPU erst dann wieder funktioniert, wenn ich eine neue (unbenutzte) TEMP-Variable anlege, das Programm lade, die Variable wieder lösche und dann wieder lade.

Frage mich auch, warum die o.G. Fehlermeldung kommt. Ich greife schließlich nicht auf den Bereich zu, in dem diese neue TEMP-Variable liegt.


PS: Hab gelesen, dass bei FUP-Ansicht auch was im TEMP-Bereich "unsichtbar" gespeichert wird. Der Baustein ist in FUP, nur die einzelnen Netzwerke sind soweit nötig in AWL...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke, werde ich beides testen. Erklärt aber für mich noch immer nicht, warum das Ganze nach einem Stop->Run der CPU erst dann wieder funktioniert, wenn ich eine neue (unbenutzte) TEMP-Variable anlege, das Programm lade, die Variable wieder lösche und dann wieder lade.

Frage mich auch, warum die o.G. Fehlermeldung kommt. Ich greife schließlich nicht auf den Bereich zu, in dem diese neue TEMP-Variable liegt.


PS: Hab gelesen, dass bei FUP-Ansicht auch was im TEMP-Bereich "unsichtbar" gespeichert wird. Der Baustein ist in FUP, nur die einzelnen Netzwerke sind soweit nötig in AWL...


Ok es erklärts für mich vielleicht nicht, aber mit beiden Lösungen zusammen (einzeln nicht getestet...) gehts :)


Irgendwelche Erklärungen? ^^



EDIT: Nochmal wg. Multiinstanz... Wenn ich den ganzen Kram hier in einen FB auslagern möchte und diesen FB dann als Multiinstanz aufrufen möchte, muss ich "LAR1 P#XXX" durch "LAR1 AR2, L P#XXX, +AR1" ersetzen?
 
Zuletzt bearbeitet:
Frage mich auch, warum die o.G. Fehlermeldung kommt. Ich greife schließlich nicht auf den Bereich zu, in dem diese neue TEMP-Variable liegt.


PS: Hab gelesen, dass bei FUP-Ansicht auch was im TEMP-Bereich "unsichtbar" gespeichert wird. Der Baustein ist in FUP, nur die einzelnen Netzwerke sind soweit nötig in AWL...

Mit deiner Vermutung liegst du schon ganz richtig. In FUP wird der lokale Stack für Zwischenergebnisse von Verschaltungen genutzt. Dazu dient dann der Bereich direkt nach den angelegten Variablen. Im Normalfall werden bei Änderungen in FUP diese "FUP-internen" Variablen mitgeführt. legst du also eine neue TempVar auf LW10, dann werden die FUP-internen Variablen, die auf LW10 liegen auf LW12 gelegt. Man kann aber im eigenen Code auf jedes beliebige Byte des Lokalstack zugreifen, z.Bsp. mit L LB 10. Es kann auch passieren, das die Variablen nicht mitgeführt werden, evtl. wenn man in AWL umschaltet und dann Temp-Var einfügt oder Netzwerke aus anderen FUP-Bausteinen einfügt. Dann kann es sein, dass eine von dir angelegte Variable auf LB 10 liegt, die FUP-internen Variablen u.a. auch auf Lokal-Bit 10.0 zugreifen. Erstens kann es dann zu falschen Ergebnissen im Baustein kommen, zweitens bekommt man eine Fehlermeldung von Step7, wenn es das denn auch mibekommt. Wenn du deinen Baustein in AWL umschaltest, kannst du in bestimmten FUP-Netzwerken (dann in AWL) sehen, wie die Lokalbits verwendet werden und auch mal prüfen, ob da Bits genutzt werden, die von deinen eigenen Variablen belegt sind. Wenn ja, dann kannst du die FUP-internen einfach auf den freien Bereich nach deinen Variablen umlegen.
 
Hab nachgeschaut, er nutzt nur einmal die Lokaldaten in nem FUP-Baustein... das war tatsächlich 199.0 - genau dort fängt die neu angelegte und dann wieder gelöschte Variable an.
Hab das mal auf 200.0 hoch gesetzt, ging aber schon durch eure Codeschnipsel.


Jetzt muss ich noch die Multiinstanz-Geschichte angehen und dann bin ich durch ;-)


Stimmt da das hier dann: überall "LAR1 P#XXX" durch "LAR1 AR2, L P#XXX, +AR1" ersetzen?
Wie läuft das beim DB-Pointer dann genau? Da hab ich ja keinen "P#XXX" sondern nur "L 0, SLD 3, LAR1"


...oder gilt das evt. nur, wenn man auf STAT zugreifen will? Hab ja alles in TEMP
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Das Ar2 musst du nur addieren wenn du auf INSTANZDATEN deines FBs indirekt zugreifst. Bei Daten die in einem anderen DB liegen darfst!! du das Ar 2 nicht addieren.

Zusammengefasst:
Wenn du auf In-/Out-/InOut-/Statvariablen deines FBs indirekt zugreifst, dann addiere immer AR2 zu deinem Pointer.
Damit ist der FB multiinstanzfähig.
 
Alles klar, danke. Ich nutze ja nur TEMP, also dürfte das alles entfallen.


Aber mal kurz dazu die Frage: Wie kann ich beim Zugriff denn dann zwischen Temp und Stat usw unterscheiden? DH TEMP0.0 ist ja z.B. L LD[AR1,P#0.0] - aber wie komme ich z.B. auf STAT0.0?
->>> Brauche das aber für diesen Baustein erstmal nicht - wie gesagt da ist alles in Temp.

Danke nochmal
 
Zurück
Oben