Mal wieder CSV in Flex (Kann es selbst nicht mehr sehen)

Matze001

Well-known member
Beiträge
2.509
Punkte Reaktionen
486
Zuviel Werbung?
->Hier kostenlos registrieren
Guten Morgen,

ich muss mich mal wieder ein wenig mit CSV in Flex rumschlagen!

Für meine PC-Runtime habe ich ein kleines Script gebastelt, welches stupide ein paar Werte in eine CSV-Datei schreibt.
Das funktioniert alles bestens. Mit einem anderen Script zeige ich diese an, und so ab 20-30.000 Zeilen dauert das schon ne Weile!

Deshalb wäre meine Überlegung den Inhalt der Datei auf 10.000 Zeilen zu begrenzen. (Mehr sind sicher nicht nötig für meine Anwendung).

Leider fehlt mir da der Aha-Effekt wenn ich durch die Befehlsliste von Flex heize.
Ansatz wäre:
Schreibe Zeile an das Ende der Datei
Lese Anzahl der Datensätze
Wenn > 10.000 dann lösche Zeile 1

Je nachdem wie performant der Spass ist, lasse ich das auch als Zyklisches Script alle 10Std. mal laufen (und lösche so das ich wieder auf <10k kommen)

Grüße

Marcel
 

Sinix

Well-known member
Beiträge
1.588
Punkte Reaktionen
216
Aha, da loggt einer die Bedienkonsole mit ;)...
Ein Ansatz wäre doch eine neue Datei bei >10k und die Vorletzte sofern vorhanden zu löschen.
 

SUW

Well-known member
Beiträge
82
Punkte Reaktionen
22
Zuviel Werbung?
->Hier kostenlos registrieren
Hallo,
wenn es um viele Werte aus einem DB von der Steuerung geht kann sich das Flexible Script schon mal verschlucken beim Werte in CSV schreiben und gleichzeitig von der Steuerung holen (meines Wissens nach ist das vom Bus abhängig).
Hatte ein ähnlichs Problem, musste 4 DBs mit jeweils 65568 Byte in eine CSV schreiben dabei verschieden Probleme beim Scripting und Datenaktualisieren festgestellt sowie an der Laufzeit des Scripts.
Meine Lösung war ein ODK Baustein "FileIO" der vom PC (WinAC) direkt den DB aus der S7 in ein Binär-File schreibt. Dieses File haben wir dann noch nach ASCII gewandelt und so hatten wir in 2 Sekunden die 4 DBs in einer CSV.

Wenn du allerdings keine WinAC hast, dann hilft dir leider die Lösung nicht.
 
OP
M

Matze001

Well-known member
Beiträge
2.509
Punkte Reaktionen
486
Hallo,

ich habe ne WinAC und die Flex RT. Die Lösung mit dem ODK wäre also möglich, und sogar mein Favorit! Aber -> Es darf ja nix kosten ;)
Vielleicht bekomme ich das ja noch hin, jemanden davon zu überzeugen. Alternativ wollte ich mal schauen ob ich irgendwas mit dem OPC machen kann... habe ich aber noch nie mit gearbeitet.

Ich logge sicher nicht die Bedienkonsole mit, sondern erfasse Betriebsdaten (Stückzähler). Für jedes Teil wird eine Zeile mit Timestamp, Infos, etc. erstellt und besteht aus 6 Werten.

Grüße

Marcel
 

PN/DP

User des Jahres 2011 - 2013; 2015 - 2017; 2020
Beiträge
17.559
Punkte Reaktionen
5.165
Du könntest ein segmentiertes Umlaufarchiv machen.
Deine Zeilen sind ungefähr gleich lang? Es müssen nicht genau 10.000 Zeilen sein?
Du könntest die Dateigröße in Byte abfragen und wenn größer 500kByte dann eine zweite CSV-Datei anfangen.
Wenn diese dann auch "voll" ist, dann die erste Datei löschen und neu beschreiben usw.
Je nachdem wieviel % Du löschen willst, kannst Du auch mit 3 oder mehr Segmenten/Dateien arbeiten.

Harald
 
OP
M

Matze001

Well-known member
Beiträge
2.509
Punkte Reaktionen
486
Jetzt gibt es schon wieder das Thema... wollte keine Religionskriege :-D

