String umkopieren

Ralle

Super-Moderator , User des Jahres 2006-2007
Teammitglied
Beiträge
15.400
Reaktionspunkte
4.034
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich hab heut mal folgendes versucht:

einen FB anlegen
1x Index IN-Var Integer
1x Schreibstring IN_OUT-Var String[254]
8x Datenstring[x] STAT-Var String[256]

Folgendes soll passieren

Abhängig vom Index (Int), soll der Schreibstring in einer der statischen Var gespeichert werden.

Das Problem:

Die IN_OUT vom Typ String[256] wird von Step7 als Pointer übergeben.

Weiß jemand den genauen Mechanismus, wie ich auf die Einzelemente dieses Pointers zugreifen kann um dann einen Any-Pointer zu bauen, den ich an den SFC20 (Block_move) antragen kann?

Irgendwie wollte mir das heute einfach nicht gelingen, ich hab alle möglichen Varianten getestet, vielleicht, war auch einfach irgendwann der Dampf raus.

Als Ausweichvariante hab ich aus dem String IN_OUT einen String IN gemacht, dann wird der String mit in den Instanz-DB aufgenommen, damit kann man im FB intern ganz gut arbeiten. Aber es wurmt mich irgendwie :ROFLMAO:!

Ich hab das mal in SCL probiert und mir den AWL-Code dann angesehen, daß ist auch nicht das, was mir vorschwebte, da wird das Ganze in einer LOOP umkopiert.

Stat_String := IO_String;
 
Pointer

Hallo Ralle,

die Pointer Sisters hatten wohl keinen Tip für dich? ;-) Hier ein Stück Code von mir

