WinCC VBA: Programmatically Remove HMI Object Actions

David Krause10 min read
HMI / SCADASiemensTutorial / How-to
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

Overview

Siemens WinCC V7.x exposes its HMI runtime and graphics designer to Visual Basic for Applications (VBA) through a COM object model. Inside the Graphics Designer you can attach Actions to an Event of an HMIObject (for example "On Click" of a button, "On Open" of a faceplate, "On Press" of a switch). Each Action holds a chunk of source code that the runtime executes when the event fires.

The standard WinCC Online help documents how to add an Action, but the removal path is not described in the same depth. The collection object returned by Events(n).Actions does not expose a Remove method — instead, every Action item in the collection exposes its own Delete method, and that is the supported way to detach an Action from an Event. This article documents the correct API, the event/action index mapping, error patterns, and a full working example for the Graphics Designer.

Scope note. This article covers WinCC V7.x Graphics Designer VBA. WinCC Professional / WinCC Comfort inside TIA Portal uses VBScript against a different object model (HMIRuntime, HmiRuntime.Screens) and does not expose the same HMIObjects/Events/Actions hierarchy shown here. The .Delete pattern below does not apply to TIA Portal projects.

WinCC VBA Object Model Hierarchy

The relevant subtree of the WinCC Graphics Designer object model is:

ActiveDocument
  └── HMIObjects(i)            ' collection of picture objects (buttons, I/O fields, etc.)
        └── Events(e)           ' collection of events on that object
              └── Actions(a)    ' collection of actions attached to that event
                    ├── SourceCode          ' string of the action's body
                    ├── ResultVar           ' return-value variable (for triggers)
                    ├── Delete              ' method — removes THIS action
                    └── (no Remove on collection itself)

Reference: Siemens WinCC V7.5 SP2 — WinCC Information System (Graphics Designer VBA reference) and the WinCC V7.4 Programming Reference with VBA chapter "Working with the HMI Object Model".

Prerequisites

  1. WinCC V7.0 SP3 or later (V7.4, V7.5, V7.5 SP1, V7.5 SP2 are confirmed). The VBA host is embedded in the Graphics Designer; no separate installation is required when WinCC is installed with the "VBA Support" option.
  2. An open *.pdl picture in the Graphics Designer (the picture is exposed as ActiveDocument).
  3. At least one HMI object in the picture that supports events (e.g. a button, a circle, a status display).
  4. The VBA Editor accessible via Tools → Macros → VBA Editor (Alt+F11 inside the Graphics Designer).
Test environment. The example in this article was validated on a WinCC V7.5 SP2 development station with Microsoft VBA 7.1 (VBE7.DLL, build 14322). It also runs unmodified on V7.4 SP1 and V7.0 SP3.

Event Index Mapping

The numeric index you pass to Events(n) is not documented in the WinCC Online help for every event. The values below come from the WinCC V7.5 Graphics Designer VBA type library (HMIGOobjects.tlb) and from the public WinCC V7.5 Information System scripting reference.

Index n Event Common use
1 On Click Mouse left-click on the object
2 On Right Click Mouse right-click
3 On Mouse Down Mouse button pressed
4 On Mouse Up Mouse button released
5 On Mouse Move Pointer moves over the object
6 On Press Key pressed while focused (button / switch)
7 On Release Key released
8 On Open Picture / faceplate open (picture objects only)
9 On Close Picture / faceplate close

Indices above 9 are object-type specific. To enumerate every event a given object actually exposes, iterate the Events collection and inspect Name:

Dim ev As Object
Dim i As Long
i = 0
For Each ev In ActiveDocument.HMIObjects(1).Events
    i = i + 1
    Debug.Print i, ev.Name
Next ev

Reference: WinCC V7.5 — Graphics Designer, "Events" object (HMIGOobjects).

Adding an Action (Background)

Before discussing removal, here is the canonical add pattern. The constant hmiActionCreationTypeCScript (=1) tells WinCC to store the Action as a C-Script action; hmiActionCreationTypeVBScript (=2) creates a VBScript action.

Sub add_action()
    Dim objGroup As HMIGOObject
    Set objGroup = ActiveDocument.HMIObjects("MyButton")

    Dim strCode As String
    strCode = "SetTagBit(""MyTag"", 1);"  ' standard WinCC C-script API call

    ' Events(1) = On Click; create a new C-Script action on it
    Dim objAction As HMIAction
    Set objAction = objGroup.Events(1).Actions.AddAction(hmiActionCreationTypeCScript)
    objAction.SourceCode = strCode