CSV ist ein Sammelsurium aus dem Forum, ein wenig auf meine Bedürfnisse angepasst. Ist noch nicht hübsch, sondern grad eher in der "Test- und Verstehphase"...

Hier habt ihr das Archivierungsscript:

Code:
Dim fso, f, ts, Dateiname, VZ_NAME, DT_STRING, DT_SPLIT, i

' Script nur Durchlaufen wenn Werte vorhanden, um Nulleinträge zu verhindern
If    (SmartTags("ARCHIVIERUNG\WERT")(0) > 0) Or (SmartTags("ARCHIVIERUNG\WERT")(1) > 0) Or (SmartTags("ARCHIVIERUNG\WERT")(2) > 0) Or (SmartTags("ARCHIVIERUNG\WERT")(3) > 0) Or    (SmartTags("ARCHIVIERUNG\WERT")(4) > 0) Or    (SmartTags("ARCHIVIERUNG\WERT")(5) > 0) Or    (SmartTags("ARCHIVIERUNG\WERT")(6) > 0) Or    (SmartTags("ARCHIVIERUNG\WERT")(7) > 0) Or    (SmartTags("ARCHIVIERUNG\WERT")(8) > 0) Or    (SmartTags("ARCHIVIERUNG\WERT")(9) > 0) Or    (SmartTags("ARCHIVIERUNG\WERT")(10) > 0) Or    (SmartTags("ARCHIVIERUNG\WERT")(11) > 0) Or    (SmartTags("ARCHIVIERUNG\WERT")(12) > 0)  Or (SmartTags("ARCHIVIERUNG\WERT")(13) > 0) Or    (SmartTags("ARCHIVIERUNG\WERT")(14) > 0) Or    (SmartTags("ARCHIVIERUNG\WERT")(15) > 0) Then   


Set fso = CreateObject ("Scripting.FileSystemObject")
' DATUM UHR VON SPS

DT_STRING = Replace(SmartTags("COM_VISU\COM_VISU.Uhrzeit_Panel"), " ", ".")
DT_STRING = Replace (DT_STRING, ":", ".")
DT_SPLIT  = Split(DT_STRING, ".")
 
' AUSGABE = JAHR           .    MONAT          .    TAG           LEERZEICHEN     STUNDE           :    MINUTE    
DT_STRING = DT_SPLIT(2) & "." & DT_SPLIT(1) & "." & DT_SPLIT(0)     & " " &        DT_SPLIT(3) & ":" & DT_SPLIT(4) 

' VERZEICHNIS
 VZ_NAME = "D:\BDE\" 'SmartTags("DATEIABLAGE")

' Verzeichnis erzeugen (Objekt erzeugen)
Set fso = CreateObject("Scripting.FileSystemObject")
'Prüfung ob das Verzeichnis existiert
If Not fso.FolderExists(VZ_NAME) Then  ' Wenn es nicht existiert, dann anlegen
   fso.CreateFolder (VZ_NAME)
Else 'Fehlermeldung ausgeben
End If
 
' Schreiben zu Internem Medium. Vorwahl über Bildschirmgrafik.
 Dateiname = VZ_NAME & "ZAEHLER.csv" 
' CSV-DATEI ANLEGEN UND SPALTENÜBERSCHRIFTEN EINTRAGEN
If Not fso.FileExists(Dateiname) Then
   fso.CreateTextFile (Dateiname)
   Set f=fso.GetFile(Dateiname)
   Set ts=f.OpenAsTextStream(8,-2) 
   ts.WriteLine ("DATUM UND UHRZEIT; REZEPTUR_ID; WERT 0 ; WERT 1 ; WERT 2 ; WERT 3 ; WERT 4 ; WERT 5 ; WERT 6 ; WERT 7 ; WERT 8 ; WERT 9 ; WERT 10 ; WERT 11 ; WERT 12 ; WERT 13 ; WERT 14 ; WERT 15 ")
   ts.Close
