WinCC Script Execution: Triggering Event Actions Programmatically

David Krause13 min read
SiemensTutorial / How-toWinCC
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

WinCC Script Execution: Triggering Event Actions Programmatically

In WinCC (TIA Portal Unified, WinCC Professional, and WinCC V7/V8), scripts are most commonly bound to object events such as On Click, On Mouse Down, or On Property Change. The straightforward question that arises in nearly every larger HMI/SCADA project is: can the script configured on an event be invoked from another script, without the operator actually clicking the button? The short answer is yes — but never by replaying the mouse event. WinCC does not expose a runtime API to fire On Click on a specific screen object. Instead, you must refactor the logic so it lives in a callable layer (project function, global action, or ODK-triggered action) and let the event, the new caller, or the ODK invoke that layer.

This reference walks through every practical method available in TIA Portal WinCC Unified V20, WinCC Professional (TIA Portal), and WinCC V7.5/V7.6/V8.0 to trigger an event-bound action programmatically, with concrete VBScript, C script, and ODK code samples, plus a decision matrix for choosing the right method.

Architectural rule: Never put business logic directly in the On Click event. Always wrap it in a project function or global action. The event handler should do nothing but call the function. This single rule makes every programmatic-trigger pattern in this article possible.

1. Why Direct Event Firing Is Not Supported

The WinCC runtime object model exposes screens (HMIScreen), screen items (HMIScreenItem), tags (HMITag), and the central HMIRuntime object. What it does not expose is a method such as HMIRuntime.FireEvent("Button1", "Click"). WinCC Unified and WinCC Professional both treat the event handler as an opaque callback owned by the graphics engine; the runtime has no public method to invoke it out-of-band.

Two practical consequences follow:

  • You cannot simulate a mouse click from VBS or C. Any attempt using WScript.Shell.SendKeys or Windows API SendInput is fragile, depends on focus, and breaks fullscreen runtime.
  • You must restructure the logic so the event becomes one of several possible entry points to a single function or action.

2. Event, Action, and Function Architecture in WinCC

Before choosing a trigger mechanism, understand the three script layers available in WinCC:

Layer Scope Where configured Callable from?
Event script (C/VBS) Single object, single event Properties → Events in the screen editor Only by the runtime engine when the event fires
Project function (VBS) / Project function (C) Project-wide, parameterised Project library → Scripts Other project functions, event scripts, global actions, ODK
Global action (cyclic / tag-triggered) Project-wide, scheduled Scheduler → Actions Triggered by time, tag change, or APStart
ODK API Runtime external C/C++ WinCC ODK installation Native Windows applications, add-ins

The correct pattern is therefore: event → project function → business logic. Once the function exists, the event becomes optional and any other script can call it directly.

3. Prerequisites

  • WinCC Unified V18 / V19 / V20 (TIA Portal) — for Unified VBScript and Unified C scripting APIs. See the official Configuring a script to an event (RT Unified) documentation.
  • WinCC Professional V18/V19/V20 (TIA Portal) — for VBScript and C scripts in the classic WinCC Professional environment.
  • WinCC V7.5 SP2 / V8.0 (or later) — for ANSI-C, VBScript, and the WinCC ODK 1200/1500/700/800 APIs.
  • WinCC ODK installed (required only for the ODK APStart / APTransAct method in section 7).
  • The event script's body must be wrapped in a project function (covered in section 4).

4. Method 1 — Refactor to a Project Function (Recommended)

This is the simplest, most portable, and most maintainable approach. It works identically in TIA Portal Unified, TIA Portal Professional, and WinCC V7/V8.

4.1 Create the project function

Open Project tree → Scripts → Project functions and add a new function. In TIA Portal Unified, the editor is reached via RT Unified → Scripts. The procedure for attaching it to an event is described in Configuring a script to an event (RT Unified).

VBScript example (Unified / Professional):

' Project function: ShowRecipeScreen
' File: Scripts/Project functions/ShowRecipeScreen.vbs
Sub ShowRecipeScreen(sRecipeName)
    Dim sScreen
    sScreen = "Recipe_" & sRecipeName
    HMIRuntime.BaseScreenName = sScreen
    ' Trace for verification
    HMIRuntime.Trace "ShowRecipeScreen: opened " & sScreen & vbCrLf
