Resolving WinCC V15.1 VBScript Archive File Copy Failures

David Krause11 min read
SiemensTroubleshootingWinCC
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Problem Overview

Engineers deploying WinCC V15.1 (part of the TIA Portal V15.1 release line) on Comfort Panels and PC-based Runtime Advanced frequently need to relocate segmented hmiDataLog archive files into a structured date-stamped folder hierarchy for long-term retention, regulatory traceability, or downstream MES ingestion. The expected behavior is straightforward: each minute the runtime flushes a 100-record archive CSV, and a VBScript routine should sweep every newly closed archive into a folder named after the current date (for example, 2020-07-11).

The actual behavior observed in the field breaks in three consistent ways:

  1. The script returns a runtime error (most commonly Object required or Bad file name or number) and aborts before any copy takes place.
  2. The script runs to completion but copies nothing because the log file is still open and locked by the Logging subsystem.
  3. The script runs but only the last file in the loop is copied, because the asynchronous nature of the internal archive dispatcher has not been accounted for.

All three symptoms trace back to the same set of constraints: archive files must be closed before they can be moved, the destination folder must exist, the path string must be properly concatenated (VBScript does not expand variables inside literal strings), and the copy loop must allow asynchronous system functions time to complete on PC Runtime.

Root Cause Analysis