End If
' VARIABLEN IN CSV-DATEI SCHREIBEN 
Set f=fso.GetFile(Dateiname)
Set ts=f.OpenAsTextStream(8,-2) 
   ts.WriteLine (DT_STRING  & ";" & SmartTags("REZEPTUR\REZEPTUR.MASCHINE.Rezeptur_ID") & ";" & SmartTags("ARCHIVIERUNG\WERT")(0) & ";" & SmartTags("ARCHIVIERUNG\WERT")(1)  & ";" & SmartTags("ARCHIVIERUNG\WERT")(2) & ";" & SmartTags("ARCHIVIERUNG\WERT")(3) & ";" & SmartTags("ARCHIVIERUNG\WERT")(4) & ";" & SmartTags("ARCHIVIERUNG\WERT")(5) & ";" & SmartTags("ARCHIVIERUNG\WERT")(6) & ";" & SmartTags("ARCHIVIERUNG\WERT")(7) & ";" & SmartTags("ARCHIVIERUNG\WERT")(8) & ";" & SmartTags("ARCHIVIERUNG\WERT")(9) & ";" & SmartTags("ARCHIVIERUNG\WERT")(10) & ";" & SmartTags("ARCHIVIERUNG\WERT")(11) & ";" & SmartTags("ARCHIVIERUNG\WERT")(12) & ";" & SmartTags("ARCHIVIERUNG\WERT")(13) & ";" & SmartTags("ARCHIVIERUNG\WERT")(14) & ";" & SmartTags("ARCHIVIERUNG\WERT")(15))
   ts.Close
      
     
      
' Werte nach Schreiben in die Datei abnullen

SmartTags("ARCHIVIERUNG\WERT")(0) = 0  
SmartTags("ARCHIVIERUNG\WERT")(1) = 0  
SmartTags("ARCHIVIERUNG\WERT")(2) = 0  
SmartTags("ARCHIVIERUNG\WERT")(3) = 0  
SmartTags("ARCHIVIERUNG\WERT")(4) = 0  
SmartTags("ARCHIVIERUNG\WERT")(5) = 0        
SmartTags("ARCHIVIERUNG\WERT")(6) = 0  
SmartTags("ARCHIVIERUNG\WERT")(7) = 0  
SmartTags("ARCHIVIERUNG\WERT")(8) = 0  
SmartTags("ARCHIVIERUNG\WERT")(9) = 0  
SmartTags("ARCHIVIERUNG\WERT")(10) = 0  
SmartTags("ARCHIVIERUNG\WERT")(11) = 0  
SmartTags("ARCHIVIERUNG\WERT")(12) = 0  
SmartTags("ARCHIVIERUNG\WERT")(13) = 0  
SmartTags("ARCHIVIERUNG\WERT")(14) = 0  
SmartTags("ARCHIVIERUNG\WERT")(15) = 0
     
End If     
     
Set ts = Nothing
Set f = Nothing
Set fso = Nothing
Set Dateiname = Nothing
Exit Sub

Und hier die Ausgabe

Code:
Const ForReading = 1
Dim fso, F, i, j, Zeile(1000000), Inhalt, VON_DATUM, BIS_DATUM, VON_MONAT_NULL, VON_TAG_NULL, VON_STUNDE_NULL, BIS_MONAT_NULL, BIS_TAG_NULL, BIS_STUNDE_NULL


' ########################################################
' Variablen Initialisieren
' ########################################################

SmartTags("ARCHIVIERUNG\AUSGABE")(0) = 0
SmartTags("ARCHIVIERUNG\AUSGABE")(1) = 0
SmartTags("ARCHIVIERUNG\AUSGABE")(2) = 0
SmartTags("ARCHIVIERUNG\AUSGABE")(3) = 0
SmartTags("ARCHIVIERUNG\AUSGABE")(4) = 0
SmartTags("ARCHIVIERUNG\AUSGABE")(5) = 0
SmartTags("ARCHIVIERUNG\AUSGABE")(6) = 0
SmartTags("ARCHIVIERUNG\AUSGABE")(7) = 0
SmartTags("ARCHIVIERUNG\AUSGABE")(8) = 0
SmartTags("ARCHIVIERUNG\AUSGABE")(9) = 0
SmartTags("ARCHIVIERUNG\AUSGABE")(10) = 0
SmartTags("ARCHIVIERUNG\AUSGABE")(11) = 0
SmartTags("ARCHIVIERUNG\AUSGABE")(12) = 0
SmartTags("ARCHIVIERUNG\AUSGABE")(13) = 0
SmartTags("ARCHIVIERUNG\AUSGABE")(14) = 0
SmartTags("ARCHIVIERUNG\AUSGABE")(15) = 0


