WinCC VBScript Export to Excel: Triggering Cyclic Actions Fix

David Krause10 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 Description

When a VBScript action is written in the WinCC Graphics Designer or WinCC Professional to export tag values to a text or CSV file (for downstream Excel consumption), the action executes nothing: no file is created on disk, no entries appear in the WinCC diagnostic trace (HMIRuntime.Trace never fires), and the RT (Runtime) project continues to run as if the script was never scheduled. The two root causes are nearly always:

  1. No execution trigger configured on the VBS action (the script is saved but no event, tag trigger, or cyclic schedule ever calls it), and
  2. Object/variable misuse when re-passing HMI Runtime Tags objects back into the HMIRuntime.Tags() factory instead of reading .Name / .Value from the cached references.

The original script posted by the user contains a re-entry bug that throws runtime error 438 ("Object doesn't support this property or method") the first time the loop iterates, which silently aborts the action before fso.CreateTextFile can be reached. The corrected version, plus the action-trigger setup, is detailed below.

Root Cause Analysis

Symptom Likely Root Cause Diagnostic Check
Action never executes; no file, no trace No trigger (cyclic, tag change, or picture event) configured Open Graphics Designer → right-click action → PropertiesTrigger tab
Runtime error 438 in WinCC diagnostic file *.log Tag object passed back into HMIRuntime.Tags() instead of .Name being used View ApDiag.txt for the script line number
Permission denied on C:\Temp\FileA.txt Runtime user lacks write permission, or folder does not exist Grant Authenticated Users Modify on the target path
Empty file written Tags not read (.Read not invoked) before .Value is read Call objTag.Read and confirm .QualityCode = 0
Excel shows #NV / #WERT! rows Excel treats ; as native list separator when regional setting is German; CSV not RFC-4180 compliant Save with ;\n or use Data → From Text/CSV wizard
Critical: In VBScript, the WinCC internal array stored Tag objects (variant-typed because Dim does not enforce type). Passing the object itself back to HMIRuntime.Tags(<tagobject>) triggers "Type mismatch" because the API expects a BSTR name. Always dereference .Name or call .Read on the cached reference.

Scripting Environment Prerequisites

  • WinCC V7.4 SP1 / V7.5 / V7.6 or WinCC Professional V16 / V17 / V18 Runtime license with VBScript option enabled.
  • Local or domain user account running the WinCC RT service that has Modify rights on the export folder (default C:\Temp must pre-exist; Scripting.FileSystemObject.CreateTextFile does not auto-create parent directories).
  • Target folder must be excluded from real-time virus scanning on the RT node (Windows Defender or third-party AV intercepts .CreateTextFile and returns E_ACCESSDENIED).
  • Tag prefix must exist; tags PLC01/TI-2112.wval and PLC01/TI-QDELAY.T01 must be reachable from the RT via the configured channel (PROFIBUS, PROFINET, OPC UA, or SIMATIC S7-Put/Get).

Corrected VBScript Reference

The script below fixes all four defects: it separates the tag-reference object from the textual name, removes the redundant HMIRuntime.Tags() re-entry, performs an explicit .Read on every tag prior to logging, and uses a unique trace prefix so the diagnostic file can be filtered.

'============================================================
' WinCC VBS148 - Export selected tags to CSV (Excel compatible)
' Tested on WinCC V7.5 SP2 + RT 1024 tags
'============================================================
Option Explicit   ' Comment out if using legacy code that relies
                  ' on implicit variants and you cannot fix it.

Dim strFilename
Dim objFSO, objFile
Dim objFileNameTag
Dim objTag
Dim i

' -- 1) Resolve the output path from a WinCC internal tag --
Set objFileNameTag = HMIRuntime.Tags("C:/Temp/FileA")   ' Tag with .csv suffix is fine
objFileNameTag.Read
If (objFileNameTag.Value = "") Then
  HMIRuntime.Trace "VBS148: Filename tag empty, aborting" & vbCrLf
  Exit Sub
End If
strFilename = CStr(objFileNameTag.Value)

' -- 2) Prepare the file (overwrite) --
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile(strFilename, True, True)  ' overwrite, Unicode

objFile.WriteLine "Tag;Value;Quality;Timestamp"

HMIRuntime.Trace "VBS148: Writing file " & strFilename & vbCrLf

' -- 3) Bulk read of the four process tags --
HMIRuntime.Tags("PLC01/TI-2112.wval").Read
HMIRuntime.Tags("PLC01/TI-QDELAY.T01").Read
HMIRuntime.Tags("PLC01/TI-QDELAY.T02").Read
HMIRuntime.Tags("PLC01/TI-QDELAY.T03").Read
HMIRuntime.Tags("PLC01/TI-QDELAY.T04").Read