The failure pattern shown in the source script (strDirectory = "C:\ & strDate &\") contains three independent defects that together prevent the copy from ever executing:

Defect Faulty Line Why It Fails Corrected Form
Broken string literal "C:\ & strDate &\" Opening quote is closed after C:; the variables are commented out as literal characters, producing path C:\ & strDate &\ which is invalid. "C:\" & strDate & "\"
Variable inside literal "ArchivePath *.*" VBScript treats ArchivePath as a literal token, not the variable holding the source path. fso.CopyFile cannot find a file literally named ArchivePath *.*. ArchivePath & "*.*" with variable outside the quotes
No folder existence check (missing) If C:\2020-07-11\ does not exist, CopyFile returns error 76 (Path not found). If Not fso.FolderExists(strDirectory) Then fso.CreateFolder(strDirectory)

Beneath these syntactic issues lies a deeper architectural constraint: WinCC Runtime holds an exclusive write handle on every active archive segment until CloseAllLogs (or the panel-specific equivalent) is called. Attempting fso.CopyFile against an open log produces error 70 (Permission denied) on PC Runtime and silently no-ops on Comfort Panels because the panel's file system API returns success but writes zero bytes.

WinCC V15.1 Archive System Functions Reference

The WinCC scripting runtime exposes the following log-management system functions in TIA Portal V15.1. They are documented in the WinCC V15.1 Scripting Reference and are usable both from VBScript procedures and C scripts:

System Function Scope Purpose Async on PC Runtime?
StartLogging Single log Begins acquisition on the named hmiDataLog. No (immediate)
StopLogging Single log Stops acquisition; flushes buffer; closes file handle. No (immediate)
CloseAllLogs All data and alarm logs Flushes and closes every active log for safe file access. Yes — allow ~500 ms
OpenAllLogs All data and alarm logs Re-opens every previously closed log. Yes — allow ~500 ms
ArchiveLogFile Single log, segmented export Copies a closed log segment into a target directory and optionally renames it. Yes — allow 1–2 s per segment
LogTag Trigger Inserts a logging marker at the current timestamp. No
Critical: The async flag is platform-dependent. On a Comfort Panel the file system call is synchronous; on PC Runtime Advanced (RT Advanced) and WinCC Runtime Professional it is queued through the logging dispatcher and may not complete before the next VBScript statement executes. This is why a one-shot copy at end-of-shift works on a Comfort Panel but a looped copy inside a scheduler event may drop files on RT Advanced.

Platform Differences: Comfort Panel vs PC Runtime

WinCC V15.1 behaves measurably differently across the two deployment targets that the source question is most likely to involve. Engineers must select their copy strategy accordingly:

Behavior Comfort Panel (WinCC Comfort/Advanced) PC Runtime Advanced (RT Advanced)
File system access path Internal Flash or SD card Windows file system (HDD/SSD/SMB)
Wildcard copy support Not natively available; loop through Folder.Files fso.CopyFile source, dest with wildcard works
Archive storage on SIMATIC SD Recommended; avoids flash wear N/A
Recommended copy mechanism Manual loop using Folder.Files enumerator + FileSystemObject.CopyFile per file Single ArchiveLogFile call inside a loop, or fso.CopyFile with wildcard
Async completion delay None (synchronous kernel) 500–2000 ms per operation
Error 70 (Permission denied) on locked file Silent no-op (writes 0 bytes) Raised as runtime error in VBScript
On a Comfort Panel, never run the archive on internal flash for long-term storage. Always set the archive storage location to the SD card path (/media/simatic/... on the Linux-based panel firmware shipped with V15.1) to avoid flash wear and to free space. Reference the WinCC V15.1 System Manual, section "Data Logging".

Solution Path 1: Corrected Wildcard Copy (PC Runtime Advanced)

This is the shortest working solution when the runtime is a PC and archives are closed. Use it inside a scheduled task or a tag-triggered event:

'------------------------------------------------------------
' WinCC V15.1 - PC Runtime Advanced
' Sweep closed hmiDataLog archives into a date-named folder
' Trigger: Scheduler event, once per minute, on the minute
'------------------------------------------------------------
Option Explicit

Dim fso, ArchivePath, strDate, strDirectory
Dim d, m, y

d = Day(Now)
m = Month(Now)
y = Year(Now)
If Len(CStr(m)) = 1 Then m = "0" & m
If Len(CStr(d)) = 1 Then d = "0" & d
strDate = y & "-" & m & "-" & d

Set fso = CreateObject("Scripting.FileSystemObject")

ArchivePath   = "C:\Storage_Data\"
strDirectory  = "C:\Storage_Data\" & strDate & "\"

' 1) Guarantee destination folder exists
If Not fso.FolderExists(strDirectory) Then
    fso.CreateFolder(strDirectory)
End If

' 2) Close every active log so the files are not locked
CloseAllLogs
HMIRuntime.Trace "ArchiveSweep: logs closed"

' 3) Allow the logging dispatcher to settle
Wait 1.0

' 4) Wildcard copy of all archive files (CSV / RDB)
fso.CopyFile ArchivePath & "*.*", strDirectory, True

HMIRuntime.Trace "ArchiveSweep: copy executed to " & strDirectory

' 5) Re-open logging
OpenAllLogs

Set fso = Nothing
End Sub

Key corrections versus the original script:

  • Path strings concatenate variables outside the literal quotes.
  • Single-digit months and days are zero-padded so folder names sort lexicographically.
  • Wait 1.0 bridges the async gap of CloseAllLogs on PC Runtime.
  • The third argument True to fso.CopyFile permits overwrite so a re-run never trips error 58.

Solution Path 2: ArchiveLogFile Loop (Recommended for Both Platforms)

The Siemens-blessed path is to call ArchiveLogFile rather than touching the file system directly. This delegates ownership to the logging subsystem, which guarantees a closed segment and consistent naming:

'------------------------------------------------------------
' WinCC V15.1 - Comfort Panel or PC Runtime
' Archive every active hmiDataLog into a date folder
'------------------------------------------------------------
Option Explicit

Dim strDate, strDirectory
Dim d, m, y, oLog, i

d = Day(Now)
m = Month(Now)
y = Year(Now)
If Len(CStr(m)) = 1 Then m = "0" & m
If Len(CStr(d)) = 1 Then d = "0" & d
strDate = y & "-" & m & "-" & d

' Panel: /media/simatic/SIMATIC HMI/DataLog
' PC:    C:\Storage_Data
strDirectory = SmartTags("ArchiveBasePath") & strDate

CloseAllLogs
Wait 1.0

' Enumerate every log and archive it individually
For i = 1 To 10
    On Error Resume Next
    ArchiveLogFile "Logging", "Archive_0" & i, strDirectory, 1
    If Err.Number <> 0 Then
        HMIRuntime.Trace "ArchiveLogFile failed for Archive_0" & i & ": " & Err.Description
        Err.Clear
    End If
    On Error Goto 0
    Wait 0.3
Next

OpenAllLogs
End Sub

The ArchiveLogFile signature is ArchiveLogFile LogType, LogName, Directory, Mode:

Parameter Meaning Allowed Values (V15.1)
LogType Subsystem owning the log "Logging" for data logs; "Alarm" for alarm logs
LogName Name as defined in the project tree String, e.g. "Archive_01"
Directory Target directory (created if missing) String, absolute path
Mode Behavior on existing file 0 = overwrite, 1 = rename with timestamp
Tip: Use Mode = 1 for daily sweep so that successive sweeps within the same day do not collide. The runtime appends _HHMMSS to the file name automatically.

Comfort Panel Enumeration Variant (No Wildcard Available)

On a Comfort Panel the VBScript runtime does not expose wildcard copy. Iterate the folder explicitly:

'------------------------------------------------------------
' Comfort Panel - manual file enumeration sweep
'------------------------------------------------------------
Option Explicit

Dim fso, fldr, file, strDate, strSrc, strDst
Dim d, m, y

d = Day(Now): m = Month(Now): y = Year(Now)
If Len(CStr(m)) = 1 Then m = "0" & m
If Len(CStr(d)) = 1 Then d = "0" & d
strDate = y & "-" & m & "-" & d

strSrc = "/media/simatic/SIMATIC HMI/DataLogs/"
strDst = "/media/simatic/Archives/" & strDate & "/"

Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FolderExists(strDst) Then fso.CreateFolder(strDst)

CloseAllLogs

Set fldr = fso.GetFolder(strSrc)
For Each file In fldr.Files
    If LCase(fso.GetExtensionName(file.Name)) = "csv" Then
        file.Copy strDst & file.Name, True
    End If
Next

OpenAllLogs
Set fldr = Nothing
Set fso = Nothing
End Sub

Deployment Procedure

  1. Open the TIA Portal V15.1 project containing the HMI device.
  2. In the project tree, navigate to HMI device → Scripts → VBScripts and create a new procedure (e.g. ArchiveSweep).
  3. Paste the appropriate solution above. Bind ArchiveBasePath to an internal tag if you need it runtime-configurable.
  4. Create a Scheduler event: HMI device → Schedulers. Configure a 1-minute periodic trigger aligned to the archive boundary. WinCC V15.1 only schedules on whole-minute boundaries; if your archive cycle is 60 s, set the trigger on every minute.
  5. Assign the procedure to the scheduler event with the On timer action.
  6. Compile and download to the target (panel or RT PC).
  7. Open the WinCC Runtime trace viewer (Start → SIMATIC → WinCC → Tools → Trace Viewer) to monitor HMIRuntime.Trace output.

Verification

After deployment, validate the sweep end-to-end with the following checks:

  1. Folder created: Confirm C:\Storage_Data\YYYY-MM-DD\ (or panel equivalent) exists within 60 s of first trigger.
  2. File count: After 10 minutes, the folder must contain at least 10 CSV files of identical structure to the live archive.
  3. File size: Each file should be ~3–10 kB given 100 records; zero-byte files indicate the copy ran while the log was still open.
  4. Logging continuity: The current archive in C:\Storage_Data\ must keep growing; the sweep must not have stopped acquisition.
  5. Trace lines: ArchiveSweep: logs closed and ArchiveSweep: copy executed to ... must appear once per minute with no error codes.

Troubleshooting Matrix

Symptom Error Code Likely Cause Fix
Object required 424 fso never instantiated, or a variable was treated as a literal Ensure Set fso = CreateObject("Scripting.FileSystemObject") executed; fix string concatenation
Bad file name or number 52 Path string malformed (variable inside literal) Move variables outside quotes: "C:\" & strDate & "\"
Path not found 76 Destination folder missing Add FolderExists / CreateFolder guard
Permission denied 70 Copy attempted while log still open Insert CloseAllLogs + Wait 1.0 before copy
Only last file copied (none) ArchiveLogFile dispatched asynchronously; loop iterated too fast Insert Wait 1.0 inside loop body
Zero-byte files on Comfort Panel (none) Wildcard copy on locked file silently no-ops Switch to manual enumeration loop with Folder.Files
Script never fires (none) Scheduler disabled or wrong trigger type Verify Schedulers → Trigger → On timer enabled, runtime >= V15.1
Runtime aborts during compile (none) Option Explicit missing; undeclared variable Add Option Explicit at top of script

Best Practices and Field Notes

  • Always use Option Explicit. TIA Portal V15.1 silently coerces undeclared VBScript variables; the compiler will not catch typos such as ArchivPath.
  • Pad months and days with leading zeros so directory listing sorts chronologically.
  • Use HMIRuntime.Trace at every state transition. Trace lines are visible in the runtime diagnostic view and are invaluable for proving the script actually ran.
  • Mind the wait budget. Total script time = CloseAllLogs + copy + OpenAllLogs. With a 1-minute archive cycle, allow no more than 30 s of script execution to avoid overlapping the next boundary.
  • Do not archive to internal flash on Comfort Panels; redirect to SD card path /media/simatic/... via the project's Storage locations configuration.
  • If using WinCC Professional rather than Comfort/Advanced, the equivalent system functions live in the WinCC Professional runtime API and the C / VBS interfaces differ; consult the WinCC V15.1 Professional system documentation before porting code.
  • For SD card redundancy on a Comfort Panel, configure two storage locations and alternate; see the Siemens Knowledge Base article Archiving on SIMATIC HMI Panels linked from the WinCC V15.1 manual's "Archiving" chapter.

Why does my VBScript report "Bad file name or number" error 52?

The error means a path string contains a variable name treated as literal text. In VBScript you cannot expand variables inside a quoted string. Concatenate instead: "C:\Storage_Data\" & strDate & "\". The original script's "C:\ & strDate &\" closes the literal at C:, leaving the variables as plain characters and producing an invalid path.

Should I use CloseAllLogs or StopLogging inside the sweep routine?

For a full sweep of all logs use CloseAllLogs + OpenAllLogs for symmetry. If you operate on a single known log, StopLogging "Logging", "Archive_01" followed later by StartLogging is sufficient and avoids disturbing other active acquisitions. On PC Runtime always allow at least 1 second of Wait between the close and the file-system operation.

What is the difference between fso.CopyFile and ArchiveLogFile?

fso.CopyFile is a generic Windows file system call that requires the source file to be closed. ArchiveLogFile is a WinCC system function that signals the logging subsystem to flush and copy a segment, with built-in options for renaming and overwriting. Use ArchiveLogFile when possible because it cooperates with the logging dispatcher and avoids permission errors on PC Runtime.

Why does only the last archive file appear in my date folder?

This is the async dispatcher signature: each ArchiveLogFile call is queued, and the VBScript loop returns control to the runtime before the queue drains. Insert a 1–2 second Wait inside the loop after every call. Alternatively, schedule the procedure less frequently (e.g. once per hour) so the loop iterates one file at a time with natural gaps.

Can I copy directly from internal flash on a Comfort Panel?

You can, but it is not recommended for long-term or high-frequency archives because flash memory has a finite write cycle. Configure the archive storage location in TIA Portal under HMI device → Logs → Storage locations to point at /media/simatic/SIMATIC HMI/ on the SD card, and verify the SD card has at least 2 GB free space. Refer to the WinCC V15.1 manual section "Configuring archive storage locations" for the exact path on your firmware revision.

Back to blog