' ########################################################
' Variablen eine Null vorranstellen, wenn sie kleiner als 10 sind
' ########################################################

If SmartTags("ARCHIVIERUNG\VON_MONAT") < 10 Then
    VON_MONAT_NULL = "0"
Else
    VON_MONAT_NULL = ""    
End If

If SmartTags("ARCHIVIERUNG\VON_TAG") < 10 Then
    VON_TAG_NULL = "0"
Else
    VON_TAG_NULL = ""    
End If

If SmartTags("ARCHIVIERUNG\VON_STUNDE") < 10 Then
    VON_STUNDE_NULL = "0"
Else
    VON_STUNDE_NULL = ""    
End If

If SmartTags("ARCHIVIERUNG\BIS_MONAT") < 10 Then
    BIS_MONAT_NULL = "0"
Else
    BIS_MONAT_NULL = ""    
End If

If SmartTags("ARCHIVIERUNG\BIS_TAG") < 10 Then
    BIS_TAG_NULL = "0"
Else
    BIS_TAG_NULL = ""    
End If

If SmartTags("ARCHIVIERUNG\BIS_STUNDE") < 10 Then
    BIS_STUNDE_NULL = "0"
Else
    BIS_STUNDE_NULL = ""    
End If
    
' ########################################################
' Suchstring zusammensetzen
' ########################################################
VON_DATUM = SmartTags("ARCHIVIERUNG\VON_JAHR") & "." & VON_MONAT_NULL & SmartTags("ARCHIVIERUNG\VON_MONAT") & "." & VON_TAG_NULL & SmartTags("ARCHIVIERUNG\VON_TAG") & " " & VON_STUNDE_NULL & SmartTags("ARCHIVIERUNG\VON_STUNDE") & ":00" 
BIS_DATUM = SmartTags("ARCHIVIERUNG\BIS_JAHR") & "." & BIS_MONAT_NULL & SmartTags("ARCHIVIERUNG\BIS_MONAT") & "." & BIS_TAG_NULL & SmartTags("ARCHIVIERUNG\BIS_TAG") & " " & BIS_STUNDE_NULL & SmartTags("ARCHIVIERUNG\BIS_STUNDE") & ":00"



' ########################################################
' Datei auslesen
' ########################################################
Set fso = CreateObject("Scripting.FileSystemObject")
Set F = fso.OpenTextFile("D:\BDE\ZAEHLER.csv", ForReading)
i = 0
Do While F.AtEndOfStream <> True   
      Zeile(i) = F.ReadLine     
      i = i + 1 
Loop


' ########################################################
' Ausgabe erzeugen
' ########################################################
j = 1 ' Zeile 0 sind Überschriften
Do While j < i   'i enthält die Anzahl der Einträge (+1) in der CSV-Datei
      Inhalt = Split(Zeile(j),";")

' gefundene Rezeptur ID in interne Variable rangieren, damit vergleichen werden kann (Nicht schön, noch ändern!!)
SmartTags("ARCHIVIERUNG\GEFUNDENE_REZEPTUR_ID") = Inhalt(1)

' Nur Addieren wenn sie im gesuchten Zeitraum liegen oder alle Einträge angezeigt werden sollen Und sie der gesuchten Rezeptur ID zugeordnet sind
    If (SmartTags("ARCHIVIERUNG\GEFUNDENE_REZEPTUR_ID") = SmartTags("ARCHIVIERUNG\GESUCHTE_REZEPTUR_ID")) And  (((Inhalt(0) >= VON_DATUM) And (Inhalt(0) <= BIS_DATUM)) Or (SmartTags("ARCHIVIERUNG\GESAMTZAEHLER")))  Then