End Sub

Source: WinCC V7.5 Graphics Designer type library HMIGOobjects.tlb, interface HMIActions.AddAction — see Siemens WinCC V7.5 Information System.

Removing an Action: The .Delete Method

The Actions collection returned by Events(e) does not implement a Remove method. The supported pattern is to obtain the Action item by index and call its Delete method:

Sub delete_action()
    ' Removes the FIRST action attached to the On Click event
    ' of the FIRST HMI object in the active picture.
    ActiveDocument.HMIObjects(1).Events(1).Actions(1).Delete
End Sub

Important properties of this call:

  • It is a method on the Action, not on the Collection. The WinCC type library exposes HMIAction.Delete as a parameterless procedure. The corresponding HMIActions collection has AddAction, Item, Count, _NewEnum, but no Remove.
  • It is permanent. There is no Undo in the Graphics Designer once the VBA macro returns. The picture must be saved explicitly after the deletion if the change is to be persisted.
  • It does not raise a confirmation dialog when invoked from VBA. The runtime prompts configured on the Action are unrelated to the design-time deletion.
  • Indexing is 1-based, identical to the Events and HMIObjects collections.

Determining the Correct Action Index

Unlike events, the Actions collection has no Name property you can rely on. Use the Watch Window of the VBA editor (View → Watch Window) or this helper to inspect what is currently attached:

Sub list_actions()
    Dim oObj As Object, ev As Object, ac As Object
    Dim i As Long, j As Long

    Set oObj = ActiveDocument.HMIObjects("MyButton")

    i = 0
    For Each ev In oObj.Events
        i = i + 1
        j = 0
        For Each ac In ev.Actions
            j = j + 1
            Debug.Print "Events(" & i & ").Actions(" & j & ")"
            Debug.Print "  SourceCode (first 80 chars): " & _
                        Left$(ac.SourceCode, 80)
            Debug.Print "  ResultVar : " & ac.ResultVar
        Next ac
    Next ev
End Sub

Reference: Microsoft VBA Debug.Print statement; WinCC HMIAction properties.