L P##CONFIG // Pointer auf CONFIG
LAR1
L W [AR1,P#0.0] // DB_Nr CONFIG
T #DB_Nr
AUF DB [#DB_Nr] // DB CONFIG öffnen
L D [AR1,P#2.0] // Pointer auf Datenbereich CONFIG
LAR1 // ins Adressregister

Eigentlich musste nur Byte 0/1 noch dazubauen und den Wiederholfaktor. Dann haste nen ANY.

André
 
Hallo Ralle,

die Pointer Sisters hatten wohl keinen Tip für dich? ;-) Hier ein Stück Code von mir

L P##CONFIG // Pointer auf CONFIG
LAR1
L W [AR1,P#0.0] // DB_Nr CONFIG
T #DB_Nr
AUF DB [#DB_Nr] // DB CONFIG öffnen
L D [AR1,P#2.0] // Pointer auf Datenbereich CONFIG
LAR1 // ins Adressregister

Eigentlich musste nur Byte 0/1 noch dazubauen und den Wiederholfaktor. Dann haste nen ANY.

André

Ich werd das morgen nochmal damit versuchen, so ähnlich hab ich es heut schon versucht, allerdings werd ich ja eine Any daraus machen, wegen dem SFC20. Denke mal, daß man einfach betriebsblind wird, vor lauter Änderungen :ROFLMAO:.
 
ich nutze häufiger meinen "any offset" baustein:

wie wärs wenn du damit einen sfc20 fütterst?


Code:
FUNCTION "ANY_OFFSET" : VOID
TITLE =
//Dieser Baustein bekommt als Eingangsparameter einen Any-Pointer der z.B. auf
//das erste Feld (Structur) in einem Array zeigt.
//Der Eingangsparameter ENTRY_NO enthält die Nummer des Array Feldes.
//Der Ausgangsparameter DST_ANY gibt einen Anypointer aus der auf das Feld mit
//der Nummer "ENTRY_NO" zeigt. 
VERSION : 0.1

VAR_INPUT
  SRC_ANY : ANY ; //Anypointer auf das erste Feld des Arrays in dem die Strukturen sind
  ENTRY_NO : INT ; //Nummer des Feldes für den Pointer am Ausgang
END_VAR
VAR_OUTPUT
  DST_ANY : ANY ; //Any-Pointer auf das angegebene Feld im Array
END_VAR
VAR_TEMP
  T_AR1 : DWORD ; 
  T_AR2 : DWORD ; 
  SyntaxID : BYTE ; 
  Bereichstyp : BYTE ; //B#16#2 = Byte; B#16#4 = Word
  Anzahl_Werte : WORD ; 
  DB_Nr : WORD ; 
  Startadresse : DWORD ; //Auchtung! Pointerformat - ggf. mit "SRD 3" in DINT wandeln
END_VAR
BEGIN
NETWORK
TITLE =Adressregister retten

      TAR1  #T_AR1; 
      TAR2  #T_AR2; 
NETWORK
TITLE =Pointer auf das erste Feld lesen

      L     P##SRC_ANY; 
      LAR1  ; 
      L     B [AR1,P#0.0]; // Syntax-ID aus dem Any-Pointer auslesen
      T     #SyntaxID; 
      L     B [AR1,P#1.0]; // Bereichstyp auslesen (B#16#2 = Byte; B#16#4 = Word)
      T     #Bereichstyp; 
      L     W [AR1,P#2.0]; // Anzahl der zu übertragenden Werte (Byte/Word)
      T     #Anzahl_Werte; 
      L     W [AR1,P#4.0]; // DB-Nummer auslesen
      T     #DB_Nr; 
      L     D [AR1,P#6.0]; // Pointer Startadresse auslesen
      T     #Startadresse; 

NETWORK
TITLE =Offset auf Ziehlfeld berechnen

      L     #ENTRY_NO; 
      +     -1; 
      L     #Anzahl_Werte; 
      *I    ; 
      ITD   ; 
      SLD   3; 
      L     #Startadresse; 
      +D    ; 
      T     #Startadresse; 
NETWORK
TITLE =Pointer auf das Ziehlfeld ausgeben

      L     P##DST_ANY; 
      LAR1  ; 
      L     #SyntaxID; 
      T     B [AR1,P#0.0]; // Syntax-ID in den Any-Pointer schreiben
      L     #Bereichstyp; 
      T     B [AR1,P#1.0]; // Bereichstyp schreiben (B#16#2 = Byte; B#16#4 = Word)
      L     #Anzahl_Werte; 
      T     W [AR1,P#2.0]; // Anzahl der zu übertragenden Werte (Byte/Word)
      L     #DB_Nr; 
      T     W [AR1,P#4.0]; // DB-Nummer schreiben
      L     #Startadresse; 
      T     D [AR1,P#6.0]; // Pointer Startadresse schreiben
NETWORK
TITLE =Adressregister zurüchschreiben
      LAR1  #T_AR1; 
      LAR2  #T_AR2; 
END_FUNCTION
 
Zuviel Werbung?
-> Hier kostenlos registrieren
So André, der Hinweis war sehr hilfreich, typischer Anfall von Betriebsblind. So geht es dann auch mit IN_OUT, was einiges an Speicherplatz im IDB einspart.

Code:
      L     P##Schreibstring
      LAR1  
      L     W [AR1,P#0.0]               // DB_Nr Schreibstring
      T     #DB_NR
//      AUF   DB [#DB_NR]               // DB Schreibstring öffnen [COLOR=Red]--> Das kann man auch weglassen, im Test geht es ohne![/COLOR]
      L     D [AR1,P#2.0]               // Pointer auf Datenbereich Schreibstring
      LAR1                              // ins Adressregister --> [B][COLOR=Red]Das hatte ich vergessen :???:[/COLOR][/B]
      SRD   3                           // macht aus dem Pointer wieder die Datenwortnummer
      T     #Schreib_DW                 // Datenwortnummer als Int 

//nun verschieben wir den Schreibstring in das Nest
      CALL  "BLK_MOVE"
       AnzahlDBB:=#Anzahl
       QuellDB  :=#DB_NR
       QuellDW  :=#Schreib_DW
       ZielDB   :=#IDB
       ZielDW   :=#IntAdr_aktNest
       RET_VAL  :=#RetVal
 
Zuletzt bearbeitet:
@Markus

So in der Art mach ich das auch in meiner DB-Datenbank, aber ein das in einem FC zu kapseln ist eine gute Idee.
 
Zurück
Oben