End Sub

ANSI-C example (WinCC V7 / Professional):

// Project function: ShowRecipeScreen
// File: Scripts/Project functions/ShowRecipeScreen.c
void ShowRecipeScreen(const char* sRecipeName)
{
    char sScreen[256];
    sprintf(sScreen, "Recipe_%s", sRecipeName);
    SetVisible(sScreen, 0, 1);   // classic WinCC V7 API
    // Or for TIA Portal: ProgramSetProperty("Screen", "Visible", 1, sScreen);
}

4.2 Call from the original event

Re-open the button event and replace the inline body with a one-line call:

' On Click of Button_Recipe_01
ShowRecipeScreen "LineA_Mix1"

For C scripts in WinCC V7 / Professional, the event body simply becomes:

// On Click of Button_Recipe_01
ShowRecipeScreen("LineA_Mix1");

4.3 Call from any other script

Now any VBScript anywhere in the project — another button, a tag-triggered global action, a scheduled action, or an ODK callback — can invoke the same function:

' On Click of Button_External_Trigger
ShowRecipeScreen "LineA_Mix1"

Multiple callers, single source of truth, zero special handling.

Why this is the right default: it works in every WinCC version, requires no add-ons, survives refactors, and is trivially testable. Use a project function unless you have a documented reason not to.

5. Method 2 — Tag-Triggered Event (No Code Refactor)

If you cannot touch the event script (for example, it is generated from a library you do not own), the cleanest workaround is to use a tag change as an indirect trigger. This pattern is mentioned in Siemens' own scheduler documentation: actions can be fired on tag change as well as cyclically.

5.1 Create a trigger tag

Add a binary or integer internal tag, e.g. Trigger_ShowRecipe.

5.2 Bind a global action to that tag

Open Scheduler → Actions and create a new global action with the trigger Tag change referencing Trigger_ShowRecipe. The action body is the same code that used to live in the event script.

5.3 Fire the tag from any script

' VBScript (Unified)
HMIRuntime.Tags("Trigger_ShowRecipe").Write 1
HMIRuntime.Tags("Trigger_ShowRecipe").Write 0   ' toggle so a second call also fires

This pattern is useful when the original event script must remain untouched but a parallel trigger is acceptable. The downside is a small latency (one tag-poll cycle, typically 250 ms in WinCC V7 and 100 ms in WinCC Unified) and the need for an extra tag.

6. Method 3 — WinCC ODK: APStart and APTransAct

The WinCC Open Development Kit (ODK) is a C/C++ API that gives external applications and internal actions programmatic access to the WinCC runtime. Two functions are the cornerstone of programmatic action triggering:

Function Purpose Declared in
APStart Starts a WinCC global action by its configured name. The action runs on the scheduler thread. apdefap.h (ODK)
APTransAct Writes a value to a WinCC tag from an external context, often used to fire a tag-triggered action. apdefap.h (ODK)

6.1 Calling APStart from C script (WinCC V7)

// Project function: StartShowRecipeAction
// Requires ODK enabled in the project (Project properties → Options → ODK)
#include "apdefap.h"
void StartShowRecipeAction(const char* sRecipeName)
{
    // The action "ShowRecipeAction" must exist in the scheduler with
    // a parameter or use a separate trigger tag.
    DWORD dwRet = APStart("ShowRecipeAction");
    if (dwRet != 0)
    {
        printf("APStart failed, error %lu\r\n", dwRet);
    }
}

On success, APStart returns 0. Common non-zero return codes from the ODK are documented in the WinCC ODK help under Return values of the ODK functions; examples include -1 for "action not found" and licensing errors when the ODK runtime licence is missing.

6.2 Passing parameters

APStart itself takes only the action name. To pass dynamic data, either:

  • Write the data into internal tags with SetTagChar / SetTagFloat first, and have the action read them at start, or
  • Use APTransAct to set a tag value that the action is bound to as its trigger.

6.3 Using APTransAct to fire a tag-triggered action

