String-Array in CSV exportieren

Socher

Level-2
Beiträge
27
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo in die Runde,

ich stehe gerade irgendwie auf dem Schlauch. Ich möchte auch TC3 eine Array mit Sting Variablen in eine CSV Date exportieren.

Der Export funktioniert im großen ganzen schon mal, nur beim öffnen der CSV Date stehen immer Hieroglyphen dabei.

Code:
VAR_INPUT

    bStart : BOOL;

     bReset : BOOL; (* Reset bei Fehler *)

    sNetId    : T_AmsNetId := ''; (* TwinCAT system network address *)

    sFileName       : T_MaxString := 'c:\TextModeGen.csv';(* CSV destination file path and name *)

    inp_Time        : STRING;

    inp_ZW_1        : REAL := 0 ;



END_VAR

VAR

    FB_Speicherzeit    : TON ;

    i                : UINT;                                  // Hilfsvariable zur Array Initialisierung

    ST_Zeit                : STRING ;

    ST_Wert1            : STRING ;

    a_Datenarray    : ARRAY [0..1000]  OF STRING; // Datenspeicher



// Schreiben einer Datei



    bError : BOOL ;

    Step : INT;

     Start : R_TRIG;

     open1 : FB_FileOpen;

     write1 : FB_FileWrite;

     close1 : FB_FileClose;   

    FB_Fehler_Zuruecksetzen    : TON ;

END_VAR

Code:
FB_Speicherzeit(IN:= NOT FB_Speicherzeit.Q, PT:= T#1M, Q=> , ET=> );

IF FB_Speicherzeit.Q THEN

    FOR i := 336 TO 2 BY -1 DO   
        a_Datenarray[i] := a_Datenarray[i-1];
    END_FOR

ST_Zeit    := inp_Time;   
ST_Wert1 :=  LREAL_TO_STRING(REAL_TO_LREAL(inp_ZW_1));

a_Datenarray[0] := CONCAT(CONCAT(CONCAT('Zeit',';'),'Zählerstand'), ';');
a_Datenarray[1] := CONCAT(CONCAT(CONCAT(ST_Zeit,';'),ST_Wert1), ';');

END_IF

// Schreiben der Daten in eine Datei

CASE step OF
0: (* Ruhezustand *)
 open1.bExecute := FALSE;
 write1.bExecute := FALSE;
 close1.bExecute := FALSE;
 Start(CLK:= bStart, Q=> ); (* Start durch Flanke *)
 IF Start.Q THEN
 step := 1;
 END_IF
1: (* Datei öffnen *)
 open1.bExecute := TRUE;
 step := step + 1;
2: (* Warten bis Datei geöffnet ist *)
 IF NOT open1.bBusy THEN
 IF NOT open1.bError THEN
 write1.bExecute := TRUE;
 step := step + 1;
 ELSE
 bError := TRUE; (* Fehler beim Öffnen *)
 step := 0;
 END_IF
 END_IF
3: (* Schreibvorgang abgeschlossen ? *)
 IF NOT write1.bBusy THEN
 write1.bExecute := FALSE;
 close1.bExecute := TRUE; (* Datei wird wieder geschlossen *)
 step := step + 1;
 END_IF
4: (* Warten bis Datei geschlossen ist *)
 IF NOT close1.bBusy THEN
 bError := write1.bError OR close1.bError;
 step := 0;
 END_IF
END_CASE

(* AKTIONEN: *)

open1(
 sNetId:= sNetId ,
 sPathName:= sFileName ,
 nMode:=FOPEN_MODEAPPEND OR FOPEN_MODETEXT ,
 ePath:= PATH_GENERIC ,
 bExecute:= ,
 tTimeout:= t#2s,
 bBusy=> ,
 bError=>,
 nErrId=>,
 hFile=> );

write1(
 sNetId:= sNetId,
 hFile:=open1.hFile ,
 pWriteBuff:= ADR (a_Datenarray),
 cbWriteLen:= SIZEOF (a_Datenarray),
 bExecute:= ,
 tTimeout:= T#60S,
 bBusy=> ,
 bError=> ,
 nErrId=>,
 cbWrite=>);

close1(
 sNetId:= sNetId,
 hFile:=open1.hFile ,
 bExecute:= ,
 tTimeout:= t#2s,
 bBusy=> ,
 bError=> ,
 nErrId=> );

(* Fehler Reset *)

FB_Fehler_Zuruecksetzen(IN:= bError, PT:= T#30S, Q=> , ET=> );

IF FB_Fehler_Zuruecksetzen.Q THEN
 step := 0;
 bError:= FALSE;
END_IF

Danke schon mal für eure Hilfe
 
Das funktioniert aus mehreren Gründen nicht.
Die Stringvariablen in a_Datenarray sind jeweils 256 Byte groß (max. 255 Zeichen + Nullterminator). Wenn du beim Schreiben cbWriteLen mit SizeOf(a_Datenarray) angibst, werden von jedem String alle 256 Bytes gespeichert, auch wenn die tatsächlichen Stringlängen kürzer sind.
Um mit FOPEN_MODETEXT Strings zu schreiben, mußt du eigentlich den FB_FilePuts verwenden. Mit dem kannst du aber pro Aufruf mit bExecute:=True immer nur einen String schreiben. Bei 1000 Strings dauert das ziemlich lange.
Am besten sammelst du die Strings in einem großen Byte-Puffer von Hand und schreibst dann mit einem FileWrite-Aufruf den gesamten Puffer, dann aber mit FOPEN_MODEBINARY. Dann mußt du dich allerdings von CONCAT verabschieden und alle Sonder- und Steuerzeichen wie z. B. Zeilenumbrüche selbst in den Puffer einfügen.
 
Zurück
Oben