Resolving WinCC VBScript Compile Errors Migrating from VBA

David Krause12 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

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.

Scope: This reference targets WinCC V7.x and WinCC Professional (TIA Portal) V15-V18. Behavior is consistent across SCADA, RT Professional, and Panel-style runtime targets. PowerShell/C# RT Professional scripts are not covered.

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.exe automation.
  • 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.

Reference: See the document VBA for Automated Configuration in the WinCC installation directory (default path 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
Performance tip: Because VBS 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:

  1. Open WinCC Explorer -> Graphics Designer.
  2. Menu Tools -> Macros -> VBA Editor.
  3. Project tree -> right-click Project -> Insert -> Module.
  4. Paste the original Sub Read_HMIObject_Dynamics() verbatim.
  5. 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:

  1. 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.
  2. 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.
  3. Strip type qualifiers. Run a search-and-replace on every Dim statement: As Integer, As Long, As String, As Boolean, As Object, As Variant, As Double, As Single. Replace with nothing.
  4. Replace design-time roots. Map ThisDocument.HMIObjects -> HMIRuntime.Screens("PictureName").ScreenItems; map ThisDocument.HMIObjs to the same.
  5. Replace Debug.Print. Debug.Print -> HMIRuntime.Trace <expression> & vbCrLf. Enable the diagnostic trace via WinCC Explorer -> Computer -> Properties -> Graphics Runtime -> Trace.
  6. Remove unsupported statements. On Error Goto, Resume, Line Input, WithEvents, user-defined Type blocks, and ReDim Preserve across object arrays are not supported.
  7. Wrap scripts in Sub ... End Sub if you want a free procedure. Action scripts do not require Sub but procedures you call from an action do.
  8. Compile with F7 in the editor. Resolve every error before deployment. The status bar must show Compile completed successfully.
  9. Validate by triggering the action manually (button click or scheduled 1 Hz cycle) and inspecting APLog.txt in the RT directory.
  10. 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 contains ThisDocument as 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 Type or 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 call cscript.exe outside the WinCC install will fail. Use HMIRuntime.Trace for diagnostics instead.
  • Implicit Variant conversion can hide bugs. Dim a : a = "10" + 5 evaluates to 15, not 105. Use explicit CStr / CLng when 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 to HMIRuntime.Scheduler or 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.

Back to blog