TwinCat 3 - String mit mehr als 255 Char einzelnd mit einem Pointer auslesen

Jaggerman

Level-1
Beiträge
4
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

seit mehreren Tagen scheitere ich bereits daran, in TC3 eine lange Exceltabelle erfolgreich einzulesen.
Also was mir bisher möglich ist, ist das Excel-File mit Hilfe der FB_Open und FB_Read in einen sehr langen einzelnen String einzulesen.
Nun muss ich diesen String allerdings wieder zerhacken um ihn in ein mehrdimensionales Array entsprechend des ursprünglichen Excel-Files zu bekommen.
Wie kann ich nun mein
FILEDATA : String(30000);
mit einem Pointer von links nach rechts hoch laufen, und dabei jedes einzelne Char auslesen und weiterverarbeiten?

Das bereits existierende Thema: "einzelne CHAR aus String lesen in ST "
http://www.sps-forum.de/codesys-und-iec61131/52285-einzelne-char-aus-string-lesen-st.html
hat mich leider auch nicht richtig vorwärts gebracht.

Mein bisheriger Ansatz:
Code:
FUNCTION_BLOCK FB_SortExcelInputToArray
VAR_INPUT
    Datastring : STRING(30000);
END_VAR
VAR_OUTPUT
END_VAR
VAR
    countrows: INT :=0;
    countcolumns : INT :=0;
    ptString : POINTER TO STRING;
    strCompareChar :String(1);
    ptByteArray : POINTER TO ARRAY[0..30000] OF BYTE;
    Dataarray : ARRAY[0..30000] OF BYTE;
    ptByteChar : POINTER TO BYTE;
    nStringSize : DINT;
    nPointPos : DINT;
END_VAR
_____________________________________________________________________________________________
ptByteArray := ADR(Datastring);
nPointPos:=0;
nStringSize := SIZEOF(Datastring);
countrows:=1;
countcolumns:=1;

WHILE nPointPos < nStringSize DO
    ptByteChar := ptByteArray^[nPointPos];
    ptString := ptByteChar;
    strCompareChar := ptString^;

     IF strCompareChar ='$N' THEN
        countrows:= countrows+1;
        nPointPos:=nPointPos+1;     
     END_IF

    IF strCompareChar =';' THEN
        countcolumns:=countcolumns+1;
        nPointPos:=nPointPos+1;        
    END_IF
    
    ExcelInputDat[countrows,countcolumns]:= concat(ExcelInputDat[countrows,countcolumns],strCompareChar);
    nPointPos:=nPointPos+1;    
END_WHILE

Freue mich über jede konstruktive Hilfe :)
 
Hi,

mal abgesehen davon, dass ich nicht weiß ob es möglich ist, einen String der Länge 30000 zu definieren, kannst du seit Twincat3 die einzelnen Zeichen nun auch ganz einfach auslesen, indem du wie in einem Array darauf zugreifst:
Datastring := 'Hallo World'
Datastring[1] = 'H';
Datastring[2] = 'a';
Datastring[3] = 'l';
Datastring[4] = 'l';
Datastring[5] = 'o' usw...


D. H. dieses array könntest du auch in einer Forschleife durchlaufen. Macht vieles einfacher.
Zur Excel Auswertung: würde nicht den ganzen Inhalt des Excel- files in den String lesen, sondern die headerline auslesen und spaltenweise vorgehen.

mfg
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Zur Klarstellung: Lädst Du tatsächlich ein binäres Excel-File oder ist es vielleicht eher eine CSV-Datei oder eine XML-Datei?
Eine csv-Datei würde ich zeilenweise einlesen und splitten.

Harald
 
Danke schon mal,

also die Definition des Strings wird erst bei mehr als 2^15 Zeichen von TC verweigert, also hoffe ich derzeit noch, dass so viele Zeichen auch wirklich eingelesen werden können. (Extremtest mit komplett vollem Excelfile folgt noch)
Allerdings bekomme ich beim Build meines Programms immer eine Fehlermeldung in der Zeile:
if Datastring[nPointPos] ='$N' then...... --> Cannot Compare Type BYTE with type STRING!

Sicher das man so ohne weiteres die einzelnen Char des Strings auslesen kann?

MFG Micha
 
Hallo Harald,

in der tat möchte ich ein .csv File einlesen, allerdings habe ich bislang noch keine Möglichkeit gesehen, dieses Zeilenweise einzulesen, da ich vorab nicht sagen kann, wie viele Zeichen (und somit wie viel Byte) eine Zeile enthält, da die Zeilenlänge in dem File variabel ist.
Habe dafür bisher nur FB_Read und FB_Gets in betracht gezogen und damit keinen Lösungsansatz gehabt.
Bin aber für Anregungen sehr dankbar!

Gruß Micha
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Sicher das man so ohne weiteres die einzelnen Char des Strings auslesen kann?

ja, sicher, geht schnell und einfach und seit Codesys 3 möglich. Es muss also kein Pointer mehr definiert und durchgereicht werden. Es gibt auch die Möglichkeit den string zusammen mit einem byte array in einer UNION abzuspeichern. Dort teilen sich alle Variablen dieser Struktur den gleichen speicherbereich. So bekommst du die einzelnen Charakter ohne groß was zu machen in einzelne Bytes abgebildet, allerdings dann im Ascii Code.

..allerdings habe ich bislang noch keine Möglichkeit gesehen, dieses Zeilenweise einzulesen
mit FB_FileGets. der gibt dir dann direkt eine ganze Line aus der Datei. Wahlweise kannst du auch händisch nach dem Steuerzeichen für einen Zeilenumbruch suchen, sollten entweder '/n' oder '$n' sein da bin ich aber gerade nicht mehr sicher.

mfg
 
Zuletzt bearbeitet:
Hallo nochmal,

also wie bereits angemerkt funktioniert der Zugriff auf die Char nicht einfach mit Datastring[number], da dies ein Byte ausgibt.
Allerdings habe ich inzwischen selber die Lösung herausgefunden:
mit
Code:
sCharacter:=F_ToCHR(c:=Datastring[number]);
funktioniert der Zugriff auf die einzelnen Chars... :)
 
Ja genau, wie erwähnt die Zeichen werden im Ascii-Code dargestellt. Ist aber an sich kein Problem. Entweder vorher umwandeln und dann vergleichen, oder nachher. F_ToCHR ist eine Möglichkeit, genau!!!
 
Zurück
Oben