Problem Statement
Siemens WinCC global actions and scheduled VBScript routines accept multiple tags in the trigger list of the Action properties dialog. The runtime semantics, however, are unambiguously OR: the action is queued for execution as soon as any one of the listed trigger tags changes its process value. The HMI engineering manual states the trigger condition explicitly: "If an action is linked with several tags, the action is executed when one of the tag values changes." This is documented in the WinCC V7.5 SP2 scripting manual and reproduced in the TIA Portal WinCC Professional V17 help system.
Engineers frequently need the opposite: the action should only fire when all N tags simultaneously satisfy a given value (for example, all permissive bits are 1, all drive statuses report Ready, or all safety-related acknowledgements have arrived). The runtime does not provide a native AND-condition across multiple trigger tags, so the logic has to be reconstructed in the script body using a guard clause or an edge-detect latch.
Trigger Model in WinCC Global Actions
A global action in WinCC Runtime is associated with a trigger configuration that consists of one or more of the following elements:
- Tag(s) — change of value (rising, falling, or any change) starts the action
- Time schedule (cyclic, once per minute, hourly, daily)
- Hotkey event
When more than one tag is listed, the action is fired once per tag-change event. There is no implicit conjunctive operator. The full specification of the trigger mechanism is provided in the WinCC V7.5 SP2 Scripting (VBS, C) manual and the WinCC Professional V17 Runtime documentation entry under Working with WinCC > VBScript > Actions > Triggering Actions.
Three Implementation Patterns for AND-Logic
Three field-proven patterns solve the multi-tag AND condition. The choice depends on tag count, HMI load budget, and whether the action has side effects that must not run multiple times in a single scan.
| Pattern | Trigger Tags | Script Calls per Cycle | Idempotency Required | Best Use Case |
|---|---|---|---|---|
| 1. Single trigger + polled read | 1 | 1 (on chosen trigger) | No | 1–4 tags, low change rate |
| 2. All-tags trigger + early-return guard | N | N (one per change) | Yes (cheap) | 2–6 tags, debug-friendly |
| 3. Edge-detect latch | 1 (or all) | 1 | Yes | Any tag count, side-effect heavy |
Pattern 1 — Single Trigger Tag with Polled Read
Use one of the permissives as the trigger tag. Inside the script, Read the remaining tags and only execute the body when every tag returns the expected value. This produces exactly one script invocation per trigger edge and gives deterministic behaviour for the action side-effects.
' --- VBScript, TIA Portal WinCC Professional / WinCC V7.x ---
Option Explicit
Dim t1, t2, t3, t4
Set t1 = HMIRuntime.Tags("HMI_DB.Permissive_Ack_1")
Set t2 = HMIRuntime.Tags("HMI_DB.Permissive_Ack_2")
Set t3 = HMIRuntime.Tags("HMI_DB.Permissive_Ack_3")
Set t4 = HMIRuntime.Tags("HMI_DB.Permissive_Ack_4")
t1.Read : t2.Read : t3.Read : t4.Read
If (t1.Value = 1) And _
(t2.Value = 1) And _
(t3.Value = 1) And _
(t4.Value = 1) Then
' --- critical section: runs only when ALL tags are 1 ---
HMIRuntime.Tags("HMI_DB.All_Permissive_OK").Write 1
ShowSystemAlarm "All permissives acknowledged - line release granted"
End If
Notes on the implementation:
- Pick the least-likely-to-chatter tag as the trigger. A tag toggling at 10 Hz will fire the action at 10 Hz even when the guard fails, so choose a stable permissive bit.
- All
Readcalls are required becauseHMIRuntime.Tags(...).Valuereturns the last cached image of the tag — without an explicitReadthe value may be stale by up to one acquisition cycle. - Wrap the body in an
If ... Thento keep the action semantically a one-shot edge-driven event.
Pattern 2 — All-Tags-Trigger with Early-Return Guard
List every tag in the trigger configuration. The runtime will invoke the script once per tag change, but the script returns immediately unless all values are 1. This pattern is favoured for clarity during commissioning and HMI screen debugging because the engineer can see, in the trace, that the action was called and returned without effect.
' --- All tags are listed as trigger tags ---
Dim t, i, allOne
Set t = HMIRuntime.Tags
allOne = True
For i = 1 To 5
Dim tg
Set tg = t("HMI_DB.Permissive_" & i)
tg.Read
If tg.Value <> 1 Then
allOne = False
Exit For
End If
Next
If Not allOne Then Exit Function
' --- critical section ---
HMIRuntime.Tags("HMI_DB.All_Permissive_OK").Write 1
ShowSystemAlarm "All five permissives acknowledged"
The early-return guard keeps the script cost proportional to the first tag that fails. For a 5-tag system where 4 of 5 are already 1 and the fifth changes once per minute, the runtime invokes the script 5 times (once per tag in the change burst) but only the last one passes the guard and runs the body.
Pattern 3 — Edge-Detect Latch
Use Pattern 3 when the action body is not idempotent (pulse output, write to a single-bit coil, incrementing tag, mailer call). The trigger is configured on one or more of the source tags, and the script writes a sticky edge bit when the AND becomes true. A second global action (or the same action in cyclic mode) processes the edge bit and clears it inside the same scan.
' --- "Permissive_OK" global action, trigger = any of the five tags ---
Dim t, i, ok, prev_ok
Set t = HMIRuntime.Tags
ok = True
For i = 1 To 5
Dim tg : Set tg = t("HMI_DB.Permissive_" & i)
tg.Read
If tg.Value <> 1 Then ok = False : Exit For
Next
HMIRuntime.Tags("HMI_DB.Permissive_OK_State").Write CInt(ok)
Dim prev : Set prev = t("HMI_DB.Permissive_OK_State_Prev")
prev.Read
If ok And (prev.Value = 0) Then
' rising edge of the AND condition
HMIRuntime.Tags("HMI_DB.All_Permissive_OK_Edge").Write 1
End If
prev.Write CInt(ok)
' --- Cyclic 250 ms consumer action ---
Dim e : Set e = HMIRuntime.Tags("HMI_DB.All_Permissive_OK_Edge")
e.Read
If e.Value = 1 Then
HMIRuntime.Tags("HMI_DB.All_Permissive_OK").Write 1
ShowSystemAlarm "All permissives acknowledged"
e.Write 0 ' clear the edge bit - one-shot
End If
This pattern survives any number of trigger tags and any tag-change storm. The edge bit is guaranteed to be set exactly once per positive-going transition of the AND condition, and is consumed by a separate action that has its own trigger (here a 250 ms cycle).
Pattern 4 — C-Script Variant (WinCC V7.x)
For high-frequency applications (above 10 events/s) the C-script interface outperforms VBScript. The behaviour is identical, but tag access is direct:
// --- WinCC V7.x C-action ---
DWORD dwVal1, dwVal2, dwVal3;
dwVal1 = GetTagDWord("HMI_DB_Permissive_1");
dwVal2 = GetTagDWord("HMI_DB_Permissive_2");
dwVal3 = GetTagDWord("HMI_DB_Permissive_3");
if (dwVal1 == 1 && dwVal2 == 1 && dwVal3 == 1)
{
SetTagDWord("HMI_DB_All_Permissive_OK", 1);
// ... action body
}
The C functions GetTagDWord, GetTagBit, GetTagFloat and the corresponding SetTag* family are defined in the C-script header apdefap.h shipped with WinCC V7.x. Refer to the Siemens WinCC V7.5 SP2 — C Scripting manual for the complete function reference.
Tag Configuration Checklist
| Property | Recommended Setting | Reason |
|---|---|---|
| Acquisition mode | Cyclic continuous, 1 s (or 500 ms for interlock) | Ensures Read returns current value |
| Acquisition cycle | Equal to or faster than the trigger cycle | Prevents stale reads when trigger fires |
| Update once per second | Disabled | The check box forces 1 s averaging — incompatible with millisecond interlocks |
| Scaling | Linear (PLC-side) | HMI scaling adds latency to the read |
| Quality code | Always valid | Bad-quality tags must be filtered before the AND |
Diagnostics and Verification
Use the WinCC tag logging or the runtime trace to confirm AND-condition behaviour. Add the following lines to the script for one-line tracing during commissioning (remove for production):
' --- commissioning trace, remove before FAT ---
HMIRuntime.Trace Text := "AND-check start, t1=" & t1.Value & _
" t2=" & t2.Value & _
" t3=" & t3.Value & _
" t4=" & t4.Value
Verification procedure on the engineering station:
- Open the WinCC Explorer and start the Graphics Runtime with Tag simulation enabled.
- In WinCC TAGSIM, force each of the N tags to 0 in turn, then to 1, and observe the trace line — the body must not execute until all tags reach 1.
- Verify only one body-execution per positive-going transition by inserting a counter tag incremented inside the critical section.
- Force one tag to 0, then back to 1, with the others already 1, and confirm the body fires exactly once on the 0→1 transition of the last tag.
- Toggle a tag at 10 Hz (using TAGSIM random generator) and verify the action invocation count matches the trigger-tag count, not the body-execution count.
Common Pitfalls
1. Forgetting Read. HMIRuntime.Tags("x").Value returns the last cached value of the tag (or 0 if never read). Calling Read on every tag inside the script is mandatory. The TIA Portal WinCC Professional V17 Runtime manual, section VBScript Object Model > HMIRuntime > Tag object, documents this requirement.
2. Mixing bool/int comparison. Tags imported from a S7-1500 BOOL tag are returned as VT_BOOL, but the Value property coerces to a numeric 0/-1 or 0/1 depending on the HMI build. Use the explicit boolean compare (t.Value = True) or stick to numeric 1 for cross-version safety.
3. Script timeout in RT Professional. TIA Portal WinCC RT Professional enforces a 1 s default timeout on a global action. A 10-tag read with a TCP connection-down state can exceed it. Increase the timeout under Runtime settings > Scripts > Timeout or guard the read with a connectivity check.
4. Trigger on a structure element that is itself an array. When the trigger is a member of a structure (e.g. DB100.Machine[3].Ready), verify the structure is fully expanded in the HMI tag table. A collapsed array element will not generate a change event.
5. Cross-project tag references. In WinCC V7.x, tag triggers are local to the project. A redundant pair (server / standby) must replicate the global action on both projects, with identical trigger tag lists and identical guard logic.
Performance Budget on Comfort Panels and RT Professional
Per the SIMATIC HMI Comfort Panel — Performance manual, a single Read of an internal tag on a Comfort Panel (TP1500, TP2200) takes approximately 0.4–0.8 ms. A 5-tag Pattern 1 guard therefore consumes 2–4 ms of script time, well below the 1 s timeout. On RT Professional (PC-based), the same guard is sub-millisecond. The dominant cost is the script-invocation overhead — typically 1–2 ms on a Comfort Panel — so a 10 Hz trigger storm from a single tag is acceptable but a 100 Hz storm should be debounced at the PLC side or limited by event-driven (rising-edge) trigger configuration.
Version Notes
| WinCC Edition | Minimum Version for This Pattern | Notes |
|---|---|---|
| WinCC V7.4 SP1 | Update 12 | C and VB scripting as documented |
| WinCC V7.5 SP2 | as released | Current LTS-style release |
| WinCC Professional (TIA V16) | V16 Update 7 | HMIRuntime object identical |
| WinCC Professional (TIA V17) | V17 Update 5 | Adds QualityCode property on tag object |
| WinCC Professional (TIA V18/V19) | latest | Unified-style script syntax supported alongside classic |
| Comfort Panel V16/V17/V18 | latest | VBS only; SmartTags also supported |
Refer to the latest TIA Portal WinCC Engineering documentation index for version-specific differences.
Safety-Considerations and SIL Notes
Global actions in WinCC are not safety-rated. The TIA Portal help system explicitly states that HMI-side logic must not be used to implement SIL 2 or SIL 3 functions. Where the AND-condition represents a safety interlock, implement the equivalent logic inside the F-CPU (e.g. in a SIMATIC S7-1500F safety program) and use the HMI action only for status display or operator notification. The HMI action may mirror the safety output but must not derive it.
Why does my WinCC global action fire multiple times for one operator action?
The runtime invokes the action once for every trigger tag that changes value. With 5 trigger tags and a 5-tag burst, the script is called 5 times. Add an idempotency guard (Pattern 2) or convert to an edge-detect latch (Pattern 3) so the body executes exactly once per logical event.
How do I read multiple tags efficiently in a WinCC VBScript global action?
Call HMIRuntime.Tags("Name").Read on every tag whose current value is needed, then access .Value. Without the explicit Read, the value returned is the last cached image and may be stale by up to one acquisition cycle. For 5–10 tags, this is well within the 1 s default script timeout.
Can I use C-Script instead of VBScript for an AND-condition trigger?
Yes. Use the C-script family GetTagDWord / GetTagBit / GetTagFloat and SetTag* to read tags and write results. C-scripts are typically 5–10× faster than VBScript on a Comfort Panel and are the recommended approach for high-frequency or large-tag-count interlocks. See the WinCC V7.5 SP2 C-scripting manual.
What acquisition cycle should I set for the trigger tags?
Set Acquisition mode = Cyclic continuous with a cycle equal to or shorter than the trigger cycle. For interlock logic, 500 ms or 1 s is typical. Do not enable the Update once per second option — it forces a 1 s averaging that defeats the trigger semantics.
Is the same AND pattern available in WinCC Unified (TIA V18+)?
Yes. WinCC Unified uses JavaScript and the equivalent Tags("Name").Read() and .Value accessors on the HMIRuntime object. The pattern — one trigger tag plus checked Read of the others — is identical; only the script syntax differs. Refer to the WinCC Professional V17/V18 documentation for the Unified script API.