WinCC VB-Skript: Archive suchen, Statusauswerten und kopieren - Problem

SPS-EK

Level-1
Beiträge
68
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo liebe Member,

kaum mit VB-Skript programmieren angefange, schon das nächste Problem. :confused:
Es geht darum, dass ich auf ein Stick über den USB Port die Archive der Runtime kopieren möchte, nur leider klappt das nicht.
Ich frage zu erst ab ob der Stick eingesteckt ist und das funktioniert auch, denn den Ordner in den die Archive sollen wird gefunden oder erstellt.

Bei folgenden Code werden die Archive nicht kopiert, obwohl die Archivierung gestoppt und die Archive geschlossen werden:
Code:
If usb_store_found And usb_folder_found Then
    'Create object for filehandling 
    Set fs_store = CreateObject("FileCtl.FileSystem")
    
    result = fs_store.Dir("\" & store_path & "\" & store_folder & "\" & "*values*" & "." & store_f_end)
    
    'Archive stoppen und schliessen 
    If result = "" Then
        ShowSystemAlarm("Kein Archiv ''values''" & " gefunden!")
    Else
        For index_archive = 0 To 100        '1
            result = fs_store.Dir()
            If result = "" Then
                Exit For
            Else
                StopLogging hmiDataLog, "values-XYZ"
                CloseAllLogs               
                Exit For
            End If
        Next
    End If
    Set fs_store = Nothing    

    'Archive suchen und kopieren ------------------------------------------------------------------------
    result = fs_store.Dir("\" & store_path & "\" & store_folder & "\" & "*values*" & "." & store_f_end)
    
    If result = "" Then
        ShowSystemAlarm("Keine Dateien vorhanden!")
    Else
        ShowSystemAlarm("Datenübertragung auf USB-Speicher gestartet!")
        source_file = "\" & store_path & result
        target_file = "\\" & usb_path & "\" & usb_folder & "\" & result
        fs_store.FileCopy source_file, target_file
        fs_store.SetAttr  source_file, 0
        ShowSystemAlarm("Erstes Archiv ''" & result & "'' gefunden und kopiert!")
        For index = 1 To 100
            result = fs_store.Dir()
            If result = "" Then
                index = index - 1
                Exit For
            Else
                source_file = "\" & store_path & result
                target_file = "\" & usb_path & "\" & usb_folder & "\" & result
                fs_store.FileCopy source_file, target_file
                fs_store.SetAttr  source_file, 0
                            
                ShowSystemAlarm("Weiteres Archiv ''" & result & "'' gefunden und kopiert!")
            End If
        Next
        ShowSystemAlarm(index & " Dateien erfolgreich übertragen!")
    End If
    
    
    'Archive öffnen und starten -------------------------------------------------------------------------
    OpenAllLogs
    StartLogging hmiDataLog, "values-XYZ"
    ShowSystemAlarm("Alle Archive geöffnet und gestartet.")
    
End If

Weiß jemand, wie ich die Archive auswerten kann ob die von der Runtime geöffnet/geschlossen sind bzw. ob die Runtime darauf zugreift?
Und sieht jemand den Fehler in meinem geposteten Code oder weiß Rat/Tipps?

Grüße SPS-EK
 
Guten Morgen SPS-EK,

hast Du im Projekt eine Meldeanzeige und/oder ein Meldefenster, wo Du auch Meldungen der Meldeklasse "System" sehen kannst? Ich meine, bei dem Skript müssten Runtime-Error-Meldungen kommen, die Du wohl nicht siehst. Mache Dir mal eine entsprechende Meldeanzeige in ein Bild.

Ist das gepostete Skript im wesentlichen Dein original Skript oder hast Du zum hier posten vielleicht zu viel gekürzt? Einige Sachen machen so keinen Sinn.

Code:
    result = fs_store.Dir("\" & store_path & "\" & store_folder & "\" & "*values*" & "." & store_f_end)
    
    'Archive stoppen und schliessen 
    If result = "" Then
        ShowSystemAlarm("Kein Archiv ''values''" & " gefunden!")
    Else
        For index_archive = 0 To 100        '1
            result = fs_store.Dir()
            If result = "" Then
                Exit For
            Else
                StopLogging hmiDataLog, "values-XYZ"
                CloseAllLogs               
                Exit For
            End If
        Next
    End If
Die For-Schleife ist unnötig, weil sie auf jeden Fall im ersten Durchlauf verlassen wird. Außerdem ist da auch noch ein Fehler, daß die Archive nicht geschlossen werden, wenn nur genau 1 Archiv-Datei gefunden wird.
--> Den Code besser ändern zu:
Code:
    result = fs_store.Dir("\" & store_path & "\" & store_folder & "\" & "*values*" & "." & store_f_end)
    
    'Archive stoppen und schliessen 
    If result = "" Then
        ShowSystemAlarm("Kein Archiv ''values''" & " gefunden!")
    Else 'mindestens 1 Archivdatei gefunden
        StopLogging hmiDataLog, "values-XYZ"
        CloseAllLogs
    End If

Code:
    [COLOR="#FF0000"]Set fs_store = Nothing[/COLOR]

    'Archive suchen und kopieren ------------------------------------------------------------------------
    result = [COLOR="#FF0000"]fs_store.Dir[/COLOR]("\" & store_path & "\" & store_folder & "\" & "*values*" & "." & store_f_end)
Das "Set fs_store = Nothing" ist unnötig, und hier führt es dazu, daß danach keine Datei-Operationen mehr ausgeführt werden weil der Bezug zum FileSystem-Objekt verloren ist. Das "result = fs_store.Dir(..." muß einen Runtime-Error werfen, und wenn Du kein "On Error Resume Next" vorher in dem Skript drin hast, dann wird das Skript abgebrochen.
--> Das "Set fs_store = Nothing" also rauslöschen.

Mehrmaliges identisches Zusammenbasteln von Strings, z.B. Dateinamen, würde ich nicht machen. Da lege ich mir das Ergebnis der ersten Verkettung auf eine Variable und benutze diese bei den folgenden Verwendungen. Also anstatt
Code:
    result = fs_store.Dir("\" & store_path & "\" & store_folder & "\" & "*values*" & "." & store_f_end)

[...]
    'Archive suchen und kopieren ------------------------------------------------------------------------
    result = fs_store.Dir("\" & store_path & "\" & store_folder & "\" & "*values*" & "." & store_f_end)
--> besser:
Code:
    Archivfilename = "\" & store_path & "\" & store_folder & "\" & "*values*" & "." & store_f_end
    result = fs_store.Dir(Archivfilename)

[...]
    'Archive suchen und kopieren ------------------------------------------------------------------------
    result = fs_store.Dir(Archivfilename)

Den Code danach habe ich mir nicht so genau angesehen, doch auch hier fällt mir auf, daß die Anordnung des ersten Dir (mit Parameter) und der Folgeaufrufe (ohne Parameter) ungünstig gelöst ist, weil die Aktion da zweimal programmiert werden muß. Besser ist dieses Konstrukt:
Code:
file = fso.Dir("*.*")    [COLOR="#008000"]'ersten Dateiname holen[/COLOR]
Do While file <> ""      [COLOR="#008000"]'wenn mindestens 1 Datei gefunden[/COLOR]
    [COLOR="#008000"]'tue irgendwas ...[/COLOR]

    file = fso.Dir()     [COLOR="#008000"]'nächsten Dateiname holen[/COLOR]
Loop
z.B.
Dateinamen eines Verzeichnisses in ein Array einlesen
Dateien löschen, welche älter als 30 Tage sind

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Morgen SPS-EK,

hast Du im Projekt eine Meldeanzeige und/oder ein Meldefenster, wo Du auch Meldungen der Meldeklasse "System" sehen kannst? Ich meine, bei dem Skript müssten Runtime-Error-Meldungen kommen, die Du wohl nicht siehst. Mache Dir mal eine entsprechende Meldeanzeige in ein Bild.

Ist das gepostete Skript im wesentlichen Dein original Skript oder hast Du zum hier posten vielleicht zu viel gekürzt? Einige Sachen machen so keinen Sinn.

Hallo Harald, freut mich dich auch hier zu begrüßen. So schnell sieht bzw. schreibt man sich wieder :ROFLMAO:

Ja das habe ich, die Meldungen werden mir angezeigt. Das nutze ich auch zum testen zwischendurch. Weiter ebenfalls ja, ich habe den geposteten Code etwas gekürzt.

Die For-Schleife ist unnötig, weil sie auf jeden Fall im ersten Durchlauf verlassen wird. Außerdem ist da auch noch ein Fehler, daß die Archive nicht geschlossen werden, wenn nur genau 1 Archiv-Datei gefunden wird.
--> Den Code besser ändern zu:
Code:
    result = fs_store.Dir("\" & store_path & "\" &  store_folder & "\" & "*values*" & "." & store_f_end)
    
    'Archive stoppen und schliessen 
    If result = "" Then
        ShowSystemAlarm("Kein Archiv ''values''" & " gefunden!")
    Else 'mindestens 1 Archivdatei gefunden
        StopLogging hmiDataLog, "values-XYZ"
        CloseAllLogs
    End If


Das "Set fs_store = Nothing" ist unnötig, und hier führt es dazu, daß danach keine Datei-Operationen mehr ausgeführt werden weil der Bezug zum FileSystem-Objekt verloren ist. Das "result = fs_store.Dir(..." muß einen Runtime-Error werfen, und wenn Du kein "On Error Resume Next" vorher in dem Skript drin hast, dann wird das Skript abgebrochen.
--> Das "Set fs_store = Nothing" also rauslöschen.

Ah super, dass war definitiv ein übler Fehler und ein Runtime error kam auch, aber nur bei dem "Set fs_store = Nothing" bzw. dem folgenden Dir-Befehl. Ich habe kein Zugriff auf das Projekt von hier aus und überrlege gerade, wieso ich das überhaupt drin hatte. :rolleyes:
Wie sinnig ist es eigentlich die Funktion "On Error Resume Next" zu nutzen? Ich mein klar, man sollte es jetzt nicht überall rein machen aber gibt es Funtionen wo man es definitiv nutzen sollte?


Mehrmaliges identisches Zusammenbasteln von Strings, z.B. Dateinamen, würde ich nicht machen. Da lege ich mir das Ergebnis der ersten Verkettung auf eine Variable und benutze diese bei den folgenden Verwendungen. Also anstatt...
besser ändern zu...

Ja das hatte ich auch erst, allerdings nutze ich die zusammengebastelten Strings extra um an den Stellen im nachhinein ohne problem etwas verändern zur können und dies nur über Übergabeparameter oder direkt am Skriptanfang die Pfade, Ordner, usw. ändern muss und trotzdem flexibel bin oder ist das eher schlecht für das Skript bzw. können dadurch zusätzliche Probleme entstehen?

Den Code danach habe ich mir nicht so genau angesehen, doch auch hier fällt mir auf, daß die Anordnung des ersten Dir (mit Parameter) und der Folgeaufrufe (ohne Parameter) ungünstig gelöst ist, weil die Aktion da zweimal programmiert werden muß. Besser ist dieses Konstrukt:

Code:
file = fso.Dir("*.*")    [COLOR=#008000]'ersten Dateiname holen[/COLOR]
Do While file <> ""      [COLOR=#008000]'wenn mindestens 1 Datei gefunden[/COLOR]
    [COLOR=#008000]'tue irgendwas ...[/COLOR]

    file = fso.Dir()     [COLOR=#008000]'nächsten Dateiname holen[/COLOR]
Loop

Super Tipp, vielen Dank und das macht wirklich Sinn...manchmal ist es echt als würde man im Wald stehen und vor lauter Bäumen den Wald nicht sehen :confused: :D


Weisst du, ob es die Möglichkeit gibt die Archive auf "von Runtime geöffnet/geschlossen" abzufragen?
 
Wie sinnig ist es eigentlich die Funktion "On Error Resume Next" zu nutzen? Ich mein klar, man sollte es jetzt nicht überall rein machen aber gibt es Funtionen wo man es definitiv nutzen sollte?

Ja das hatte ich auch erst, allerdings nutze ich die zusammengebastelten Strings extra um an den Stellen im nachhinein ohne problem etwas verändern zur können und dies nur über Übergabeparameter oder direkt am Skriptanfang die Pfade, Ordner, usw. ändern muss und trotzdem flexibel bin oder ist das eher schlecht für das Skript bzw. können dadurch zusätzliche Probleme entstehen?

Weisst du, ob es die Möglichkeit gibt die Archive auf "von Runtime geöffnet/geschlossen" abzufragen?


Folgender Fall: Der Rückgabewert wird während dem laufenden Skript beschrieben, diesen veräbderlichen Wert möchte ich zurück geben zur Laufzeit? Geht das, wenn ja wie?


Kann mir bitte jemand die Fragen zum weiteren Verständnis beantworten?
 
Zurück
Oben