天天看點

西門子SCL程式設計執行個體—多個位元組轉換字元串Byte_String

作者:巨控小周

關于多個位元組轉換字元串博途有更簡單的方法,但是這個也是不錯的思路可以借鑒學習。

該功能将多個位元組(從“開始”開始,到“結束”結束)複制到一個字元串中。另外還将寫入資料的長度複制到字元串标頭中。

可以将任意類型的輸入資料(數組、字元串等)附加到“DATA_IN”。必須在“DATA_OUT”上對字元串提前進行參數化。

西門子SCL程式設計執行個體—多個位元組轉換字元串Byte_String
西門子SCL程式設計執行個體—多個位元組轉換字元串Byte_String
西門子SCL程式設計執行個體—多個位元組轉換字元串Byte_String

功能說明:

資料塊接受任意輸入變量(數組、字元串或資料區域)并從輸入區域DATA_IN的位元組“開始”到“結束”将資料複制到輸出區域“DATA_OUT”。“DATA_OUT”處的資料按字元串處理。

如果要從輸入端的char數組中複制位元組0到位元組10(包括位元組10),則必須指定數值“開始”=0;;“結束”=10。0将資料複制到DATA_OUT的字元串中。

如果要将輸入端的一個字元串從第一個字母複制到第12個字母則必須對“開始”=2和“結束”=13進行參數化。

如果需要複制的資料區域大于輸出端上的字元串,則不會進行複制并将輸出端PaFe設定到1。

如果DATA_OUT未進行參數化,則輸出PaFe=2。PaFe=3,則輸入資料過短(檢查“開始”和“結束”,輸入端“結束”上的數值可能位于輸入端“開始”的數值前)。

然後可以使用其他系統功能(例如CONCAT)将輸出的字元串附加到另一個字元串。或者也可以繼續調整INSERT。

代碼:

西門子SCL程式設計執行個體—多個位元組轉換字元串Byte_String
REGION (* Programm *)
    //Zeiger kopieren
    #DATA_IN_T := #DATA_IN;
    #DATA_OUT_T := #DATA_OUT;
    
    #dBZ_Hilfsvariable := #p_DATA_OUT.BZ;//BZ sichern  
    
    //Zeiger anpassen um den Header zu lesen/schreiben
    #p_DATA_OUT.DataCount := 1;            //nur 1 Byte schreiben
    
    //Laenge des Ausgabestring lesen
    #erg_SFC20 := BLKMOV(SRCBLK := #DATA_OUT_T, DSTBLK => #bHeader_Str_Laenge);
    
    #bHeader_Str_Inhalt := INT_TO_BYTE(#Ende - #Start + 1);
    
    #PaFE := 0;
    IF BYTE_TO_INT(#bHeader_Str_Laenge) < (#Ende - #Start + 1) THEN
        #PaFE := 1;    //Ausgabedaten zu lang fuer Ausgabestring
    ELSIF #p_DATA_OUT.DBNR = 0 THEN
        #PaFE := 2;    //kein Ausgangfeld festgelegt
    ELSIF (#Ende - #Start + 1) < 1 THEN
        #PaFE := 3;    //Eingabedaten zu kurz
    ELSIF #Start < 0 THEN
        #PaFE := 4;    //Startwert kleiner 0
    ELSE
        #PaFE := 0;
    END_IF;
    
    //Daten kopieren, wenn Fehler = 0
    IF #PaFE = 0 THEN
        
        (***********String Laenge in Ausgabestring schreiben**************************)
        //BZ_Hilfsvariable ist der gesicherte Beginn vom unveraenderten Zeiger
        //Zeiger setzen auf Byte 0, dies entspricht der String Laenge
        #p_DATA_OUT.BZ := (#dBZ_Hilfsvariable AND dw#16#FFFF0000) OR #dBZ_Hilfsvariable (*+ 0*);
        
        //Header des OUTPUT schreiben 
        #erg_SFC20 := BLKMOV(SRCBLK := #bHeader_Str_Laenge, DSTBLK => #DATA_OUT_T);
        (*****************************************************************************)
        
        (***********Belegte Laenge in Ausgabestring schreiben**************************)
        //BZ_Hilfsvariable ist der gesicherte Beginn vom unveraenderten Zeiger
        //Zeiger setzen auf Byte 1, dies entspricht der belegten String Laenge
        #p_DATA_OUT.BZ := (#dBZ_Hilfsvariable AND dw#16#FFFF0000) OR INT_TO_DWORD(DWORD_TO_INT(#dBZ_Hilfsvariable) + 1 * 8);
        
        //Header des OUTPUT schreiben 
        #erg_SFC20 := BLKMOV(SRCBLK := #bHeader_Str_Inhalt, DSTBLK => #DATA_OUT_T);
        (*****************************************************************************)
        
        //Zeiger anpassen INPUT
        #p_DATA_IN.DataCount := BYTE_TO_WORD(#bHeader_Str_Inhalt);
        #p_DATA_IN.BZ := (#p_DATA_IN.BZ AND dw#16#FFFF0000) OR INT_TO_DWORD(DWORD_TO_INT(#p_DATA_IN.BZ) + #Start * 8);
        
        //Zeiger anpassen OUTPUT
        #DATA_OUT_T := #DATA_OUT;
        #p_DATA_OUT.DataCount := #p_DATA_IN.DataCount;
        #p_DATA_OUT.BZ := (#dBZ_Hilfsvariable AND dw#16#FFFF0000) OR INT_TO_DWORD(DWORD_TO_INT(#dBZ_Hilfsvariable) + 2 * 8);
        
        //Daten kopieren
        #erg_SFC20 := BLKMOV(SRCBLK := #DATA_IN_T, DSTBLK => #DATA_OUT_T);
    END_IF;
END_REGION



           

繼續閱讀