Resolving WinCC VBScript Compile Errors When Migrating from VBA
WinCC engineers who copy script snippets from forum threads, knowledge bases, or legacy projects frequently hit a hard wall when they paste a Visual Basic for Applications (VBA) sample into a WinCC runtime script and try to compile. The compiler rejects code that uses explicit type declarations such as Dim temp As Integer, references to design-time-only objects like ThisDocument, or loops over HMIObjects collections that only exist in the Graphics Designer environment. This article documents the root cause, lists the language-level differences, and provides a field-proven conversion workflow that keeps both the original VBA logic and a fully functional VBScript replacement side by side.
1. Problem Description: Symptoms in the WinCC Script Editor
When you paste VBA-style code into a WinCC VBScript action, picture event, or faceplate property, the editor raises one of the following compile errors immediately:
| Symptom | Editor Behavior | Typical Cause |
|---|---|---|
Syntax error after Dim
|
Red underline on the line; status bar: Expected statement |
As Integer, As String, As Boolean after a variable name |
| Object not defined: ThisDocument | Compile stops, error 424 Object required | VBA design-time object used in runtime script |
| Unknown class: HMIObject / HMIProperty | Compile error: Variable not defined | Graphics Designer automation model not available in runtime |
| Implicit type warnings (WinCC V7.5+) | Yellow triangle in editor margin | Use of Variant where a strongly typed variable would be safer |
| Runtime log entry: Action fault | WinCC Alarm Control: Status of actions: fault | Compile-time issue not surfaced until first scheduled execution |
' VBA sample - Graphics Designer only - WILL NOT compile in VBS runtime
Sub Read_HMIObject_Dynamics()
Dim Our_Object As HMIObject
Dim Each_Property As HMIProperty
For Each Our_Object In ThisDocument.HMIObjects
Debug.Print String(6, "=") & Our_Object.ObjectName & String(6, "=") & vbTab & Chr(34) & Our_Object.Type & Chr(34) & vbCrLf
For Each Each_Property In Our_Object.Properties
If Not IsEmpty(Each_Property.value) Then
If Each_Property.IsDynamicable Then
If Our_Object.Properties(Each_Property.Name).DynamicStateType = hmiDynamicStateTypeDynamicDialog Then
Debug.Print Each_Property.Name & vbTab & _
Our_Object.Properties(Each_Property.Name).DynamicStateType & vbCrLf & _
Our_Object.Properties(Each_Property.Name).Dynamic.SourceCode
End If
End If
End If
Next Each_Property
Next Our_Object
End Sub
The script attempts to enumerate every HMI object on a Graphics Designer picture, read each property's dynamization type, and print the embedded source of any Dynamic Dialog. That is a perfectly valid design-time VBA macro - it is not a runtime action, and it cannot be converted into one without rewriting from scratch.
2. Root Cause: VBA and VBScript Are Different Languages
WinCC exposes two distinct automation surfaces, and confusing them is the most common source of the symptoms above:
-
Graphics Designer VBA - A design-time COM automation interface used by WinCC Engineering to script the editor itself: create menus, bulk-place objects, read or write picture properties, inspect dynamization. Runs inside the WinCC Explorer / Graphics Designer process via
HMIGO.exeautomation. -
WinCC Runtime VBScript - A stripped-down VBScript 5.x engine embedded in
CCAlgRt.exe/CCEServer.exe(TIA Portal) that executes actions, picture events, scheduler tasks, and faceplate scripts against the live RT database.
The two environments do not share namespaces. HMIObject, HMIProperty, ThisDocument, Debug.Print, and explicit As Type clauses belong exclusively to the VBA design-time model. When you paste them into a runtime script the parser fails at the first unrecognized token.
C:\Program Files\Siemens\Automation\WinCC\Documents\VBA.pdf) for the design-time model. For the runtime VBS object model refer to WinCC VBS Reference (WinCC V7.x) and WinCC Professional - Scripting help (TIA Portal).
3. WinCC Scripting Environments Side-by-Side
| Aspect | Graphics Designer VBA | WinCC Runtime VBScript |
|---|---|---|
| Host process | HMIGO.exe / WinCC Explorer | CCAlgRt.exe / CCEServer.exe |
| Engine | VBA 7.x (Microsoft) | VBScript 5.8 (Windows Script Host) |
| Trigger | Manual or menu-driven macro | Tag trigger, cyclic schedule, event, property change |
| Object root |
ThisDocument (active picture) |
HMIRuntime (project root) |
| Object enumeration |
HMIObject, HMIProperty
|
ScreenItems, Screen, Tags
|
| Variable typing |
Dim x As Integer supported |
Untyped only: Dim x
|
| Debug output |
Debug.Print to Immediate window |
HMIRuntime.Trace to log file |
| Execution context | Design time, single-threaded | Runtime, single-threaded per action |
| Persistent state | Picture file .pdl
|
Process memory; lost on RT restart |
4. VBScript Language Limitations That Trip VBA Developers
WinCC runtime uses Microsoft's VBScript engine. The following VBA constructs are not available and must be rewritten before the editor will accept the script:
| VBA Construct | VBScript Equivalent | Notes |
|---|---|---|
Dim x As Integer |
Dim x |
All VBS variables are Variant
|
Const FOO As Long = 100 |
Const FOO = 100 |
No type qualifier allowed |
Function Bar(ByVal n As Long) As String |
Function Bar(n) : Bar = "" : End Function |
No parameter or return types |
Debug.Print x |
HMIRuntime.Trace "x=" & x & vbCrLf |
Trace writes to WinCC_Sys_<date>.log |
ThisDocument.HMIObjects |
HMIRuntime.Screens("Main").ScreenItems |
Use RT object model |
MsgBox "Done" |
Not available in runtime | Use HMIRuntime.ShowSystemPopup (limited) or alarm logging |
Set obj = CreateObject("...") |
Set obj = CreateObject("...") |
Works, but only against registered COM |
On Error Goto Label |
On Error Resume Next |
Structured error handling only |
Variant boxing costs CPU per access, hot-loop code that reads tags inside a For i = 1 To 10000 cycle is 5-15% faster when the tag value is cached in a local variable rather than calling HMIRuntime.Tags("...").Read each iteration.
5. WinCC VBS Runtime Object Model
The runtime object model is rooted at HMIRuntime and exposes the live project tree. The most-used members:
| Path | Purpose | Example |
|---|---|---|
HMIRuntime.Tags("TagName") |
Direct tag access (read/write/explicit) | HMIRuntime.Tags("Motor1_Speed").Read |
HMIRuntime.Screens("Main") |
Open or reference a picture window | HMIRuntime.Screens("Main").ScreenItems("Button_1").BackColor = RGB(0,255,0) |
HMIRuntime.Screens("Main").ScreenItems |
Collection of objects on a picture | Iterate with For Each
|
HMIRuntime.ActiveScreen |
Currently visible base picture | HMIRuntime.ActiveScreen.ScreenName |
HMIRuntime.DataSet |
Archive data set reference | Used in conjunction with .Read
|
HMIRuntime.Trace |
Write to diagnostic log | HMIRuntime.Trace "Message" & vbCrLf |
HMIRuntime.ShowSystemPopup |
Native popup dialog (V7.4 SP1+) | HMIRuntime.ShowSystemPopup "Alarm", "Tag bad", 5 |
HMIRuntime.UI |
Top-level UI controls (V7.5+) | Lock / unlock operator input |
For TIA Portal WinCC Professional the API names are case-insensitive but follow the same hierarchy. HMIRuntime becomes the entry point of every C-/VBScript action.
6. Converting the Sample VBA Macro to a VBS Runtime Action
The original VBA macro tries to enumerate picture objects. In runtime you cannot enumerate an arbitrary picture's ScreenItems by reflective property access because each item exposes different attributes. The functional equivalent for a runtime diagnostic is to read the dynamization source through the tag value associated with the property instead of through the design-time Dynamic.SourceCode API. A safer pattern is below.
6.1 Read a tag bound to a property
' WinCC VBS runtime - read a single tag bound to the property "Value" of object "MyField"
Sub Read_Field_Value()
Dim objScreen
Dim objItem
Dim sValue
Set objScreen = HMIRuntime.Screens("Main")
Set objItem = objScreen.ScreenItems("MyField")
sValue = objItem.OutputValue ' I/O field exposes OutputValue at runtime
HMIRuntime.Trace "Read_Field_Value: MyField = " & sValue & vbCrLf
End Sub
6.2 Enumerate objects with typed safe iteration
' WinCC VBS runtime - iterate ScreenItems and print Name + Type only
Sub List_ScreenItems()
Dim objItem
Dim iCount
iCount = 0
For Each objItem In HMIRuntime.Screens("Main").ScreenItems
HMIRuntime.Trace String(6, "=") & objItem.ObjectName & String(6, "=") & _
vbTab & Chr(34) & objItem.Type & Chr(34) & vbCrLf
iCount = iCount + 1
Next objItem
HMIRuntime.Trace "Total objects: " & iCount & vbCrLf
End Sub
The two snippets compile cleanly because every Dim lacks a type qualifier, HMIRuntime replaces ThisDocument, and the only property read (ObjectName, Type) is available on the runtime ScreenItem base interface.
6.3 Direct mechanical fixes (when conversion is overkill)
If the original VBA snippet only needs to be used as a debugging tool during engineering, do not paste it into runtime. Instead, install the macro inside Graphics Designer:
- Open WinCC Explorer -> Graphics Designer.
- Menu Tools -> Macros -> VBA Editor.
- Project tree -> right-click Project -> Insert -> Module.
- Paste the original
Sub Read_HMIObject_Dynamics()verbatim. - Press F5 to run. Output appears in the Immediate window.
This preserves As Integer, As HMIObject, Debug.Print, and ThisDocument exactly as written. Runtime and design-time macros are stored separately.
7. Step-by-Step Migration Workflow
Use this checklist when a project moves faceplates, standard pictures, or global scripts from ANSI-C to VBS, or when refactoring an old VBA macro into runtime behavior:
-
Inventory the scripts. Open the project with WinCC Tag Simulator or the WinCC Project Migrator and list all
.pas(ANSI-C) and.bcl(VBS) files. Confirm whether faceplates are involved - faceplates in WinCC V7.x support VBS only, so any ANSI-C code on a faceplate must be ported. - Classify each script as runtime or design-time. Anything that needs to enumerate picture objects, batch-modify pictures, or read dynamization source is design-time VBA and stays in the VBA editor.
-
Strip type qualifiers. Run a search-and-replace on every
Dimstatement:As Integer,As Long,As String,As Boolean,As Object,As Variant,As Double,As Single. Replace with nothing. -
Replace design-time roots. Map
ThisDocument.HMIObjects->HMIRuntime.Screens("PictureName").ScreenItems; mapThisDocument.HMIObjsto the same. -
Replace Debug.Print.
Debug.Print->HMIRuntime.Trace <expression> & vbCrLf. Enable the diagnostic trace via WinCC Explorer -> Computer -> Properties -> Graphics Runtime -> Trace. -
Remove unsupported statements.
On Error Goto,Resume,Line Input,WithEvents, user-definedTypeblocks, andReDim Preserveacross object arrays are not supported. -
Wrap scripts in
Sub ... End Subif you want a free procedure. Action scripts do not requireSubbut procedures you call from an action do. - Compile with F7 in the editor. Resolve every error before deployment. The status bar must show Compile completed successfully.
- Validate by triggering the action manually (button click or scheduled 1 Hz cycle) and inspecting APLog.txt in the RT directory.
- Back up the working script. Store the original VBA macro under Project Documentation / VBA macros for traceability.
8. ANSI-C: When You Do Not Need VBS at All
If a script was already working in ANSI-C and the migration was triggered only by faceplate restrictions, evaluate whether VBS is required. ANSI-C remains fully supported in WinCC V7.x runtime for actions and scheduler tasks. It is only faceplates that limit scripting to VBS. For non-faceplate code, ANSI-C is often faster and gives you static typing.
| Criterion | ANSI-C | VBScript |
|---|---|---|
| Compile speed (per 1000 lines) | ~200 ms | ~80 ms |
| Runtime per access (tag read) | ~0.05 ms via GetTagFloat
|
~0.40 ms via HMIRuntime.Tags(...).Read
|
| Type safety | Strong (compile-time) | None (Variant) |
| Debugger | External (MSVC) | WinCC internal; trace-based |
| Faceplate support | No | Yes |
| External COM access | Limited | Full via CreateObject
|
The decision rule used in mature WinCC codebases: use VBS only where faceplate events demand it, and keep everything else in ANSI-C. Hybrid projects routinely mix both languages inside the same picture.
9. Common Compile Errors and Fix Matrix
| Error Code | Editor Message | Likely Cause | Fix |
|---|---|---|---|
| 800A0400 | Expected statement |
As Type after Dim
|
Remove qualifier |
| 800A0401 | Expected integer constant | Const X As Long = ... |
Const X = ... |
| 800A0411 | Name redefined | Duplicate Sub or variable name in same scope |
Rename or move out of scope |
| 800A03EE | Expected ')' | Comma vs. semicolon in MsgBox
|
Replace MsgBox with custom popup |
| 424 | Object required | Use of ThisDocument or HMIObject
|
Move to VBA or replace with HMIRuntime
|
| 429 | ActiveX component can't create object |
CreateObject("Word.Application") on a server without Office |
Remove dependency or install component |
| 507 | Exception occurred | Null reference inside loop | Guard with If Not objItem Is Nothing Then
|
10. Verification Procedure
After the rewrite, run a four-stage verification to confirm the script compiles, runs, and behaves correctly under load:
10.1 Compile check
Open the script in the WinCC Script Editor and press F7. Confirm the status bar reports Compile successful. If it shows line numbers, fix them one at a time, top-down.
10.2 Static call check
Right-click the script -> Check References. Resolve every not found entry by correcting tag names or picture names. Typo'd tag names produce a runtime read returning 0 silently.
10.3 Single-step runtime check
Attach the action to a button Click event. Press the button in RT. Inspect APLog.txt and the Diagnosis view of WinCC Explorer. Confirm expected HMIRuntime.Trace lines appear.
10.4 Cyclic load test
Schedule the script on a 100 ms cycle for ten minutes. Monitor CPU on the RT server. Healthy VBS actions consume less than 1% CPU per 1000 lines on a typical IPC. Anything above 5% indicates a missing tag cache or a runaway loop.
11. Field-Proven Caveats
-
VBA samples from old WinCC V6 forums still circulate. They were written for
WinCC Explorer VBA, not for runtime. Treat any snippet that containsThisDocumentas design-time only. -
Faceplate property scripts ignore VBA entirely. In WinCC V7.4 SP1 and later, faceplate properties support only VBScript expressions. If your migration story is "faceplate compile error", the answer is almost always a leftover
As Typeor a VBA object reference. -
Microsoft removed VBScript from default Windows 11 builds for security reasons. WinCC runtime ships its own
vbscript.dll, so this does not affect RT, but standalone scripts that callcscript.exeoutside the WinCC install will fail. UseHMIRuntime.Tracefor diagnostics instead. -
Implicit Variant conversion can hide bugs.
Dim a : a = "10" + 5evaluates to15, not105. Use explicitCStr/CLngwhen concatenating tag values into display strings. -
Long-running VBS blocks picture events. VBS actions are single-threaded against
CCAlgRt.exe. A 500 ms loop in a button-click event blocks every other event in the project. Offload toHMIRuntime.Scheduleror to a separate task.
12. Quick Reference Card
| If the code uses... | Put it in... | Because... |
|---|---|---|
ThisDocument.HMIObjects |
VBA macro in Graphics Designer | Design-time automation only |
Debug.Print |
VBA macro in Graphics Designer | Immediate window, not RT |
Dim x As Integer |
VBA macro | VBS rejects type qualifiers |
HMIRuntime.Tags(...).Read |
Runtime VBS action | Live tag access |
HMIRuntime.Screens(...).ScreenItems |
Runtime VBS action | Live picture objects |
GetTagFloat / SetTagFloat |
Runtime ANSI-C action | Fast native tag API |
faceplate property script |
Runtime VBS only | Faceplate restriction |
FAQ
Why does WinCC VBS reject "Dim x As Integer" while VBA accepts it?
VBScript is a scripting language with a single Variant type, while VBA is a full programming language with explicit typing. WinCC runtime uses the VBScript engine, so every Dim qualifier after the variable name produces compile error 800A0400. Use Dim x and let the engine coerce at runtime.
Can I run a VBA macro that enumerates HMIObjects during runtime?
No. ThisDocument, HMIObject, and HMIProperty exist only inside the Graphics Designer design-time automation surface. During runtime the active picture is reached via HMIRuntime.ActiveScreen and live objects via ScreenItems; their property set is a subset of the design-time API.
Do I have to migrate ANSI-C faceplate scripts to VBS?
Only if the script is used inside a faceplate. Faceplate property and event scripts in WinCC V7.x support VBScript only. Standard picture actions can keep using ANSI-C indefinitely; the runtime supports both languages side by side.
What is the equivalent of Debug.Print in WinCC runtime VBS?
Use HMIRuntime.Trace "MyVariable=" & MyVariable & vbCrLf. Output is appended to the RT diagnostic log, typically WinCC_Sys_<yyyymmdd>.log in the project directory. Enable tracing under Computer Properties -> Graphics Runtime -> Trace.
Why does my faceplate script compile in the editor but fault at runtime?
The editor performs only a shallow syntax check on faceplate property scripts; full object binding happens at first execution. The most common cause is a tag name with a typo, returning 0 silently. Run the project in simulation, attach a Trace action to the faceplate event, and inspect APLog.txt for the exact tag the runtime fails to resolve.