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:
- No execution trigger configured on the VBS action (the script is saved but no event, tag trigger, or cyclic schedule ever calls it), and
-
Object/variable misuse when re-passing
HMI Runtime Tagsobjects back into theHMIRuntime.Tags()factory instead of reading.Name/.Valuefrom 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 → Properties → Trigger 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 |
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:\Tempmust pre-exist;Scripting.FileSystemObject.CreateTextFiledoes 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
.CreateTextFileand returns E_ACCESSDENIED). - Tag prefix must exist; tags
PLC01/TI-2112.wvalandPLC01/TI-QDELAY.T01must 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
.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)
- In the WinCC Explorer, drill into the target picture (e.g.
NewPdl0.Pdl) and locate the action. Double-click to open the VBS editor. - Open Properties → Trigger. The rightmost icon in the icon bar (a clock with a green play arrow) opens the trigger dialog.
- Click Add, choose Standard cycle or Tag trigger.
- For a 1 Hz export, set the time base to
1 sand counter to1. For a 250 ms export, time base250 ms, counter1.
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. - Compile (Ctrl+F7) and press Activate. The action fires immediately after the first cycle elapses.
Method 2 — Tag Trigger (event-driven on tag change)
- In Trigger dialog, add an entry of type Tag.
- Pick the source tag (e.g.
PLC01/TI-2112.wval). - Choose trigger condition: On change, On rising edge (val > prev), or On falling edge (val < prev).
- Apply. The VBS executes the moment the trigger condition evaluates true.
Method 3 — Picture / Mouse / Keyboard Event
- Open the picture in Graphics Designer.
- Select the graphical object (button, I/O field, rectangle).
- Right-click → Properties → Events → e.g. Mouse → Click.
- Action: Direct connection / VBS action. Assign your
ExportExcelprocedure.
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%orC:\Windows\Tempis silently redirected per-user even for elevated services. UseC:\Temp,D:\WinCCExports\, or a UNC path like\\FILESVR\wincc$\csv\. -
Antivirus — Windows Defender Controlled Folder Access blocks
fso.CreateTextFileon protected directories such asDocuments\. -
Read-only tag — if
C:/Temp/FileAis a tag configured with read-only acquisition, the.Readworks, but if the tag is not subscribed you getQualityCode = 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
- Action saved with name — right-click in Graphics Designer tree, confirm Action has a red dot indicating unsaved or a green checkmark when compiled.
- Trigger tab non-empty — Properties → Trigger lists at least one entry.
- Script compiles — Ctrl+F7 in the VBS editor returns no errors. Errors are listed in Output window.
- Runtime active — the RT icon in the system tray is green, not grey.
-
Trace line appears — at top of action,
HMIRuntime.Tracewrites to*.LOGwithin one trigger cycle. -
CSV file exists — browse to
strFilenameand confirm the file timestamp updates per cycle. -
Headers correct — first line is
Tag;Value;Quality;Timestamp. - 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
.Readthereafter. - 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 callobjFile.Writeonce, not per-tagWriteLine. - 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:
-
HMIRuntime→HMIRuntimestill exists as the legacy compatibility entry, but new scripts should useTags("Tag1").Readon the unifiedTagobject. - 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.