SmartTags("ARCHIVIERUNG\AUSGABE")(0) =  (SmartTags("ARCHIVIERUNG\AUSGABE")(0) + Inhalt(2))
SmartTags("ARCHIVIERUNG\AUSGABE")(1) =  (SmartTags("ARCHIVIERUNG\AUSGABE")(1) + Inhalt(3))
SmartTags("ARCHIVIERUNG\AUSGABE")(2) =  (SmartTags("ARCHIVIERUNG\AUSGABE")(2) + Inhalt(4))
SmartTags("ARCHIVIERUNG\AUSGABE")(3) =  (SmartTags("ARCHIVIERUNG\AUSGABE")(3) + Inhalt(5))
SmartTags("ARCHIVIERUNG\AUSGABE")(4) =  (SmartTags("ARCHIVIERUNG\AUSGABE")(4) + Inhalt(6))
SmartTags("ARCHIVIERUNG\AUSGABE")(5) =  (SmartTags("ARCHIVIERUNG\AUSGABE")(5) + Inhalt(7))
SmartTags("ARCHIVIERUNG\AUSGABE")(6) =  (SmartTags("ARCHIVIERUNG\AUSGABE")(6) + Inhalt(8))
SmartTags("ARCHIVIERUNG\AUSGABE")(7) =  (SmartTags("ARCHIVIERUNG\AUSGABE")(7) + Inhalt(9))
SmartTags("ARCHIVIERUNG\AUSGABE")(8) =  (SmartTags("ARCHIVIERUNG\AUSGABE")(8) + Inhalt(10))
SmartTags("ARCHIVIERUNG\AUSGABE")(9) =  (SmartTags("ARCHIVIERUNG\AUSGABE")(9) + Inhalt(11))
SmartTags("ARCHIVIERUNG\AUSGABE")(10) =  (SmartTags("ARCHIVIERUNG\AUSGABE")(10) + Inhalt(12))
SmartTags("ARCHIVIERUNG\AUSGABE")(11) =  (SmartTags("ARCHIVIERUNG\AUSGABE")(11) + Inhalt(13))
SmartTags("ARCHIVIERUNG\AUSGABE")(12) =  (SmartTags("ARCHIVIERUNG\AUSGABE")(12) + Inhalt(14))
SmartTags("ARCHIVIERUNG\AUSGABE")(13) =  (SmartTags("ARCHIVIERUNG\AUSGABE")(13) + Inhalt(15))
SmartTags("ARCHIVIERUNG\AUSGABE")(14) =  (SmartTags("ARCHIVIERUNG\AUSGABE")(14) + Inhalt(16))
SmartTags("ARCHIVIERUNG\AUSGABE")(15) =  (SmartTags("ARCHIVIERUNG\AUSGABE")(15) + Inhalt(17))

    End If

j = j + 1
Loop

' Variable zurücksetzen, nachdem das script durchlaufen wurde    
SmartTags("ARCHIVIERUNG\GESAMTZAEHLER") = False

F.Close

Wie gesagt verhaut mich dafür nicht, ich schaufel mich erstmal durch die Funktionen, dann wird es hübsch gemacht!
Habe z.B. in der Ausgabe noch 2 Schleifen, die ich später zu einer machen will (Halbe Scriptlaufzeit) etc.

Grüße

Marcel

P.S: Ich möchte nicht in mehreren Dateien rumheizen, ich möchte einfach die letzten X (müssen nicht 10k) Einträge haben.
 

JesperMP

Well-known member
Beiträge
6.544
Punkte Reaktionen
1.258
Ich begrenze den Grösse von die CSV-Dateien indem das jeden Tag wird eine neue CSV Datei angelegt.
Und den Datum wird ein Teil von Dateiname.
Wäre das eine einfache Lösung ?
 

PN/DP

User des Jahres 2011 - 2013; 2015 - 2017; 2020
Beiträge
17.559
Punkte Reaktionen
5.165
OK, nur eine Arbeits-Datei.

Wenn die Datei > 1MB (oder eine Größe, die etwa 15.000 Zeilen entspricht)
dann die ersten 5.000 Zeilen in einen Dummy-Puffer lesen, dann alle folgenden Zeilen in eine zweite Datei kopieren. Erste Datei löschen. Zweite Datei umbenennen zu Erste Datei.

Dann pendelt Deine CSV-Datei zwischen 10.000 und 15.000 Zeilen.

Harald
 

JesperMP