#include "apdefap.h"
void FireShowRecipeByTag(const char* sTagName, double dValue)
{
    // APTransAct(lpszTagName, dwType, lpvData, dwSize, dwQuality, lpszUser, dwCode)
    DWORD dwRet = APTransAct(
        (LPCSTR)sTagName,        // tag name
        APT_DOUBLE,              // data type
        &dValue,                 // value buffer
        sizeof(dValue),
        0,                       // quality = good
        NULL,                    // user
        0                        // code
    );
    if (dwRet != 0)
    {
        // See ODK return codes; non-zero indicates a WinCC error.
        printf("APTransAct failed, code %lu\r\n", dwRet);
    }
}

Combined with a global action whose trigger is set to Tag change on the same tag, this is the ODK equivalent of Method 2 but with deterministic timing because the tag write is synchronous.

6.4 Licensing and runtime requirements

The WinCC ODK is gated by a runtime licence option. In WinCC V7.5 and later this is the WinCC/ODK licence; in TIA Portal Unified the equivalent is the Runtime ODK option. The project must also have ODK enabled in Project properties → Options → ODK; the option is not available unless the engineering licence includes it.

ODK code must be compiled against the correct ODK version (1200, 1500, 700, 800). Mismatched header/library versions cause load-time errors on the WinCC server. Always rebuild the DLL after a WinCC major version upgrade.

7. Method 4 — Simulating the Trigger from a Cyclic Action

For purely internal logic that must run on a schedule, the simplest path is a cyclic global action that monitors a condition and invokes the project function from Method 1. Cyclic actions are documented in the same scheduler editor as tag-triggered actions.

' Cyclic global action (Unified VBScript) — runs every 1 s
If HMIRuntime.Tags("bAutoShow").Read = 1 Then
    ShowRecipeScreen "Auto_LineA"
    HMIRuntime.Tags("bAutoShow").Write 0
End If

This is equivalent to a polling worker and is the right tool when the trigger source is external (a PLC flag, a database row, a message frame) and you do not want to push event wiring into the PLC.

8. Method Comparison Matrix

Method Requires refactor? Latency External callers? WinCC V7 WinCC Professional WinCC Unified ODK licence?
1. Project function Yes (one function) Direct (call) Yes (via ODK bridge) Yes Yes Yes No
2. Tag-triggered action No (parallel action) ~1 tag cycle (100–250 ms) Yes (write the tag) Yes Yes Yes No
3. ODK APStart / APTransAct No Synchronous Yes (native C/C++) Yes Limited Yes (ODK V20) Yes
4. Cyclic action No 1 cycle period No (internal only) Yes Yes Yes No

9. Step-by-Step: Triggering a Button's On Click Logic from Another Button

This procedure realises the original forum scenario: button A has a configured On Click action; button B must run the same logic without the operator clicking A.

  1. Open the screen that contains Button A in the WinCC graphics editor.
  2. Select Button A and open Properties → Events. Note the configured On Click script.
  3. In the project tree, create a new Project function (VBS or C) named e.g. ButtonA_Action.
  4. Copy the body of the On Click event into the new function. Convert any unqualified identifiers to fully qualified ones (e.g. HMIRuntime.BaseScreenName in Unified, ActivateScreen in V7).
  5. Replace the On Click body with a single call: ButtonA_Action.
  6. Compile / build the project and load it to the runtime.
  7. Test Button A — it must behave exactly as before.
  8. Open Button B's On Click event and insert the same call: ButtonA_Action.
  9. Compile, load, and test both buttons. Both must produce identical screen transitions.

10. Step-by-Step: Triggering from Outside the Project via ODK

  1. Install WinCC ODK and activate the WinCC/ODK runtime licence on the target station.
  2. In the engineering project, enable ODK support under Project properties → Options → ODK.
  3. Create the global action that the external code will start (e.g. ShowRecipeAction) and parameterise it via internal tags as described in section 6.2.
  4. Create a new C++ DLL project in Visual Studio, link against the matching ODK import library (e.g. apdefap.lib for ODK 1500).
  5. Implement a function that calls APStart("ShowRecipeAction") after writing parameters with SetTagXxx or APTransAct.
  6. Export the function with __declspec(dllexport) and drop the DLL into the WinCC project path so it is loaded by the runtime or by the configured add-in.
  7. Restart the WinCC runtime and verify via the WinCC diagnostics window (WinCC V7) or the Unified RT trace that the action starts.

