Disabling WinCC Toolbar Buttons at Runtime with VBScript

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

1. Overview

Siemens WinCC (TIA Portal / WinCC Professional and WinCC V7.x) provides two distinct categories of buttons on a runtime screen: standard toolbar buttons configured in the WinCC Explorer under Menus and Toolbars (stored in the project's .mtl file), and screen-level custom buttons created directly on a screen from the Toolbox palette. They expose different object models at runtime, and only the second category is directly scriptable with a per-instance Enabled or Operable property. Standard toolbar buttons cannot be toggled individually from VBS or C — the only supported method is replacing the entire toolbar configuration while runtime is running.

This article documents the three engineering-acceptable workarounds: (a) swapping between two pre-defined .mtl toolbars, (b) rebuilding the toolbar as a set of custom screen objects bound to a PLC tag, and (c) using the Operable property on graphics objects that inherit operator-control enable behavior. Each approach is paired with working VBScript, the exact HMIRuntime object path, and a verification procedure.

2. Problem Details

Symptom: A WinCC standard toolbar (configured in WinCC Explorer → Menus and Toolbars → file.mtl) contains 10+ command buttons, one per machine sequence. The HMI engineer must prevent operator access to specific buttons while a sequence is active. Toggling individual buttons should follow a PLC tag (e.g., SequenceRunning_01..SequenceRunning_10).

What does not work: The intuitive script

HMIRuntime.ActiveDocument.CustomToolbars(0).ToolbarItem("btnReturn").Enabled = False

fails silently. The CustomToolbars collection exposes a Visible and Name property on the toolbar itself, but ToolbarItem members are read-only at runtime. A Siemens application engineer confirmed in writing that per-button modification of a standard toolbar is not supported. References to the supported CustomToolbars object can be found in the WinCC V7.5 SP2 manual, WinCC V7.5: Working with WinCC → Customizing the User Interface → Custom Toolbars (Siemens entry ID 109773706).

3. Root Cause Analysis

Standard WinCC toolbars are instantiated from compiled resources inside WCCOAui.exe / CCExpMgr.dll and belong to the host shell, not the active screen document. The CustomToolbars object exposed by HMIRuntime.ActiveDocument is a collection of toolbar definitions — the children (ToolbarItem) have no public mutator in the WinCC runtime API. Any attempt to assign .Enabled, .Visible, or .Operable on a ToolbarItem raises error 0x80020009 (E_FAIL) or is silently ignored depending on the WinCC version.

By contrast, screen objects added from the Toolbox (button, round button, graphical I/O field, custom web control) are stored in the screen's PDL / F(X) source and re-instantiated at runtime as part of the document's ScreenItems collection. They are first-class members of the runtime document and accept all standard property writes.

4. Solution Architecture

Three engineering patterns solve the requirement. Choose by project constraints.

Method Best For Granularity Effort Re-build on PLC tag change
1. Toolbar swap (two .mtl definitions) WinCC V7 projects, large button counts Whole toolbar Low (duplicate toolbar once) Re-loads the entire toolbar container
2. Custom screen buttons in TIA WinCC Professional / TIA Portal Per button Medium (relayout) Direct .Enabled write per object
3. Operable property Any object inheriting operator enable Per object Low (single property) Tag-driven through Operable animation

4.1 Decision flowchart

Start: Do you need per-button enable/disable at runtime? Standard .mtl toolbar exists? Is TIA Portal (WinCC Prof) used? Method 1 Toolbar Swap Duplicate .mtl → swap via VBS Method 2 Custom Screen Buttons Use ScreenItems with .Enabled Alternative path → Method 3: Use Operable property with PLC tag

5. Method 1 — Toolbar Swapping with VBScript

5.1 Engineering the two toolbars

  1. Open WinCC Explorer, expand Menus and Toolbars, double-click the active .mtl file (typically file.mtl).
  2. Build the toolbar that contains all 10 sequence buttons — call this Toolbar_Full (for example, name the toolbar in the Toolbars tab as tb_SequenceFull).
  3. Duplicate the toolbar by right-clicking the Toolbars list and selecting Duplicate. Rename the copy to tb_SequenceRunning. In this toolbar, edit every sequence button to set its Operator authorization or Function so that pressing it has no effect (or remove the buttons entirely).
  4. Compile the project (right-click the project → Rebuild).

5.2 Swapping the toolbar at runtime

The CustomToolbars collection is indexable, and the Active property can be set to swap the currently displayed toolbar. Use a global action or a tag-triggered C/VBS action.

' VBS - Module: ModToolbarSwap
' Triggered by a "SequenceMode" change event
Sub ToolbarSwap_ByMode()
    Dim objDoc
    Set objDoc = HMIRuntime.ActiveDocument

    If SmartTags("SequenceMode") = 1 Then
        ' Running mode → show toolbar with disabled buttons
        objDoc.CustomToolbars(0).Name = "tb_SequenceRunning"
    Else
        ' Idle mode → show full operator toolbar
        objDoc.CustomToolbars(0).Name = "tb_SequenceFull"
    End If
End Sub
Note: In WinCC V7.5 and later, the .Name setter is supported. In older builds, use the legacy HMIRuntime.Screens("Overview").CustomToolbars(0).Activate() pattern together with a hot-key driven toolbar assignment. Confirm the supported property set against the WinCC V7.5: Working with WinCC reference (Siemens entry ID 109773706).

6. Method 2 — Custom Screen Buttons (TIA Portal / WinCC Professional)

This is the recommended approach for TIA Portal projects. Custom buttons placed on a screen are full members of ScreenItems and accept .Enabled writes.

6.1 Build the toolbar on a screen

  1. Open the relevant screen in the TIA Portal HMI editor.
  2. From Templates → Toolbars, drag a custom toolbar control onto the screen, or place 10 round buttons (or graphical I/O fields) on a header bar.
  3. Rename each button to a stable runtime name (e.g., btnSeq01..btnSeq10). This name becomes the HMI tag in ScreenItems.
  4. Wire the Click event of each button to its corresponding VBS action.

6.2 Tag-driven enable/disable

' VBS - Global script, scheduled every 500 ms (or tag-triggered)
' Inputs: SmartTags("SequenceRunning_01")..("SequenceRunning_10") Bool
'         SmartTags("OperatorLevel") Int (0 = no auth, 1 = operator, 2 = admin)
Sub Disable_Buttons_ByTag()
    Dim objBtn
    Dim i, idx, isRunning, allow

    For i = 1 To 10
        idx = CStr(i)
        Set objBtn = HMIRuntime.ActiveScreen.ScreenItems("btnSeq" & Format(i, "00"))

        isRunning = CBool(SmartTags("SequenceRunning_" & idx))
        allow     = (SmartTags("OperatorLevel") >= 1)

        ' Operable: greys out, blocks click
        objBtn.Operable = (Not isRunning) And allow
        ' Enabled: visual only, click still fires if Operable not also set
        objBtn.Enabled  = (Not isRunning) And allow
    Next
End Sub
Critical: In WinCC Comfort/Advanced, ScreenItems("name") is valid only while the parent screen is the active document. Buttons on Pop-up screens are accessed through HMIRuntime.Screens("PopUpName").ScreenItems("btnName"). For the global scheduled action, restrict polling to the start screen to avoid null references.

7. Method 3 — Operable Property with PLC Tag Animation

For engineers who want zero scripting, WinCC supports the Operator control enable animation on most interactive graphics objects. The Operable property accepts a tag value and dynamically toggles the operator control authority.

  1. Select the button (round button, button, I/O field).
  2. In the properties pane → Animations, add Operator control enable.
  3. Bind it to a PLC tag (Bool). Configure the table so that tag = 0 disables operation and tag = 1 enables it.
  4. Compile → RT. The button grey-out, click suppression, and focus handling are all handled by the runtime.

This is the lowest-risk path for plants with audit requirements: the disable state is enforced at runtime, not merely visual.

8. VBScript Reference — HMIRuntime Object Map

Object Property / Method Type Read/Write Notes
HMIRuntime.ActiveDocument — Document — Use for CustomToolbars swap.
Document.CustomToolbars .Count, .Item(i) Collection Read Cannot mutate children.
CustomToolbars(i) .Name, .Visible, .Activate Object Read/Write (V7.5+) Assign by name to swap toolbars.
HMIRuntime.ActiveScreen — Screen — Use for ScreenItems access.
Screen.ScreenItems(name) .Enabled, .Operable, .Visible Object Read/Write Valid for objects placed in the screen.
HMIRuntime.Screens("name") — Screen — Use when accessing pop-ups or non-active screens.
SmartTags("name") — Variant Read/Write External/PLC tags and internal tags.

9. Step-by-Step — Sequence Toolbar with PLC-Lockout

9.1 Prerequisites

  • WinCC V7.5 SP2 or TIA Portal V17+ with WinCC Professional/Comfort/Advanced.
  • PLC tags already exposed to HMI: SequenceRunning_01..SequenceRunning_10 (Bool), OperatorLevel (Int).
  • Project compiled, RT license active.

9.2 Procedure (Method 2, TIA Portal)

  1. Create a new screen SequenceOverview and add 10 round buttons named btnSeq01..btnSeq10. Stack them in a horizontal toolbar at the top of the screen.
  2. For each button, configure the Click event to call StartSequence_xx VBS actions that write the corresponding StartCmd_xx Bool to the PLC.
  3. Add a global VBS action PollLockout scheduled every 500 ms containing the code from §6.2.
  4. Compile → Start Runtime. Click Start Sequence 01 on the HMI; verify the PLC receives the command and that SequenceRunning_01 goes high.
  5. Confirm the btnSeq01 visually greys out within one poll cycle and that subsequent clicks are suppressed (no new StartCmd_01 pulse generated).
  6. Reset SequenceRunning_01 on the PLC. The button must return to active state within one poll cycle (≤ 500 ms).

9.3 Procedure (Method 1, WinCC V7)

  1. Create two toolbars: tb_Full (10 enabled buttons) and tb_Running (buttons set to operator authorization level 9, effectively dead).
  2. Add a VBS global action ToolbarSwap_ByMode from §5.2, triggered on tag change of SequenceMode.
  3. Compile, start RT, verify the toolbar swap occurs without flickering and that no events fire on the suppressed toolbar.

10. Verification & Testing

Check Procedure Pass Criterion
Button grey-out timing Toggle PLC tag from PLC simulator, observe button State change ≤ 1 s (TIA scheduled actions at 500 ms)
Click suppression Click disabled button, monitor PLC tag StartCmd_xx No pulse emitted (variance 0)
Toolbar swap latency (Method 1) Time SequenceMode change → visible swap ≤ 250 ms on V7.5 SP2 (typical 50–100 ms)
Tag-pull latency (Method 2) Force tag via WinCC Tag Simulator ≤ 500 ms + 1 scan
Authorization overlap Set OperatorLevel = 0, attempt click Button stays disabled regardless of SequenceRunning
Pop-up screen consistency Open pop-up on top of active screen, click button Pop-up button references resolve; no null object errors

11. Troubleshooting Matrix

Symptom Probable Cause Fix
Object required (Error 424) on ScreenItems("...") Wrong screen is active, or object name misspelled Use HMIRuntime.Screens("PopUpName") explicitly; verify name in Properties → General → Name
Button stays enabled despite script Script bound to wrong event (e.g., Mouse Down instead of Click) or button is a static graphic, not a screen object Verify the object is from the Toolbox (not pasted image) and re-bind events
Toolbar swap does nothing WinCC build pre-V7.5 lacks Name setter Use .Activate method with a pre-registered toolbar ID, or upgrade to V7.5 SP2
Tags read 0 even though PLC says 1 HMI tag connection not refreshed after PLC download Right-click tag → Update, or restart RT
Pop-up screen button has no effect at runtime Pop-up not yet loaded when script runs Defer script with HMIRuntime.BaseScreenName check or use pop-up Open event trigger
Authentication still allows click despite grey-out Enabled set, but Operable not set Set Operable = False (blocks click); Enabled alone is cosmetic
Compile error: Name already in use Two toolbars share a name after duplicating Rename second toolbar in Toolbars tab before compiling

12. Performance and Security Considerations

  • Polling frequency: A 500 ms global scheduled action is acceptable for ≤ 50 buttons. For larger counts, replace the loop with a single tag that carries a packed bitmask and dispatch via a Tag-triggered action (event-driven, no scan load).
  • Authority separation: Combine the Operable property with the WinCC user administration (Operator authorization tab) to enforce a defense-in-depth model — the button is greyed out by tag, blocked by operator level, and audited by Audit if WinCC Logging is licensed.
  • Tooltips: When disabling a button, set objBtn.Tooltip = "Sequence active — locked" to give the operator a clear reason. This reduces support calls.
  • RT restart: Toolbar swap state is non-persistent. After an RT restart, the active toolbar is re-read from the .mtl file. If the persisted toolbar must reflect the last sequence state, run the swap script from a Startup action.

13. Version Notes

WinCC Version Behavior Reference
V7.4 SP1 CustomToolbars(i).Name writable; toolbar item members read-only Siemens entry ID 109772921 — WinCC V7.4: Customizing the User Interface
V7.5 SP2 Adds .Activate on toolbar; confirms read-only items Siemens entry ID 109773706 — WinCC V7.5: Working with WinCC
TIA V15.1 Comfort/Advanced — limited custom toolbars; ScreenItems VBS supported Siemens entry ID 109751706 — WinCC Professional V15.1: Programming Scripting
TIA V17 / V18 Full Operable and Enabled writes; OPC UA tag binding Siemens entry ID 109817206 — WinCC Professional V18: Visualizing Processes

14. Field-Proven Caveats

  1. Do not write to ToolbarItem.Enabled in any VBS version — the property is generated by the COM type library but the underlying IDispatch does not implement put_Enabled. The script returns a generic 0x80020009 in the GSC diagnostics.
  2. WinCC Global Script Diagnostics (apdiag.exe) is the fastest tool to verify whether a tag-triggered action actually executed. Enable Logging level: All in Computer → Properties → Graphics Runtime.
  3. When migrating from V7 to TIA, the custom toolbars must be re-engineered — there is no direct import path for the .mtl file. Plan for a 1:1 rebuild during cutover.
  4. Buttons bound to faceplate instances are accessed through the faceplate's ScreenItems after the faceplate container is in the active screen. Add an extra read guard: If TypeName(objContainer) = "HMIButton" Then.

15. FAQ

Can I disable a single button inside a WinCC standard toolbar at runtime?

No. Standard .mtl toolbar buttons are read-only members of the CustomToolbars collection at runtime. The supported workaround is to swap the whole toolbar to a pre-built tb_SequenceRunning definition via HMIRuntime.ActiveDocument.CustomToolbars(0).Name = "tb_SequenceRunning", or rebuild the toolbar as screen-level custom buttons and write objBtn.Operable = False.

What is the difference between Enabled and Operable on a WinCC button?

Enabled toggles the visual state (grey-out). Operable blocks the click event from firing and removes the control from keyboard tab order. Always set Operable = False to enforce operator lockout; Enabled alone is cosmetic.

Why does ScreenItems("btnName") return Object required at runtime?

The button is on a different screen than HMIRuntime.ActiveScreen, or the object was renamed in the HMI editor and the script was not re-saved. Use HMIRuntime.Screens("ScreenName").ScreenItems("btnName") for non-active or pop-up screens, and verify the object's Name property matches exactly.

How fast does a tag-driven button disable take effect in WinCC Professional?

A scheduled VBS action at 500 ms produces a worst-case latency of 500 ms + one RT scan, typically < 600 ms. For sub-100 ms response, replace polling with a tag-triggered action that fires on the OnChange event of the lockout tag.

Is the toolbar swap state preserved across an RT restart?

No. The runtime reloads the default .mtl toolbar at startup. If the swap must persist, trigger the swap script from a WinCC Startup action that reads the current SequenceMode tag and re-applies the correct toolbar name.

Back to blog