Archivierung per skript

Tigerente1974

Level-3
Beiträge
1.826
Reaktionspunkte
293
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Forum.

Ich möchte mich erstmalig an skripte heranwagen.

Die Aufgabenstellung ist folgende:

Eine Palette wird gescannt. Der Barcode soll zusammen mit 2 weiteren Werten in einer csv-Datei abegelegt werden.

Dieses Beispiel von Siemens scheint mir der richtige Ansatz zu sein: http://support.automation.siemens.com/WW/view/de/28937151

Ich habe das Beispielporjekt MP277 geöffnet.
Ich möchte nicht die Variante #2 mit dem Meldearchiv nutzen, sondern die Variante #1.

In der Simulation am laptop erhalte ich die Fehlermeldung "Active X - Komponente kann kein Objekt erstellen FileCtl.FileSystem <Script 01> in Zeile 13"

Ich stehe noch total am Anfang und weiß nicht woran das liegt. Kann jemand helfen?

Edit: Ich arbeite mit WinCC flexible 2008-SP3
 
Es gibt Unterschiede zwischen VB auf Windows CE und auf einem "normalen" Windows PC. Wenn du es in der Simulation laufen lässt sind die Windows Funktionen zu verwenden. Für die Simulation müsstest du das Skript anpassen, oder eine Abfrage für das Betriebssystem einbauen.

Das ist in deinem Link auch weiter verlinkt:
http://support.automation.siemens.com/WW/view/de/13408815
 
Jetzt brauche ich nochmal Hilfe.

In dem Beispielprojekt wurden interne Variablen verwendet.
Ich möchte Werte aus einem Global-DB auf der SPS archivieren.

Leider habe ich weder durch Lesen noch durch Probieren herausgefunden wie das geht.

In dem Beispielskript sah das so aus:

Code:
' Werte der Variablen in die Archivdatei schreiben (Tag_x)
	' Write values of variables in archive file (Tag_x)
	Dataset = CStr(Now) & ";" & CStr(SmartTags("TAG_01")) & ";" & CStr(SmartTags("TAG_02")) 'Create the Dataset'

TAG_01 und TAG_02 sind interne Variablen.

An die Stelle der internen Variablen möchte ich jetzt meine Werte aus dem Global-DB "Daten" schreiben.

Z.B.: Daten.Wert_1

Wie bekomme ich das hin?
 
Wenn du die internen Variablen in der Variablentabelle von WinCC Flexible an die entsprechenden Hardwareadressen von deienm GLOBAL DB bindest müsste es das doch gewesen sein. Oder verstehe ich das falsch?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Vielleicht, oder wahrscheinlich stehe ich auf dem Schlauch...

Aber die interne Variable kann ich nicht mit der Adresse verbinden.
Intern bedeutet ja auch, dass nur das Panel die Variable kennt. So richtig nachvollziehbar fände ich das auch nicht.
 
Immer bissel blöd wenn man zuhause ist und nicht mal geschwind reinschauen kann. In TIA hab ich das erst kürzlich gemacht. Dachte das handling in WinCCFlexible 2008 müsste da gleich sein. Kannste nicht da wo die Variablen deklariert sind, also in der allgemeinen Variablentabelle in der Zeile wo die Varable deklariert ist, einfach eine Hardwareadresse auswählen. Die Variable ist dann nicht mehr intern, das ist richtig.
 
Du deklarierst einfach deine Variable aus dem Global DB unter Variablen im WinCCflex.

Diese kannst du dann einfach im Script verwenden mit:

Code:
SmartTags("MEINE_GLOBALE_VARIABLE")

Grüße

Marcel

P.S: Der Name im WinCCflex zählt!
 
Argh...

Manchmal sieht man den Wald vor Bäumen nicht :roll:

Ich habe bei den Variablen Unterordner angelegt. In diesem Fall "Archivierung".

Also muss ich die Variable natürlich auch so angeben: "Archivierung\MeinDB.Meine_Variable". Der Compiler hat zu Recht gemeckert, dass ich nur "MeinDB.Meine_Variable" geschrieben habe.

Die Tastenkombination [Alt]+[Rechts] hat mir dabei geholfen meinen Fehler zu finden. Dann wird der Name inkl. Pfad nämlich korrekt angelegt.
Vielen Dank an alle!
 
