Invert a Bit in a WinCC Flexible Array Tag Using Scripts
When configuring a Button event in Siemens WinCC Flexible (the predecessor engineering tool to TIA Portal's WinCC Comfort/Advanced/Unified), the Click -> InvertBit system function will not list an array element. The tag-selection dialog only exposes scalar BOOL tags and the base name of an array, never an indexed element such as Tag_1[3]. This is a hard limitation of the event configuration GUI, not of the runtime. The standard workarounds are (1) declaring a dedicated scalar BOOL tag for every array element you want to toggle, or (2) writing a short VBScript that resolves the array index at click time. This article documents the script approach, the runtime implications of both methods, and the modern equivalent in WinCC Unified's InvertBitInTag system function.
1. Overview of the Problem
WinCC Flexible 2008 SP5 and WinCC (TIA Portal) Comfort/Advanced expose the following built-in system functions on a button's Click event:
SetBitResetBitInvertBit-
SetTag/SetTagBit
Each of these dialogs walks the configured HMI tag list and filters by data type and bit-availability. A BOOL[55] PLC tag (e.g. Tag_1 ARRAY[0..54] OF BOOL in the connected S7-300/400 DB or a STEP 7 / TIA data block) shows up in the dialog as a single multi-element entry. The Bit number field can be set, but the target address is always the start of the array. There is no Element index input, and there is no checkbox to expose a specific element. Result: clicking OK either silently drops the selection or forces you to pick a scalar BOOL tag.
2. Prerequisites
- WinCC Flexible 2008 SP5 (or WinCC Comfort/Advanced V13 SP1 and later) installed on the engineering station.
- An HMI device with VBScript support. Supported panels: all WinCC (TIA) Comfort Panels, WinCC (TIA) RT Advanced, and PC-based WinCC Flexible RT. The basic OP 77B, TP 177B 4" and the OP 73 / TP 177A lines do not support VBScript and require the scalar-tag workaround.
- A connected PLC (S7-300, S7-400, S7-1200, S7-1500, or a third-party controller over OPC) exposing the BOOL array.
- The HMI tag bound to the array must be configured with Length = 55 (or matching the PLC array size) and Data type = Bool array in the tag properties.
- The Global Script runtime option is enabled (default in Comfort Panels and PC RT).
3. Understanding the Tag Configuration
Suppose the S7-1500 contains a data block "MyDB" with a tag of type ARRAY[0..54] OF BOOL named MyFlags. The corresponding HMI tag in WinCC Flexible looks like:
| Property | Value |
|---|---|
| Name (HMI) | dbTest_BooleanArray |
| PLC tag | MyDB.MyFlags |
| Connection | S7-1500 / S7-1200 (or appropriate for controller) |
| Data type | Bool array |
| Length | 55 |
| Acquisition cycle | 100 ms (typical for flags) |
| Update on change | Yes |
The Length field must equal the array dimension in the PLC. WinCC Flexible indexes elements from 0 to Length-1. Internally each BOOL occupies one bit in a packed byte image, but the script layer exposes them as a logical boolean array via the SmartTags() collection.
4. Solution A — VBScript with an Index Parameter (Recommended)
4.1 Create the script
Open the project's Scripts editor (Project tree -> Scripts -> VB Scripts) and add a new function:
Function InvertArrayBit(ByVal idx)
Dim arr
Set arr = SmartTags("dbTest_BooleanArray")
If IsArray(arr) Then
' Read current value, toggle, write back
If arr(idx) = True Then
arr(idx) = False
Else
arr(idx) = True
End If
Else
' Single element fallback (HMI tag of length 1)
If SmartTags("dbTest_BooleanArray") = True Then
SmartTags("dbTest_BooleanArray") = False
Else
SmartTags("dbTest_BooleanArray") = True
End If
End If
End Function
Equivalently, using a one-line boolean NOT:
SmartTags("dbTest_BooleanArray")(idx) = Not SmartTags("dbTest_BooleanArray")(idx)
Not in VBScript performs a bitwise NOT on the 16-bit integer representation. For a BOOL (0 or -1) the result is consistent: Not 0 = -1 (True) and Not -1 = 0 (False). WinCC Flexible's runtime converts these back to the canonical True / False before writing to the tag.4.2 Pass the index
The index can be supplied three different ways. The choice depends on how the button is generated.
| Source | Use case | Code |
|---|---|---|
| Hard-coded constant | One button per array element | InvertArrayBit(3) |
| Internal HMI tag | Index driven by PLC or another screen | InvertArrayBit(SmartTags("iIndex")) |
| Dynamic dialog (event property) | Different index per visible button instance | Use the Tag prefix + Index tag pattern (see Section 6) |
4.3 Wire the script to the button
- Open the screen containing the button.
- Select the button, open Properties -> Events -> Click.
- In the function list choose VB script (not System function).
- Click the ... button to open the script editor; the new function appears in the left tree.
- From the function list, drag
InvertArrayBitinto the right-hand pane. WinCC Flexible automatically generates a call stub. - Replace the placeholder parameter with the desired index expression, for example
3orSmartTags("iIndex"). - Compile the project (Project -> Compiler -> All) and transfer to the panel.
5. Solution B — Scalar Tag per Array Element
For panels that do not run VBScript, the only option is to expose every individual bit as its own HMI tag:
- Add 55 HMI tags of type Bool bound to
MyDB.MyFlags[0]...MyDB.MyFlags[54]. - Use the normal Click -> InvertBit event on each button.
5.1 Cost analysis
Every additional HMI tag consumes a slot in the area pointer image and a polling slot in the configured acquisition cycle. Typical numbers for a Comfort Panel with a 100 ms acquisition cycle:
| Quantity | Effect |
|---|---|
| 1–32 tags | Negligible (< 1 % CPU on a TP900 Comfort). |
| 64–128 tags | Noticeable update lag in tag-status displays if any cycle is missed. |
| 256+ tags | Runtime becomes sluggish; consider increasing the cycle time or splitting screens. |
| 500+ tags | Exceeds the recommended comfort limit; switch to scripts or move the toggling logic into the PLC. |
For 55 elements the scalar approach is feasible on a Comfort Panel, but the project is harder to maintain: a PLC-side array resize requires 55 HMI-side renames. The script approach scales to arrays of any size without configuration churn.
6. Solution C — One Button, Many Indices (Index Tag Pattern)
A common requirement is a single button graphic reused at runtime, with the index changing per screen context. The pattern uses an internal HMI tag iBtnIndex of type Int (-32768 to 32767) that the screen sets before calling the script:
' Pre-event on a focus-change or mouse-hover:
SmartTags("iBtnIndex") = 7 ' element to toggle when the button is clicked
' Click event:
Call InvertArrayBit(SmartTags("iBtnIndex"))
For a dynamic alternative, use the Tag prefix feature: bind a button to a tag whose name itself is constructed from another tag, e.g. "dbTest_BooleanArray_" & SmartTags("iBtnIndex"). This is only available on SetTag / GetTag when the index tag is Static in the project's HMI Tags table; it does not extend the InvertBit system function itself.
7. Modern Alternative: WinCC Unified InvertBitInTag
WinCC Unified (TIA Portal V17 and later, with full coverage of the system function from V20) ships a dedicated runtime function that does accept an element index. The signature is:
InvertBitInTag(Tag, BitNumber)
| Parameter | Type | Description |
|---|---|---|
Tag |
HMI tag | The HMI tag whose bit is to be inverted. May be of integer or bit-array type. |
BitNumber |
Int | Zero-based bit number within the tag value. |
Behaviour: if the bit is currently 1 (True) it is set to 0 (False), and vice versa. The function returns Void. A complete reference is at the Siemens TIA Portal Help: InvertBitInTag (RT Unified, V20) page.
7.1 Example: Unified button configuration
- Open the screen, select the button.
- Open Properties -> Events -> Click.
- Add a new system function: InvertBitInTag.
- Tag: select the integer or bool-array HMI tag.
- BitNumber: either a literal (e.g.
3) or a tag reference (e.g.HMI_Tag_1). - Compile and download. No VBScript is required.
This is the recommended path for new projects on Unified Comfort Panels (MTP700/1000/1200/1500/1900) and Unified PC RT. Existing WinCC Flexible projects that cannot be migrated to TIA Portal should continue to use the VBScript workaround from Section 4.
8. Performance and Runtime Considerations
8.1 Script execution latency
On a TP900 Comfort, a VBScript that performs one read + one write of a single array element completes in 1–3 ms. For 55 buttons on a single screen the combined script overhead is therefore in the order of 60–150 ms, well under one acquisition cycle. The bottleneck is normally the PLC read phase, not the script itself.
8.2 Are the writes acknowledged?
WinCC Flexible returns immediately after issuing the write request. The actual write to the PLC may complete on a later cycle (typically within 50–200 ms for an S7-1500 over PROFINET). If the script is part of a click animation, do not assume the value is visible in a neighbouring IO field on the same frame.
8.3 Polling vs. event-driven updates
When the script writes the array element, the panel triggers a write job for the entire BOOL array. The PLC does not need to be polled for that array to be up to date. If you also read the same element from the same screen, configure the array tag with Update on change = Yes to minimize cycle time.
8.4 Mixing scripts and system functions
You may freely mix the InvertBit system function on scalar BOOL tags with a VBScript on array elements inside the same project. They share the same global SmartTags collection and the same area pointers.
9. Step-by-Step Verification
After the project has been compiled and downloaded, perform the following checks before declaring the screen production-ready.
-
Static check: In the engineering environment, select the button and verify that Properties -> Events -> Click shows a script call to
InvertArrayBitwith a valid integer argument. Recompile if the field is empty. - Tag list audit: In Project -> HMI Tags, confirm that the array tag has Length = 55 and Data type = Bool array. A mismatch silently truncates the index and may produce out-of-bound writes to neighbouring PLC memory.
-
Live read: In the runtime, place an IO field bound to
dbTest_BooleanArray[5]next to the button. Click the button and confirm the IO field flips state within one acquisition cycle (default 100 ms). -
PLC cross-check: In TIA Portal, open the PLC online view, navigate to
MyDB.MyFlags[5], and confirm the bit toggles in lockstep with the HMI display. Any delay greater than ~500 ms points to a saturated PROFINET line or an oversized acquisition cycle. -
Boundary test: Click the button bound to index 0 and the button bound to index 54. Confirm both write. A common bug is a copy-paste that leaves the index at
SmartTags("iIndex")with no initialization, in which caseiIndexreads 0 by default and only the first element ever toggles.
10. Troubleshooting Matrix
| Symptom | Likely cause | Resolution |
|---|---|---|
| Button click does nothing | Script not bound to the Click event; or script runtime disabled. | Re-open event configuration, re-add the function. On PC RT, ensure HmiRT.exe /script /enable is set in the startup list. |
| Runtime warning Index out of range | Index tag exceeds array length - 1. | Clamp the index with If idx > 54 Then idx = 54 at the top of the function. |
| Only element 0 toggles | Index tag not initialised, or literal 0 hard-coded by mistake. |
Pre-event must write the index before the click. Verify with the online tag inspector. |
| Write succeeds but PLC value does not change | Area pointer disabled; wrong DB number; write protection on the data block. | |
| HMI sluggish after adding 30+ script buttons | Per-click VBScript overhead plus 100 ms acquisition cycle | Increase acquisition cycle to 200 ms on non-critical screens, or move toggle logic into the PLC and use a single set/reset bit on the HMI side. |
| Element appears stuck in the HMI IO field but updates in the PLC | Update on change = No; cycle too slow | Enable Update on change on the array tag and force a manual refresh of the IO field with UpdateTag. |
| Script runs on panel but errors on PC RT | Case-sensitive SmartTags collection; trailing semicolons in VBScript |
Use exactly SmartTags("..."). VBScript is case-insensitive in identifiers but not in string literals. |
11. Migration Notes: WinCC Flexible → TIA Portal Unified
Projects upgraded from WinCC Flexible 2008 to TIA Portal V15 and later gain two new options:
- On a Comfort Panel running Comfort/Advanced firmware, the script approach from Section 4 continues to work without modification.
- If the target panel is a Unified Comfort Panel (MTP series), convert the script to the
InvertBitInTagsystem function (Section 7) for a 5–10× improvement in click-to-update latency and a smaller project binary.
During migration, the array length is auto-detected from the PLC tag, so a previous manual Length setting is replaced by the bound DB element count. Verify the resulting Length matches the array dimension before recompiling.
Why does the InvertBit system function refuse my BOOL array tag?
WinCC Flexible's InvertBit dialog binds the bit address at compile time. Because the GUI cannot express a runtime index, the address resolution step rejects any array-typed tag. The runtime has no such restriction, which is why a VBScript that resolves the index at runtime works fine.
Is there a way to avoid writing a VBScript at all?
On panels without VBScript support (TP 177B 4", OP 77B), declare one scalar BOOL HMI tag per array element and use the normal Click -> InvertBit event. The trade-off is more tag configuration and a heavier project. On WinCC Unified panels, the new InvertBitInTag system function handles arrays directly.
Can I use C-script instead of VBScript?
Yes. The C-syntax equivalent is BOOL b = GetTagBit("dbTest_BooleanArray", idx); SetTagBit("dbTest_BooleanArray", idx, !b);. C-scripts run faster than VBScripts on Comfort Panels and are recommended for high-frequency toggles (more than ~5 per second).
What happens if the index is outside the array bounds?
The runtime raises a Tag out of range warning in the diagnostic viewer and aborts the write. On PC RT the script reports Subscript out of range. Always validate the index with a If idx < 0 Or idx > 54 Then Exit Function guard.
Does toggling a bit from the HMI also trigger the PLC's edge evaluation?
Yes. WinCC Flexible writes the new BOOL value to the PLC, so any rising/falling edge blocks downstream in the PLC see the transition normally. If the PLC is the master for that bit (e.g. an HMI-driven set with a PLC reset), the HMI write is treated as a regular operator input.