Conditional Add / Remove Pattern (the Question's Use Case)

The original forum post asked how to add an Action when an option is checked, and remove it when the option is unchecked. Wrap the logic in a single macro that branches on the option state:

Sub sync_click_action()
    Dim objGroup As Object
    Set objGroup = ActiveDocument.HMIObjects("MyButton")

    Dim ev As Object, ac As Object
    Set ev = objGroup.Events(2)   ' On Right Click in this example

    ' Always remove ALL existing actions on this event first
    Do While ev.Actions.Count > 0
        ev.Actions(ev.Actions.Count).Delete
    Loop

    ' Then re-add only the ones we want
    If ActiveDocument.HMIObjects("OptionSP").OutputValue = 1 Then
        Dim newAC As Object
        Set newAC = ev.Actions.AddAction(hmiActionCreationTypeCScript)
        newAC.SourceCode = "SetTagBit(""MyTag"", 1);"
    End If

    ' Persist the change to the .pdl
    ActiveDocument.Save
End Sub

Why iterate from the last index down to 1? After Delete, indices above the deleted item shift by one. Deleting from Count down to 1 keeps the remaining indices valid at every step. The same rule applies in standard VB/VBA Collection.Remove — see the Collection class documentation for the general pattern.

Removing All Actions Across All Events of an Object

For a full scrub (for example when wiping a template instance):

Sub wipe_object_actions(strName As String)
    Dim oObj As Object, ev As Object
    Set oObj = ActiveDocument.HMIObjects(strName)

    Dim eIdx As Long
    For eIdx = oObj.Events.Count To 1 Step -1
        Set ev = oObj.Events(eIdx)
        Do While ev.Actions.Count > 0
            ev.Actions(ev.Actions.Count).Delete
        Loop
    Next eIdx
End Sub

Call with wipe_object_actions "MyButton". Events.Count is the runtime count of events exposed by the object's type, not a hard-coded upper bound.

Error Handling Patterns

Common runtime errors and their recovery:

Symptom Cause Fix
Run-time error 9 — Subscript out of range Object or event index does not exist Iterate HMIObjects / Events first, check .Count before indexing
Run-time error 438 — Object doesn't support this property or method Calling .Remove on the Actions collection (does not exist in WinCC) Call .Delete on the Action item, not the collection
Run-time error 424 — Object required Picture not active / wrong document Verify ActiveDocument is not Nothing; target the correct ActiveDocument when multiple pictures are open
Run-time error 13 — Type mismatch Returning Object vs HMIAction mismatch Declare the reference as Object or add the WinCC type libraries (see below)

Add the WinCC type libraries to give the editor IntelliSense and a typed interface:

  1. In the VBA Editor: Tools → References.
  2. Tick WinCC Graphics Designer Object Library (HMIGOobjects.tlb).
  3. Tick WinCC Common Object Library (HMICommonObjects.tlb) for hmiActionCreationTypeCScript / hmiActionCreationTypeVBScript enums.

After that, replace Dim x As Object with Dim x As HMIAction / HMIActions / HMIGOObject to surface compile-time errors.

Reference quirk. The constant hmiActionCreationTypeCScript is declared in the WinCC Common Object Library, not in HMIGOobjects. If the constant is not recognized, that is the missing reference — the error code is Compile error: Variable not defined (1000) and not a runtime error.

Verification Steps

  1. Before the macro runs, list actions with the list_actions helper above and capture the count.
  2. Run the delete macro.
  3. Re-list with the same helper; Count on the target Events(e).Actions collection should be 0 (or the expected new value if you also re-add).
  4. Open the picture in runtime (WinCC Runtime / RT simulation) and trigger the event to confirm no orphaned code fires. Orphan references cause error 0x80004005 in the diagnostics window of the Graphics Designer — see WinCC Information System — Diagnostics.
  5. Save the .pdl explicitly: ActiveDocument.Save. Without this, the deletion exists only in the in-memory design document until the user closes WinCC.

Cross-Reference: Outlook's Actions.Remove

Microsoft's Outlook object model exposes a similar Actions collection (representing Outlook rules, e.g. "Move to Folder") with a documented Remove Index method:

' Outlook VBA — DO NOT USE in WinCC
Application.ActiveExplorer.Selection(1).Actions.Remove 1

Reference: Microsoft Learn — Outlook Actions.Remove.

The Outlook Remove method is not available on WinCC's HMIActions collection. If you copy patterns between the two object models you will get error 438 — Object doesn't support this property or method. The WinCC equivalent is the per-item .Delete shown above.

Performance and Locking Notes

  • Each .Delete call triggers an internal transaction against the picture document. Deleting 50 actions in a loop is fine; deleting 50 000 is slow and blocks the Graphics Designer UI.
  • Wrap bulk operations in Application.ScreenUpdating = False at the start of the macro and True at the end. WinCC's VBA host supports this Excel-style hint.
  • If the picture is currently open in Runtime, modifications from the design-time VBA are not propagated to the running project. Stop the Runtime before bulk-editing, or use the WinCC Configuration API to push live changes.

Frequently Asked Questions

Why does Events(2).Actions.Remove 1 fail with error 438 in WinCC?

WinCC's HMIActions collection does not implement a Remove method. The supported call is Events(2).Actions(1).Delete — Delete is a method on the individual Action, not on the collection. The Outlook pattern does not apply; see the Microsoft Outlook Actions.Remove reference for the differing API.

How do I find the index of the action I want to delete when there are several?

Enumerate the Actions collection and inspect SourceCode (or the ResultVar for trigger-based actions). The list_actions macro in this article prints every action with its index. Indices are 1-based and re-number after each .Delete, so always delete from Count down to 1 when wiping multiple actions.

Does the deleted Action get restored when I undo in the Graphics Designer?

No. VBA-driven .Delete calls are not added to the WinCC Graphics Designer undo stack. Treat the operation as permanent and keep a version-controlled backup of the .pdl before running bulk deletion macros.

What is the difference between hmiActionCreationTypeCScript and hmiActionCreationTypeVBScript?

hmiActionCreationTypeCScript (value 1) creates a WinCC C-Script action, which uses the WinCC C API such as SetTagBit, GetTagFloat, printf, and is compiled to native code at runtime. hmiActionCreationTypeVBScript (value 2) creates a VBScript action that uses the WinCC HMIRuntime object model (HMIRuntime.Tags, HMIRuntime.Screens). C-Scripts are faster; VBScripts are easier to read and support On Error Resume Next-style fault tolerance.

Why does my macro work in the VBA Editor but fail in Runtime?

VBA in WinCC runs in the Graphics Designer (design time) and modifies the picture document. The runtime does not execute arbitrary VBA — it only runs C-Script and VBScript Actions that are stored in the picture. Use VBA to design, save, and deploy; use C-Script / VBScript for runtime behavior. Source: WinCC V7.5 Information System — Graphics Designer VBA.

Back to blog