Ich denke ich habe das verstanden, wie man Daten auf einem USB-Stick archivieren kann.
Jetzt kommt der nächste step.
Ich habe schon mal Meldearchive mit der Archivierungsfunktion -also ohne skript- auf den server des Kunden abgelegt.
Dabei konnte ich die Archive nicht unmittelbar auf dem Kundenserver ablegen. Die Archivierung wurde immer abgebrochen, wenn die Verbindung zum server "verlorenging". Die Archivierung erfolgt nun auf einem USB-Stick am Panel.
Ich habe das dann über den Aufgabenplaner so gelöst, dass die Archivierung stündlich gestoppt, auf den Server kopiert und wieder gestartet wird.
Das funktionierte dann wie gewünscht.

Ich denke ich brauche für die Skriptlösung des Variablenarchivs eine ähnliche Lösung.
Nach einigem Lesen erschien mir die Lösung aus der FAQ brauchbar.

http://www.sps-forum.de/hmi/41710-move-bzw-dateien-kopieren-2.html

Ich habe da noch ein paar Fragen:

1. Stimmt es, dass nicht kopiert/verschoben wird, wenn die Datei schon am Ziel vorhanden ist?
2. Falls überschrieben werden kann. Was geschieht, wenn die Zieldatei geöffnet ist?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
update:

Ich habe jetzt erstmal zum Reinkommen mit der PC_Runtime geübt. Dort habe ich den "copyfolder"-Befehl benutzt, um den gesamten Archivordner zu kopieren.
Das hat funktioniert. Die Dateien werden auch standardmäßig überschrieben, wenn kein entsprechender Parameter mitgegeben wird.
Für die WIN CE-Variante werde ich prüfen, ob es etwas ähnliches gibt.
 
Jetzt könnte ich noch etwas Hilfe gebrauchen.
Das komplette Szenario sieht jetzt wie folgt aus:

1. Auf einem USB-Stick werden Daten im Append-Modus in einer csv-Datei archiviert. Das klappt problemlos
2. Auf dem server des Kunden soll in einer festen Datei ebenfalls im Append-Modus archiviert werden.
Bei jedem neuen Eintrag soll geprüft werden, ob die Datei auf dem server aktualisiert werden kann.
Dies hängt von der Erreichbarkeit des servers und dem Vorhandensein einer "WriteAccess"-Datei ab.
Es ist also möglich, dass mehrere Einträge gesammelt werden, bevor geschrieben werden kann.

Wenn ich die Archivdatei immer nur kopiere, wird sie wohl irgendwann die Speicherkapazität des Sticks sprengen...

Also möchte ich die server-Datei nur aktualisieren und anschließend die Quelldatei auf dem Stick löschen.
Bei der Aktualisierung muss ich dafür dann wissen, wieviele Einträge ich aktualisieren muss.
Das geschieht aktuell über den Umweg, die Einträge der Quelldatei in ein Array zu kopieren. Das gefällt mir nicht so gut.
In der Zieldatei bleiben bei jeder Aktualisierung 2 Zeilen zwischen den Werten frei.

1. Gibt es einen eleganteren Weg für mein Vorhaben?
2. Wie bekomme ich die Leerzeilen weg?

Code:
Dim PathSearch, Path, Index, Result, fso, SourceFile, DestFile, f, fs, Header, StartTime, StopTime, DelayTime, i, Zeile(10000)

Set PathSearch = CreateObject("FileCtl.FileSystem")