' -- 4) Dump values --
Dim aTags
aTags = Array( _
  HMIRuntime.Tags("PLC01/TI-2112.wval"), _
  HMIRuntime.Tags("PLC01/TI-QDELAY.T01"), _
  HMIRuntime.Tags("PLC01/TI-QDELAY.T02"), _
  HMIRuntime.Tags("PLC01/TI-QDELAY.T03"), _
  HMIRuntime.Tags("PLC01/TI-QDELAY.T04") )

For i = 0 To UBound(aTags)
  Set objTag = aTags(i)
  objFile.WriteLine objTag.Name & ";" & _
                    CStr(objTag.Value) & ";" & _
                    CStr(objTag.QualityCode) & ";" & _
                    CStr(Year(Now)) & "-" & _
                    Right("0" & Month(Now),2) & "-" & _
                    Right("0" & Day(Now),2) & " " & _
                    Right("0" & Hour(Now),2) & ":" & _
                    Right("0" & Minute(Now),2) & ":" & _
                    Right("0" & Second(Now),2)
  HMIRuntime.Trace "VBS148: " & objTag.Name & "=" & _
                   objTag.Value & " Q=" & objTag.QualityCode & vbCrLf
Next

objFile.Close
Set objFile = Nothing
Set objFSO = Nothing
Why .Read on every tag? The WinCC RT cache is per-process. Reading in bulk before the loop guarantees that the snapshot is internally consistent — if you read inside the loop, each tag is fetched at a different scheduler tick and the row set can describe different process states. This is documented in the Siemens FAQ — WinCC VBS: Access to Tag values.

Triggering the VBS Action

An action in WinCC is inert until at least one trigger is configured. There are three supported trigger types, each selectable in the action's Properties → Trigger tab:

Method 1 — Cyclic Trigger (most common for periodic CSV export)

  1. In the WinCC Explorer, drill into the target picture (e.g. NewPdl0.Pdl) and locate the action. Double-click to open the VBS editor.
  2. Open Properties → Trigger. The rightmost icon in the icon bar (a clock with a green play arrow) opens the trigger dialog.
  3. Click Add, choose Standard cycle or Tag trigger.
  4. For a 1 Hz export, set the time base to 1 s and counter to 1. For a 250 ms export, time base 250 ms, counter 1.
    Available time bases: 250 ms, 500 ms, 1 s, 2 s, 5 s, 10 s, 1 min, 5 min, 10 min, 1 h — same as for C actions.
  5. Compile (Ctrl+F7) and press Activate. The action fires immediately after the first cycle elapses.

Method 2 — Tag Trigger (event-driven on tag change)

  1. In Trigger dialog, add an entry of type Tag.
  2. Pick the source tag (e.g. PLC01/TI-2112.wval).
  3. Choose trigger condition: On change, On rising edge (val > prev), or On falling edge (val < prev).
  4. Apply. The VBS executes the moment the trigger condition evaluates true.

Method 3 — Picture / Mouse / Keyboard Event

  1. Open the picture in Graphics Designer.
  2. Select the graphical object (button, I/O field, rectangle).
  3. Right-click → Properties → Events → e.g. Mouse → Click.
  4. Action: Direct connection / VBS action. Assign your ExportExcel procedure.
Quick visibility test: If Runtime is already running, simply switch to a different picture and back. Scripts triggered by picture-open events fire on navigation. This is the fastest way to confirm a script is being scheduled at all.

Verifying the Trigger Without Real Hardware

To isolate "script never runs" from "script runs but fails", add a globally visible side effect at the very top of the action:

HMIRuntime.Trace "VBS148 ENTER @ " & Now & vbCrLf

Then open the WinCC RT diagnostic viewer (Start → Programs → Siemens Automation → WinCC → Tools → WinCC Tag Logging / APDiag) or check <ProjectPath>\<ComputerName>\<ProjectName>.LOG. If the line appears, the trigger is wired correctly and you can move on to the tag-name and file-permission issues. If the line does not appear, the action is not being scheduled — re-open the trigger dialog and confirm.

Permissions and Security Context

WinCC Runtime launches child scripts under the user account that started the WinCC RT service (typically CCAdminWinSysUser or a configured service account). Common permission pitfalls:

  • UAC virtual folders — writing into %ProgramFiles% or C:\Windows\Temp is silently redirected per-user even for elevated services. Use C:\Temp, D:\WinCCExports\, or a UNC path like \\FILESVR\wincc$\csv\.
  • Antivirus — Windows Defender Controlled Folder Access blocks fso.CreateTextFile on protected directories such as Documents\.
  • Read-only tag — if C:/Temp/FileA is a tag configured with read-only acquisition, the .Read works, but if the tag is not subscribed you get QualityCode = 0xC0 (BAD — No Communication). See Siemens FAQ 109751529 for the full quality-code table.

Common Quality Codes (Quick Reference)

