Step 7 VAR_Input String nach DB verschieben

MC_DARKSTONE

Level-1
Beiträge
25
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi,
ich bräuchte etwas hilfe mit dem verschieben von einem String in ein DB.
Ein FC bekommt als Input ein String und dieser soll dann in ein DB ab pos X gespeichert werden.

Ich könnte es mit einer Schleife und dem FC26 "Middle part of a STRING" machen

Code:
%DB30.DBB[Zeiger]:=CHAR_TO_BYTE(STRING_TO_CHAR(MID(in:= Befehl, l:=1, P:=I)))
I:=I+1
Zeiger:=Zeiger +1

Kennt einer eine bessere Variante z.B. via BLKMOVE...

Zudem wollte ich die Länge das Strings erfahren mit "FC21" Length of a STRING.
aber ich kann für S:= nicht die Input Variable angeben, Fehlermeldung "Parameterübergabe nicht Korrekt"
Es funktioniert nur wenn ich "Befehl" einem TempString übergebe, warum?

Code:
FUNCTION FC3: VOID 
TITLE = 'SCL_BLOCK'

VAR_INPUT
     Befehl: STRING[20];     
END_VAR
VAR
    MERKER : BOOL;
    I : INT;
    MERKER_FOR : BOOL;
    Anzahl:INT;
    TempString:STRING[20];
    Zeiger:INT;
END_VAR

BEGIN
Zeiger:=50;
TempString:=Befehl;
Anzahl := LEN(S :=TempString (*IN: STRING*)    ); // Geht
Anzahl := LEN(S :=Befehl (*IN: STRING*)    ); // Geht nicht

REPEAT
        %DB30.DBB[Zeiger]:=CHAR_TO_BYTE(STRING_TO_CHAR(MID(in:=TempString, l:=1, P:=I))); // Geht
        %DB30.DBB[Zeiger]:=CHAR_TO_BYTE(STRING_TO_CHAR(MID(in:=Befehl, l:=1, P:=I)));  // Geht nicht
        I:= I+1;
        Zeiger:=Zeiger+1;

    UNTIL I = Anzahl -1
    END_REPEAT;
.....


Versuch mit BLKMOVE erzeugt den Fehler "Ungültiger oder fehlender Funktionstyp"
egal ob TempString oder Befehl eingesetzt wird

Code:
FUNCTION FC204: VOID 

VAR_INPUT
    Befehl: STRING[20];
END_VAR
VAR_TEMP
    TempString:STRING[20];
    Struct_pointer: STRUCT
        ANY_ID:BYTE; // S7 Pointer =10h
        SOURCE_DATATYPE:BYTE; // Datentyp des Byte=2 Word=4
        SOURCE_LENGHT:WORD;
        SOURCE_DBNUMMER:WORD;
        SOURCE_BYTE_POINTER:BYTE; // Speicherbereich 84=DB
        SOURCE_BYTE7: BYTE; // Bit 0,1,2 Byteadresse (letzte stellen der 16Bit 0=15, 1=14, 2=13)
        SOURCE_BYTE8: BYTE; // Bit 0-7 Byteadresse (Bit 7=12...0=6)
        SOURCE_BYTE9: BYTE; //Bit 7-3 ByteAdresse Bit 2-0 Bitadresse)
        (* BSP für DB2.DBX5.4  5= 101 / 4= 100
        SourceByte7 = 0, SourceByte8 = 0, SourceByte9 = b#0010 1100 *) 
    END_STRUCT;
    
pANY_SOURCE AT Struct_pointer: ANY;
END_VAR

BEGIN
//------------------------------------------------
// AnyPointer Erstellen P#DB250.DBX23.0 WORD 20
//------------------------------------------------
Struct_pointer.ANY_ID:= 16#10;
Struct_pointer.SOURCE_DATATYPE:= 16#4; // DATENTYPE FESTELGEN WORD
Struct_pointer.SOURCE_LENGHT := 16#14;
Struct_pointer.SOURCE_DBNUMMER := 16#FA;
Struct_pointer.SOURCE_BYTE_POINTER:= 16#84;
Struct_pointer.SOURCE_BYTE7:= 2#0;
Struct_pointer.SOURCE_BYTE8:= 2#0;
Struct_pointer.SOURCE_BYTE9:= 2#10111000;

BLKMOV(SRCBLK := TempString // IN: ANY
       ,DSTBLK := pANY_SOURCE // OUT: ANY
       ); // INT

....
Danke
Gruß
Erick
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Bastel Dir in VAR_TEMP mittels AT-Sicht einen ANY auf Deinen DB-Zielbereich zusammen, dann kannst Du mit BLKMOV kopieren:
Code:
VAR_INPUT
  Befehl: STRING[20];
END_VAR
VAR_TEMP
  result : INT;
  tmpAny : ANY ;
  _tmpAny AT tmpANY : STRUCT
    syntaxID: BYTE;
    dataType: BYTE;
    dataCount: WORD;
    dbNumber: WORD;
    areaPointer: DWORD;
  END_STRUCT;
END_VAR

  //Zielbereich-ANY basteln, z.B. P#DB30.DBX50.0 STRING 1
  _tmpAny.syntaxID    := 16#10;
  _tmpAny.dataType    := 16#13; //STRING
  _tmpAny.dataCount   := 1;
  _tmpAny.dbNumber    := 30;    //DB30
  _tmpAny.areaPointer := 16#84000000 OR INT_TO_DWORD(50 * 8); //P#DBX50.0

  result := BLKMOV(SRCBLK := Befehl, DSTBLK := tmpAny);

(statt "P#DB30.DBX50.0 STRING 1" sollte auch funktionieren "P#DB30.DBX50.0 BYTE 20", ich weiß jetzt aber grad nicht, ob BLKMOV das evtl. anders ausführt)

Harald
 
Moin,
Danke für die Antworten.

Es funktioniert. Ich hatte vergessen dem BLKMOVE ein Return Val zu geben
I entspricht dem RET_VAL //INT
Code:
I:=BLKMOV(SRCBLK := Befehl // IN: ANY
       ,DSTBLK := pANY_SOURCE // OUT: ANY
       ); // INT

Um den String zu Verschieben ist es egal ob der AnyPpinter als ein BYTE, WORD, CHAR... deklariert ist. Nur wenn man ihn als STRING deklariert wird nichts kopiert
Zudem kann der Anypointer eine beliebige Anzahl an Daten kopieren.
Bei 1 Byte wird das erste CHAR kopiert und
bei 100 Byte erfolgt die max Länge des Stringes (ohne Stringkopf).

Gruß
Erick
 
Zurück
Oben