'USB-Stick suchen
'--------------------

    Path = "Storage Card USB" 
    
    SetValue SmartTags("Status_kopieren"), 10                 'Text: Suche USB-Stick
    
    StartTime = Now
    DelayTime = 500        'Timer 100 endspricht 1sec.
    StopTime = StartTime + DelayTime / 24 / 360000
    Do
    If  PathSearch.Dir("\" & Path) = ""_
        And Now >= StopTime Then
        SetValue SmartTags("Status_kopieren"), 20            'Text: USB-Stick nicht gefunden!
        
        ElseIf PathSearch.Dir("\" & Path) = Path Then     
        SetValue SmartTags("Status_kopieren"), 30            'Text: Suche Zielordner
    End If
    Loop Until Now >= StopTime

'30: Ziellaufwerk suchen
'-----------------------

If SmartTags("Status_kopieren") = 30 Then
    Path = "\\LAPTOP_WO\Logs\"
    
    StartTime = Now
    DelayTime = 500        'Timer 100 endspricht 1sec.
    StopTime = StartTime + DelayTime / 24 / 360000
    Do                        
    Result = Ziel_pruefen (Path)
    If  Result = "Logs" Then
        SetValue SmartTags("Status_kopieren"), 50            'Text: Schreibfreigabe prüfen
    ElseIf Now >= StopTime Then    
        SetValue SmartTags("Status_kopieren"), 40            'Text: Zielordner nicht gefunden
    End If
    Loop Until Now >= StopTime
End If 


'50: Schreibfreigabe prüfen
'--------------------------

If SmartTags("Status_kopieren") = 50 Then
    Path = "\\LAPTOP_WO\Logs\WriteAccess.ok"
    
    StartTime = Now
    DelayTime = 500        'Timer 100 endspricht 1sec.
    StopTime = StartTime + DelayTime / 24 / 360000
    Do                        
    Result = Ziel_pruefen (Path)
    If  Result = "WriteAccess.ok" Then
        SetValue SmartTags("Status_kopieren"), 70            'Text: Zieldatei suchen
    ElseIf Now >= StopTime Then    
        SetValue SmartTags("Status_kopieren"), 60            'Text: keine Schreibfreigabe
    End If
    Loop Until Now >= StopTime
End If 

'70: Zieldatei abfragen
'---------------------

If SmartTags("Status_kopieren") = 70 Then
    
    Set f = CreateObject("FileCtl.File")
    Set fs = CreateObject("FileCtl.FileSystem")
    
    Path = "\\LAPTOP_WO\Logs\Data.csv"
    
    'Prüfen ob Ablagepfad vorhanden, wenn nicht -> erzeugen.
    Ordnerpfad_anlegen Path ' Übergabe des Ablagepfades aus dem Script "Script_Storage_Path" / Handing over of the storage path from the script "Script_Storage_Path"

    StartTime = Now
    DelayTime = 1000        'Timer 100 endspricht 1sec.
    StopTime = StartTime + DelayTime / 24 / 360000
    Do                        
    Result = Ziel_pruefen (Path)
    If  Result = "Data.csv" Then
        SetValue SmartTags("Status_kopieren"), 90            'Text: Einträge kopieren
    ElseIf Now >= StopTime Then    
        SetValue SmartTags("Status_kopieren"), 80            'Text: Datei nicht gefunden
    End If
    Loop Until Now >= StopTime
End If 

' Datei öffnen bzw. erstellen, wenn sie noch nicht existiert
' Open File or create file if it does not exist 
 f.open Path, 8                                 

' Tabellenkopf zusammenstellen 
' Create table header 
 Header = "Storage time;Barcode;Wert" &  Chr(10)
 
' Wenn Datei 0 Byte groß, dann ist sie neu
' If file is 0 byte the file is new
 If fs.FileLen(Path) = 0 Then                      
   f.lineprint(Header)
' =0 => Tabellenkopf muss eingefügt werden
 End If 
 ' Datei wieder schließen
     f.Close
     
'90: letzten Eintrag suchen
'--------------------------

If SmartTags("Status_kopieren") = 90 Then
    
    Set fso = CreateObject("FileCtl.FileSystem")
    
    SmartTags("Name") = fso.Dir("\Storage Card USB\*.csv")        'Suchen nach ersten Dateiname auf Stick
    f.open("\Storage Card USB\" & SmartTags("Name")),1,1
    
    For i = 1 To 10000
    If f.EOF = True Then Exit For
    Zeile(i) = f.LineInputString
    SmartTags("tmpZeile") = Zeile(i)
    Next
    ' Datei wieder schließen
     f.Close
     SetValue SmartTags("Status_kopieren"), 100
End If 


'100: Einträge im Appendmodus anhängen
'-------------------------------------

If SmartTags("Status_kopieren") = 100 Then
    
' FileObject erstellen
' Create FileObject
 Set f = CreateObject("FileCtl.File")
 
' Datei öffnen im Append-Modus
 f.open "\\LAPTOP_WO\Logs\Data.csv", 8 
 
For i = 1 To 10000
    f.lineprint Zeile(i+1)
    If Zeile(i) = SmartTags("tmpZeile") Then Exit For
    Next
    ' Datei wieder schließen
     f.Close 

 SetValue SmartTags("Status_kopieren"), 110
End If
    
'110: Quelldatei löschen
'-----------------------

If SmartTags("Status_kopieren") = 110 Then
     fs.Kill ("\Storage Card USB\" & SmartTags("Name"))
     SetValue SmartTags("Status_kopieren"), 200
End If
' Verwendeten Speicher wieder freigeben

Set f  = Nothing
Set fs = Nothing
Set fso = Nothing
Set PathSearch = Nothing
 
Zuletzt bearbeitet:
Hallo Tigerente,

zuerst eine Frage: wie sieht der Inhalt deiner Quelldatei genau aus?

Und eine zweite Frage: Verwendest du die Anzahl der hinzuzufügenden Zeilen irgendwie weiter?


Denn die Zeilenumbrüche könntest du schon beim Einlesen der Quelldatei dem zu kopierenden Dateiinhalt hinzufügen:

#######################################################
'90: letzten Eintrag suchen
'--------------------------
....
Statt
Zeile(i) = f.LineInputString
Verwende
fileContent = fileContent & f.LineInputString & vbCrLf
....
#######################################################

Beim Anfügen der neuen Zeilen reicht dann:

#######################################################
'100: Einträge im Appendmodus anhängen
'-------------------------------------
....
Statt
For i = 1 To 10000
f.lineprint Zeile(i+1)
If Zeile(i) = SmartTags("tmpZeile") Then Exit For
Next
Verwende
f.lineprint fileContent
....
End If
#######################################################


Gruß, Fred
 
Hallo faust,

der Vorschlag hat mich auf jeden Fall weitergebracht. In der bisherigen Version musste ich ein Array deklarieren und war nicht sicher, ob die Anzahl der Felder im Zweifelsfall reicht.
Der Code sieht jetzt wie folgt aus.

90:
Code:
For i = 1 To 10000
	If f.EOF = True Then Exit For
	fileContent = fileContent & f.LineInputString & vbCrLf
	SmartTags("Laenge") = i
	Next

100:
Code:
 f.open "\\LAPTOP_CHRIS_WO\Logs\NVE.csv", 8 

 f.lineprint fileContent

Damit der Header der Quelldatei nicht jedesmal in die Zieldatei kopiert wird, habe ich das Erzeugen des Headers in der Quelldatei entfernt.
In der "neuen" Version bleibt eine Zeile bei jeder Aktualisierung frei.
Siehe Anhänge.
csv.jpgQuelle.jpg
 
Hallo Tigerente,

die Leerzeile erklärt sich dadurch, dass mit dem Befehl 'f.linePrint' automatisch ein Zeilenumbruch eingefügt wird. Da dein Quell-Dateiinhalt (temporär gespeichert in der Variable 'fileContent') am Ende ebenfalls einen Zeileumbruch enthält...

Du musst also beim Einlesen der Quelldatei den letzten Zeilenumbruch mit Hilfe des Befehls 'Left(fileContent, (Len(fileContent) - 2)) abschneiden.


Gruß, Fred
 
Hallo Fred.

Super!!! Jetzt klappt es :D

Danke dafür.

Der Compiler hat allerdings den Code so nicht akzeptiert.
Ich musste das dann so schreiben:

Code:
For i = 1 To 1000000
		If f.EOF = True Then Exit For
			fileContent = fileContent & f.LineInputString & vbCrLf
			'Leerzeile am Ende löschen
			Laenge = Len (fileContent - 2)
 			fileContent = Left(fileContent,Laenge)
	Next

Vielleicht noch eine letzte Frage.
Ich lasse meine Schleife jetzt bis 1000000 laufen. Das wird sicher reichen. Ist aber auch nicht ganz sauber ausprogrammiert.
Gibt es eine Möglichkeit, das sauber zu programmieren?
Ach ja. Warum muss ich eigentlich "2" abziehen, um die Leerzeile zu löschen?
 
Zurück
Oben