QualityCode (hex) Meaning Action
0x00 Good — value valid Use value as-is
0x40 Uncertain — substituted Flag row in CSV (UNCERTAIN)
0x60 Bad — sensor failure Do not export; raise alarm
0x80 Bad — last usable value Export with caution flag
0xC0 Bad — no communication Check PLC connection / tag rights
0x00 with Value empty PLC tag exists but has not been written Configure initial value at tag level

Verification Checklist

  1. Action saved with name — right-click in Graphics Designer tree, confirm Action has a red dot indicating unsaved or a green checkmark when compiled.
  2. Trigger tab non-emptyProperties → Trigger lists at least one entry.
  3. Script compiles — Ctrl+F7 in the VBS editor returns no errors. Errors are listed in Output window.
  4. Runtime active — the RT icon in the system tray is green, not grey.
  5. Trace line appears — at top of action, HMIRuntime.Trace writes to *.LOG within one trigger cycle.
  6. CSV file exists — browse to strFilename and confirm the file timestamp updates per cycle.
  7. Headers correct — first line is Tag;Value;Quality;Timestamp.
  8. Excel import works — open Excel → Data → From Text/CSV → Delimiter = Semicolon. If column splitting fails on German locales, choose Delimited → Semicolon explicitly in the wizard.

Performance and Scaling Notes

Each HMIRuntime.Tags("...") call performs a name lookup against the tag database. In a 1 Hz export with 50 tags this adds ~50 ms per cycle on a mid-range RT PC — well inside budget, but for high-frequency exports follow these practices:

  • Hoist tag references into module-level variables on first call; reuse via .Read thereafter.
  • For exports over 1 kHz or with >200 tags, switch to a C action or to WinCC Connectivity Pack / OLE-DB which exposes the same tag data via SQL without VBS overhead.
  • Buffer writes: build a single string with vbCrLf-separated rows and call objFile.Write once, not per-tag WriteLine.
  • Close and re-open the file on a longer cycle (e.g. hourly) to minimise lock contention with antivirus and Excel.

Alternative: Direct OLE-DB / OPC UA Export

When the export volume exceeds a few thousand rows or needs to run decoupled from the picture, the Siemens-recommended path is to query the WinCC archive (or the live tag cache) through OLE-DB or OPC UA. Connection strings for a local WinCC project:

' WinCC V7 OLE-DB example
Const strConn = "Provider=WinCCOLEDBProvider.1;" & _
                "Catalog=WinCC_CC_<ProjectName>_<RT>;" & _
                "Data Source=.<ServerName>"
Dim oConn, oRS
Set oConn  = CreateObject("ADODB.Connection")
oConn.Open strConn
Set oRS    = oConn.Execute("SELECT Tag,Value,TimeStamp FROM PView" )

For WinCC Professional (TIA Portal) the equivalent path is WinCC Runtime/Server OPC UA.

Migration to WinCC Unified (TIA Portal V17/V18)

VBS remains supported in WinCC Unified through the Scripts editor, but the API surface changed:

  • HMIRuntimeHMIRuntime still exists as the legacy compatibility entry, but new scripts should use Tags("Tag1").Read on the unified Tag object.
  • Triggers are configured per script in the Trigger attribute of the Scheduled task.
  • Cyclic export via picture events is no longer needed; a global Scheduled task is preferred.

Why does my VBS action never run even though I saved and compiled it?

WinCC only invokes actions that have at least one trigger configured in Properties → Trigger. Open the action, click the clock-icon in the toolbar, add a standard cycle (e.g. 1 s), recompile, and re-activate Runtime. A saved but un-triggered action is dormant.

Runtime error 438 "Object doesn't support this property or method" at HMIRuntime.Tags(<tagobject>).

You stored the tag objects inside arrTags and then passed that array element back to HMIRuntime.Tags(). The factory expects a BSTR name, not a tag object. Either call arrTags(i).Read and use arrTags(i).Value, or rebuild the array with string names and re-fetch via HMIRuntime.Tags(arrTags(i)) only when needed.

The script runs (trace line shows) but no file is written.

Either the path is invalid (C:\Temp does not exist) or the runtime user lacks Modify rights. Test by hard-coding strFilename = "C:\Temp\FileA.txt", manually creating the folder, and reloading Runtime. If the hard-coded path works, the issue is the tag holding the path; if not, it is NTFS permissions or antivirus.

How do I get the current value of a tag including its quality in VBS?

Call objTag.Read, then read objTag.Value, objTag.QualityCode, and objTag.Timestamp (WinCC V7.5 and later). Writing all three into your CSV makes Excel dashboards aware of bad data, which is required by IEC 62443 visualisation recommendations.

Can I write to Excel directly instead of CSV?

Yes — instantiate Excel.Application via CreateObject("Excel.Application"), open a workbook, and Worksheet.Cells(row,col).Value = tagValue. This is slower and requires Excel installed on the RT node, which contradicts the WinCC hardening guide; the recommended pattern is CSV + scheduled Excel macro for post-processing.

Back to blog