11. Verification Checklist

  • Trace output: Add a HMIRuntime.Trace (Unified) or printf (V7) line at the top of the function and confirm it fires only when expected, not on every cycle.
  • APStart return code: Capture the return value and assert == 0 before assuming the action started.
  • Tag-triggered action: Toggle the trigger tag from 0 to 1 and back, then back to 1 again; the action must fire twice, confirming the change is detected both ways.
  • Event handler removal test: Temporarily delete the original On Click script and confirm the alternate trigger still works — this proves the logic is no longer dependent on the event.
  • Licence check: In WinCC License Analysis verify that the ODK option shows valid at runtime if Method 3 is in use.

12. Common Pitfalls

  • Calling the function from the wrong scope. Project functions are global, but in WinCC Unified you must use the VBScript global namespace, not a screen-local module.
  • Re-entrancy. If the same action is fired recursively (e.g. APStart inside an action whose body is the action itself), the runtime can deadlock the scheduler. Always guard with a "running" flag tag.
  • Tag-write thrash on tag-triggered events. Writing the same value the tag already has will not fire the action. Always toggle or use a counter tag.
  • ODK header mismatch. A DLL compiled against ODK 700 will not load under a WinCC V8 runtime expecting ODK 800 symbols; rebuild on upgrade.
  • Event script left empty. When refactoring, leaving an empty On Click event can make subsequent maintenance impossible to recognise. Either leave a one-line comment or remove the event binding entirely.

13. Security and Operational Considerations

Triggering event actions programmatically bypasses operator confirmation and authorisation tied to the UI control. If the original On Click was guarded by WinCC user-administration rights (the Authorization property on the screen object), replicating the action in a global function moves that check out of the button and into the script:

' VBScript (Unified) - explicit authorisation check
Sub ShowRecipeScreen(sRecipeName)
    If HMIRuntime.Tags("CurrentUser_Level").Read < 5 Then
        HMIRuntime.Trace "ShowRecipeScreen: insufficient rights" & vbCrLf
        Exit Sub
    End If
    HMIRuntime.BaseScreenName = "Recipe_" & sRecipeName
End Sub

Document this explicitly in the project, otherwise an external trigger can drive actions the operator was never permitted to drive from the UI.

14. Related Runtime APIs

API Use case WinCC version
HMIRuntime.Tags(...).Write Set tag from any VBS Unified, Professional
HMIRuntime.BaseScreenName = ... Screen change Unified, Professional
SetVisible / ActivateScreen Screen & layer control WinCC V7 / V8
APStart Start a global action WinCC V7 / V8, Unified ODK
APTransAct Set tag from ODK / scheduler WinCC V7 / V8, Unified ODK
GrafRT APIs Direct object manipulation WinCC V7 / V8

15. FAQ

Can I fire a WinCC On Click event from VBScript directly?

No. WinCC does not expose a runtime method to fire a UI event. Wrap the On Click body in a project function and call that function from any other script, or bind a global action to a tag change and write the tag from VBScript.

What is the difference between APStart and APTransAct in the WinCC ODK?

APStart("ActionName") launches a configured global action by name on the scheduler. APTransAct writes a value to a WinCC tag and is typically used to fire a tag-triggered action or to pass data into an action that will start.

Do I need a WinCC ODK licence to trigger an action programmatically?

Only for the ODK-based methods (Method 3). The project-function and tag-triggered methods work with a standard WinCC runtime licence. ODK requires the WinCC/ODK runtime option in WinCC V7/V8 or the Runtime ODK option in WinCC Unified.

Why is my tag-triggered action not firing when I write the same value twice?

Tag-triggered actions fire only on a value change. If the tag is already at the new value, the action will not run. Either toggle the tag (write the new value, then write a different one) or use an incrementing counter tag whose value always changes.

Is the refactor (Method 1) supported in WinCC Unified V20?

Yes. WinCC Unified V20 supports VBScript and C project functions in RT Unified → Scripts, and any of them can be bound to an object event as documented in the official Configuring a script to an event (RT Unified) guide.

Back to blog