Step 7 AWL - Array in ein anderes Array kopieren

Limette

Level-2
Beiträge
282
Reaktionspunkte
3
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

Ich habe ein Temp-Array

2021-07-30_16h54_33.png

ich würde nun gerne einen Teil des Arrays in ein anderes Array(auch 64 byte lang) blkmoven. Der "Teil" soll aber flexibel bleiben, also einmal 30 char oder 20..etc

Code:
      LAR1  P##ResultCut                  //Any ins adressregister laden
      L     W#16#10                     //SyntaxID. bei S7 immer 10
      T     LB [AR1,P#0.0]

      L     W#16#3                      //Typ Char
      T     LB [AR1,P#1.0]

      L     #ResultLength              //Anzahl Bytes
      T     LW [AR1,P#2.0]

      L     DINO                        //Quell-DB
      T     LW [AR1,P#4.0]

      L     0                              //Anfang der Quelle
      SLD   3
      T     LD [AR1,P#6.0]

      L     B#16#86                    //Speicherbereich (hier Lokaldaten)
      T     LB [AR1,P#6.0]
      
      
       CALL  "BLKMOV"
       SRCBLK :=#ResultCut
       RET_VAL:=#_Dummy_INT
       DSTBLK :=#NewResult

Meine Frage:
Funktioniert das so?
Was passiert wenn das Temp Array nicht mehr auf Adresse 0.0 steht? Kann man ich rausfinden wo das Array gerade liegt?

Danke im Voraus.
 
Mit
Code:
L P##Result
LAR1

ladest du einen Zeiger auf #Result ins AR1. Das kannst du dann umgekehrt zu deinem Code in Variablen zerlegen, die Länge manipulieren und wieder auf deinen Zeigeer #Result_Cut legen. Dein Code sieht gut aus. Nur würd ich immer Byte als Typ nehmen.
Und DBNR brauchst du bei Lokaldaten nicht angeben.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mit
Code:
L P##Result
LAR1

ladest du einen Zeiger auf #Result ins AR1. Das kannst du dann umgekehrt zu deinem Code in Variablen zerlegen, die Länge manipulieren und wieder auf deinen Zeigeer #Result_Cut legen. Dein Code sieht gut aus. Nur würd ich immer Byte als Typ nehmen.
Und DBNR brauchst du bei Lokaldaten nicht angeben.
Danke erstmal.
Hast du so gemeint?

Code:
      L    P##Result
      LAR1

      L    B [AR1,P#0.0]
      T    #SaveSyntax

      L    B [AR1,P#1.0]
      T    #SaveTyp

      L    D [AR1,P#6.0]
      T    #Offset

      L    B [AR1,P#6.0]
      T    #Storage
 
 LAR1  P##ResultCut                  //Any ins adressregister laden
      L     #SaveSyntax                  //SyntaxID. bei S7 immer 10
      T     LB [AR1,P#0.0]

      L     #SaveTyp                      //Typ Char
      T     LB [AR1,P#1.0]

      L     #ResultLength              //Anzahl Bytes
      T     LW [AR1,P#2.0]

      L     #Offset
      T     LD [AR1,P#6.0]

      L     #Storage                     //Speicherbereich (hier Lokaldaten)
      T     LB [AR1,P#6.0]
      
      
       CALL  "BLKMOV"
       SRCBLK :=#ResultCut
       RET_VAL:=#_Dummy_INT
       DSTBLK :=#NewResult
 
Wenn das nur weniger als 100 Byte bleiben, dann könntest Du die auch gleich in einer Schleife direkt kopieren anstatt ANY-Pointer für BLKMOV zu basteln.

Harald
 
Wenn das nur weniger als 100 Byte bleiben, dann könntest Du die auch gleich in einer Schleife direkt kopieren anstatt ANY-Pointer für BLKMOV zu basteln.

Harald
es würden sicher weniger als 100 bleiben, aber die Methode oben blick ich +/- noch. Bei ner awl Schleife bin ich halt raus. :)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich bin in AWL nicht mehr so fit, aber ich denke jetzt fällts mir ein. Kann es sein das du hier tResultData als ANY ausliest, sondern den tatsächlichen Inhalt des Char-Arrays? Bei dir steht ja in der ID nicht 10 sondern 31. Versuch mal den Code in einen weiteren FC zu packen, und tResultData und tCut als ANY zu übergeben.
 
Is ja kein Beinbruch. In der Classic-Welt hatten wir oft einen Standard-FC im Einsatz mit dem man zwei ANYs manipulieren konnte und dann intern ein BLKMOV aufgerufen wurde.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
könntest Du die auch gleich in einer Schleife direkt kopieren anstatt ANY-Pointer für BLKMOV zu basteln.
Code:
VAR_TEMP
  Result     : ARRAY [1 .. 64] OF CHAR ; //Quell-Array
  NewResult  : ARRAY [1 .. 64] OF CHAR ; //Ziel-Array
  StartIndex : INT ;   //Index erstes zu kopierendes Char
  ResultLen  : INT ;   //Anzahl zu kopierender Chars
  LoopCount  : INT ;   //Schleifenzähler
  AR2_Save   : DWORD ; //zum merken AR2 Inhalt
END_VAR
Ungetestet:
Code:
// eine Anzahl = ResultLen Chars 
// von  Result[StartIndex] bis Result[StartIndex + ResultLen - 1]
// nach NewResult[1] bis NewResult[ResultLen] kopieren

      TAR2  #AR2_Save           //in FB: Inhalt AR2 sichern!

      LAR2  P##NewResult        //AR2 auf Ziel-Array stellen

      L     #StartIndex         //StartIndex 1..64 in Quell-Array
      +     -1                  //--> Offset 0..63
      SLD   3                   //--> P#0.0 .. P#63.0
      LAR1  P##Result           //AR1 auf Anfang Quell-Array stellen
      +AR1                      //den Offset des StartIndex dazuaddieren

      L     #ResultLen          //Anzahl zu kopierender Chars
lop:  T     #LoopCount          //Schleifenzähler Kopierschleife

      L     LB [AR1,P#0.0]      //Char von Quell-Array Result[j]
      T     LB [AR2,P#0.0]      //in Ziel-Array NewResult[i] kopieren

      L     P#1.0
      +AR1                      //Pointerregister auf das
      +AR2                      //nächste Char weiterstellen

      L     #LoopCount          //alle Chars kopiert?
      LOOP  lop                 //ggf. wiederholen

      LAR2  #AR2_Save           //Inhalt AR2 wiederherstellen

Funktioniert ungefähr so (Pseudocode):
FOR i := 1, j := StartIndex TO i <= ResultLen DO AR2[i] := AR1[j];
bzw.:
pz := ADR(NewResult[1]); pq := ADR(Result[StartIndex]); FOR i := 1 TO i <= ResultLen DO *pz++ := *pq++;

Harald
 
Code:
VAR_TEMP
  Result     : ARRAY [1 .. 64] OF CHAR ; //Quell-Array
  NewResult  : ARRAY [1 .. 64] OF CHAR ; //Ziel-Array
  StartIndex : INT ;   //Index erstes zu kopierendes Char
  ResultLen  : INT ;   //Anzahl zu kopierender Chars
  LoopCount  : INT ;   //Schleifenzähler
  AR2_Save   : DWORD ; //zum merken AR2 Inhalt
END_VAR
Ungetestet:
Code:
// eine Anzahl = ResultLen Chars
// von  Result[StartIndex] bis Result[StartIndex + ResultLen - 1]
// nach NewResult[1] bis NewResult[ResultLen] kopieren

      TAR2  #AR2_Save           //in FB: Inhalt AR2 sichern!

      LAR2  P##NewResult        //AR2 auf Ziel-Array stellen

      L     #StartIndex         //StartIndex 1..64 in Quell-Array
      +     -1                  //--> Offset 0..63
      SLD   3                   //--> P#0.0 .. P#63.0
      LAR1  P##Result           //AR1 auf Anfang Quell-Array stellen
      +AR1                      //den Offset des StartIndex dazuaddieren

      L     #ResultLen          //Anzahl zu kopierender Chars
lop:  T     #LoopCount          //Schleifenzähler Kopierschleife

      L     LB [AR1,P#0.0]      //Char von Quell-Array Result[j]
      T     LB [AR2,P#0.0]      //in Ziel-Array NewResult[i] kopieren

      L     P#1.0
      +AR1                      //Pointerregister auf das
      +AR2                      //nächste Char weiterstellen

      L     #LoopCount          //alle Chars kopiert?
      LOOP  lop                 //ggf. wiederholen

      LAR2  #AR2_Save           //Inhalt AR2 wiederherstellen

Funktioniert ungefähr so (Pseudocode):
FOR i := 1, j := StartIndex TO i <= ResultLen DO AR2[i] := AR1[j];
bzw.:
pz := ADR(NewResult[1]); pq := ADR(Result[StartIndex]); FOR i := 1 TO i <= ResultLen DO *pz++ := *pq++;

Harald
Hi PN/DP. Danke für dein Hilfe.
Es kommt leider ein Bereichslängenfehler(Stelle: T LB [AR2,P#0.0]). Wäre cool, wenn du nochmal helfen könntest.
Anhang anzeigen 55670Anhang anzeigen 55671
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Deine Anhänge funktionieren leider nicht... Kannst Du vielleicht mit Text erklären was Du tust?
Hast Du #StartIndex einen Wert 1..64 und #ResultLen einen Wert 1..64 (höchstens der verbleibenden #Result-Array-Restlänge) zugewiesen?
Beispiel:
#StartIndex = 3, #ResultLen = 10 kopiert von Result[3]..Result[12] nach NewResult[1]..NewResult[10]

Ich habe den Code mal mit PLCSIM getestet, bei mir funktioniert er wie beabsichtigt.

Harald
 
Zuletzt bearbeitet:
Weil Du den Code offensichtlich in einem FB verwendest, ein Hinweis:
Zwischen LAR2 P##NewResult und LAR2 #AR2_Save kannst Du nicht auf Variablen der FB-Instanz zugreifen, weil dazu der original Inhalt des AR2 nötig ist (AR2 enthält den Multiinstanzoffset dieser FB-Instanz).

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Weil Du den Code offensichtlich in einem FB verwendest, ein Hinweis:
Zwischen LAR2 P##NewResult und LAR2 #AR2_Save kannst Du nicht auf Variablen der FB-Instanz zugreifen, weil dazu der original Inhalt des AR2 nötig ist (AR2 enthält den Multiinstanzoffset dieser FB-Instanz).

Harald
Hallo Harald,
Hab noch eine Frage/Problem.
StartIndex = 1
ResultLen = 34
Der Inhalt wird von Result nach NewResult kopiert. Die ersten 34 Stellen passen auch. Aber danach stehen noch irgendwelche Hieroglyphen und Teile des davor kopierten Inhalts. Also Arraystelle 35-42 stehen Sachen drin, obwohl eigentlich nichts drin stehen sollte.
Hast du mir einen Tipp?
Danke im Voraus
 
Aber danach stehen noch irgendwelche Hieroglyphen und Teile des davor kopierten Inhalts.
Die überzähligen Zeichen kannst Du auch einfach ignorieren/nicht auswerten, Dein Programm weiß doch wie lang ResultLen ist.

Also Arraystelle 35-42 stehen Sachen drin, obwohl eigentlich nichts drin stehen sollte.
"Nichts drin" gibt es nicht. In einer Char-Variable steht immer etwas drin. Und wenn das Programm nichts neues hineinschreibt, dann steht eben das drin was zuletzt hineingeschrieben wurde oder womit das Char initialisiert wurde oder bei TEMP ein quasi zufälliger/unkontrollierter Wert.

Harald
 
Zurück
Oben