Well-known member
Beiträge
6.544
Punkte Reaktionen
1.258
Zuviel Werbung?
->Hier kostenlos registrieren
wie wärs mit einer datenbank statts csv? sqlite z.b.
hier gibts dazu etwas code: http://www.djhweb.co.uk/sqlite2.htm
Das ist eine höchst interessante Link !
Auf sqlite.org steht es "Cross-platform: Unix (Linux, Mac OS-X, Android, iOS) and Windows (Win32, WinCE, WinRT) are supported out of the box. Easy to port to other systems."
Also kein Windows 64-bit wäre ein dealbreaker für mich. Hat jemand erfahrung das es trotzdem geht unter Win 64-bit ?
 

Jochen Kühner

Well-known member
Beiträge
4.154
Punkte Reaktionen
474
Das ist eine höchst interessante Link !
Auf sqlite.org steht es "Cross-platform: Unix (Linux, Mac OS-X, Android, iOS) and Windows (Win32, WinCE, WinRT) are supported out of the box. Easy to port to other systems."
Also kein Windows 64-bit wäre ein dealbreaker für mich. Hat jemand erfahrung das es trotzdem geht unter Win 64-bit ?

Denke es sollte da auch laufen... Hier gibt es eine x64 ODBC Treiber: http://www.ch-werner.de/sqliteodbc/ wobei Ich denke man braucht den 32Bit, da die flexible Runtime bestimmt eh keine 64 Bit App ist!
 
OP
M

Matze001

Well-known member
Beiträge
2.509
Punkte Reaktionen
486
Eine Datenbank war auch schon ein Ansatz, aber irgendwie habe ich angst das etwas wie MS-SQL die Kiste zu sehr runterbremst.

sqllite kann ich nicht beurteilen.

Wäre der OPC-Server nicht soetwas wie eine Datenbank? Oder habe ich da ein falsches Verständnis von?

Das schöne an Datenbanken ist ja, dass man durch die Abfragen schon alles erschlagen kann, was ich gerade zu Fuß mit der Zeitraumauswertung machen muss.

Grüße

Marcel
 

Jochen Kühner

Well-known member
Beiträge
4.154
Punkte Reaktionen
474
Zuviel Werbung?
->Hier kostenlos registrieren
Eine Datenbank war auch schon ein Ansatz, aber irgendwie habe ich angst das etwas wie MS-SQL die Kiste zu sehr runterbremst.

sqllite kann ich nicht beurteilen.

Wäre der OPC-Server nicht soetwas wie eine Datenbank? Oder habe ich da ein falsches Verständnis von?

Das schöne an Datenbanken ist ja, dass man durch die Abfragen schon alles erschlagen kann, was ich gerade zu Fuß mit der Zeitraumauswertung machen muss.

Grüße

Marcel

Also Ich hab früher so n Protokoll in MySQL gemacht, und auch mit Flex Scripten daten reingeschrieben. Die auswertung hab Ich allerdings dann über eine Webseite mit Apache und PHP gemacht (aber das ist ja zweitrangig). Denke nicht das der MySQL Server dein System sehr bremst (10000 Datensätze sind ja nun auch nicht so viel).

Aber Ich hab ja SQLLite vorgeschlagen, da dies im Endeffekt ohne Installation (Ok du brauchst den ODBC Treiber) laufen kann. Ist ja kommplett dateibasiert.

Und um die Anzahl der Zeilen zu begrenzen, hab Ich z.B. in meinem Protokoller (http://www.sps-forum.de/showthread.php/46470-DotNetSimaticDatabaseProtokoller) folgende Abfrage drinn:

"DELETE FROM tabelle WHERE id <= SELECT max(id) FROM tabelle) - (10000)"
wobei ID eine Autoincrement Spalte ist!
 

volker

Supermoderator
Teammitglied
Beiträge
5.477
Punkte Reaktionen
937
ich hab zu hause auch ne mysql-datenbank laufen z.b. den kompletten siemens ca10. das sind über 100000 datensätze. reinschreiben und lesen geht sehr schnell. und resourcen brauch der kaum. das wscript verbraucht deutlich mehr.

ein beispiel für access und mysql findest du hier
 
OP
M

Matze001

Well-known member
Beiträge
2.509
Punkte Reaktionen
486
Okay also muss ich mir mal ne SQL-Datenbank drauf werfen.

Hab recht umfangreiche Erfahrungen mit mySQL, das sollte funktionieren.

Grüße

Marcel
 
Oben