Dynamically Assign Tags to WinCC I/O Fields on Button Click

David Krause16 min read
HMI ProgrammingSiemensTutorial / 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

A static tag binding in a WinCC I/O field is set once in the screen editor and cannot be re-pointed at runtime through the Properties dialog. To swap the underlying PLC tag (or HMI internal tag) that an I/O field reads or writes when an operator presses a button, you must wire the swap explicitly through one of the runtime-side mechanisms exposed by the HMI: a direct connection in the button's mouse event, a VBScript / C-Script handler, or — on WinCC Unified (TIA Portal V20) — a script dynamization on the I/O field's Process value property. Each method has different authoring cost, runtime cost, and scope (single screen vs. faceplate reuse). This reference walks through all three, including complete VBScript and JavaScript snippets, a faceplate multi-instance technique for swapping pump/motor tags from a single screen, and a verification matrix for the most common commissioning defects.

Prerequisites

  • SIMATIC WinCC V7.x SP3 or later (V7.4 SP1 or V7.5 SP2 recommended), OR WinCC Comfort/Advanced V15.1 or later, OR WinCC Unified V17 / V20 in TIA Portal.
  • Configured HMI connection to a SIMATIC S7-1500 / S7-1200 / S7-300/400 PLC (PROFINET or PROFIBUS), or a stand-alone runtime using internal tags only.
  • Two or more HMI tags of the same data type (e.g. Tag_Motor1_Speed and Tag_Motor2_Speed, both REAL) accessible from the screen where the I/O field is placed.
  • For faceplate reuse: a WinCC faceplate type with one or more tag interface properties exposed as interface tags.
  • WinCC Explorer / TIA Portal project with the screen compiled successfully (no compile errors) before testing the dynamic assignment.
  • Panel firmware supporting the chosen method: Comfort Panels (TP700–TP2200) support VBScript and direct connections; WinCC Unified Comfort Panels (MTP700–MTP2200) require the Unified dynamization pattern.
Authoring tip: Compile and download a baseline project to the runtime before adding any dynamic logic. A screen that fails to compile will mask the dynamic binding in the runtime, making it look as if the swap "doesn't work" when the underlying problem is a syntax or namespace error from the previous build.

Architecture: Why Static Binding Is Not Enough

In every WinCC generation, an I/O field's Output value (display) and Input value (operator entry) properties are statically linked to a single tag in the screen editor. The runtime does not re-evaluate this binding when a button is pressed — the link is fixed for the life of the screen instance. To re-point the I/O field, the authoring environment must reach into the I/O field's Output value / Input value property at runtime through one of three exposed extensibility points:

  1. Direct connection on the triggering object's mouse event — writes a constant, a tag, or an expression to a target object's property. Available in WinCC V7 and WinCC Flexible.
  2. VBScript or C-Script handler on the mouse event — uses the WinCC runtime object model (HMIRuntime, ScreenItems, Tags) to write to the target I/O field's OutputValue / InputValue properties directly.
  3. Script dynamization on the I/O field's Process value property in WinCC Unified — a script or expression under Properties > General > Process value that is re-evaluated on every acquisition cycle, allowing the binding to swing between two or more tags based on a control tag.
Runtime State — I/O Field Tag Binding on Button Click Initial IOField = Tag_Placeholder Bound to Motor1 IOField = Tag_Motor1_Speed OutputValue set by handler Bound to Motor2 IOField = Tag_Motor2_Speed OutputValue set by handler Click Btn_Motor1 Click Btn_Motor2 Toggle

Method 1 — Direct Connection (WinCC V7 / WinCC Flexible)

The direct-connection method requires no scripting and is the fastest path to a working dynamic tag assignment. It is limited to writing a single source value (a constant or a tag) to a single target property on a single event, which is exactly what a button-click swap needs.

  1. In the screen editor, place the I/O field and rename it (e.g. IOField_Speed) so it can be addressed by name.
  2. Open Properties > Output/Input > Output value and bind it to a placeholder tag (e.g. Tag_CurrentSpeed) so the screen compiles. The runtime binding is what matters; the static value here is overwritten on the first click.
  3. Insert the first button (e.g. Btn_Motor1). Open Properties > Events > Mouse > Mouse Action (Press).
  4. In the Direct Connection dialog, configure:
    • Source: TagTag_Motor1_Speed (or, for a write-back, a constant value).
    • Target: Object on screenIOField_Speed → property Output value.
  5. Repeat for the second button (Btn_Motor2), pointing its source at Tag_Motor2_Speed and its target at the same I/O field's Output value.
  6. Compile and download. Pressing Btn_Motor1 now swaps the I/O field to display Tag_Motor1_Speed; pressing Btn_Motor2 swaps it to Tag_Motor2_Speed.
Visual cue: Once a direct connection writes to an I/O field's Output value, the property in the Properties window renders in bold. Bold indicates a property that is no longer statically owned by the screen and is being driven by a runtime event. This is the fastest way to confirm the wiring is correct before pressing the button — see the official WinCC V7 documentation for the bold-property convention.

Method 2 — VBScript (WinCC V7 / WinCC Comfort/Advanced)

VBScript gives full programmatic control. The same two-button, one-I/O-field scenario becomes a 6-line handler, and the same handler can drive dozens of fields from a single click — useful when a "faceplate" screen must re-bind every property to a new instance's tag set in one go.

VBScript — two-button swap

' --- OnClick of Btn_Motor1 ---
Dim objIO
Set objIO = ScreenItems("IOField_Speed")
objIO.OutputValue = SmartTags("Tag_Motor1_Speed")
objIO.InputValue  = SmartTags("Tag_Motor1_Speed")
' (the I/O field name in quotes is case-sensitive in WinCC V7 RT)
' --- OnClick of Btn_Motor2 ---
Dim objIO
Set objIO = ScreenItems("IOField_Speed")
objIO.OutputValue = SmartTags("Tag_Motor2_Speed")
objIO.InputValue  = SmartTags("Tag_Motor2_Speed")

VBScript — re-binding every field on a faceplate screen

' --- OnClick of Btn_SelectInstance ---
' Prefix-based instance switching. Both motors expose
' tags named "Motor_Speed", "Motor_Current", "Motor_Voltage"...
' The HMI tag prefix "Tag_PumpA_" / "Tag_PumpB_" determines the
' data source. We walk the screen items and reassign by name.
Dim sPrefix, sOldPrefix, oItem, sName
sOldPrefix = SmartTags("Tag_ActivePrefix")   ' e.g. "Tag_PumpA_"
sPrefix    = SmartTags("Tag_NewPrefix")      ' e.g. "Tag_PumpB_"

For Each oItem In ScreenItems
    sName = oItem.Name
    If Left(sName, 5) = "IOFld" Then
        ' IOFld_Speed, IOFld_Current, IOFld_Voltage
        Dim sField : sField = Mid(sName, 6)   ' "Speed"
        oItem.OutputValue = SmartTags(sPrefix & sField)
        oItem.InputValue  = SmartTags(sPrefix & sField)
    End If
Next
SmartTags("Tag_ActivePrefix") = sPrefix
Tag prefix pattern: Author the PLC program so that every motor instance exposes tags with the same suffix (Speed, Current, Voltage, State...). A single WinCC HMI tag prefix (Tag_PumpA_, Tag_PumpB_) is then swapped on button click, and the VBScript loop reassigns all I/O fields in one frame. This is the classic pre-faceplate technique for one-picture-many-pump faceplates.

Method 3 — C-Script Variant (WinCC V7 RT)

On older WinCC V7 projects where VBScript is disabled (a project-level setting under Computer Properties > Runtime > Scripts) or unavailable on the panel firmware, the equivalent C action is:

/* --- OnClick of Btn_Motor1 (C action) --- */
{
    SetOutputValueDouble(lpszPictureName, "IOField_Speed",
                         GetTagFloat("Tag_Motor1_Speed"));
    /* if the I/O field is configured as Output/Input, also write back: */
    SetTagFloat("Tag_Motor1_Speed",
                GetOutputValueDouble(lpszPictureName, "IOField_Speed"));
}

C actions run in the C interpreter compiled with the project. They are faster than VBScript for high-cycle use but slower to author and harder to debug; the direct-connection method is recommended unless the swap must occur on a high-frequency trigger (e.g. every 100 ms poll). Note that WinCC Comfort Panels do not support C-Script — use VBScript or direct connections on those panels.

Method 4 — WinCC Unified (TIA Portal V20) Script Dynamization

WinCC Unified exposes the I/O field's Process value as a scriptable property in the Inspector. The dynamization column in the Properties window accepts a tag, an expression, or a script that is re-evaluated on every acquisition cycle. The runtime architecture is different: the I/O field is no longer just an "object with a property"; it is a control bound to a dynamization pipeline that the Unified runtime evaluates on every poll. The I/O field can be created by dragging a configured tag from the detail view onto the screen using drag-and-drop; an I/O field is created and linked to the tag, as documented in the official IO field (RT Unified) reference for TIA Portal V20.

  1. Place the I/O field on the Unified screen. It is auto-bound to the tag you dragged from the detail view; rename the field to IOField_Speed.
  2. Open the Inspector window → Properties > General > Process value. In the Dynamization column, click the entry and select Tag from the list.
  3. Bind the Process value to a control tag — typically a STRING or an INT index that the runtime evaluates to choose which underlying tag to forward.
  4. In the script attached to the Process value property, return the value from the currently selected source tag. Example (JavaScript, the native Unified scripting language):
    // Process value READ script of IOField_Speed
    let iSel = Tags("Tag_ActiveMotor").Read();   // 1 or 2
    if (iSel === 1) {
        return Tags("Tag_Motor1_Speed").Read();
    } else if (iSel === 2) {
        return Tags("Tag_Motor2_Speed").Read();
    }
    return 0;
    
  5. Wire the button click events to set Tag_ActiveMotor to 1 or 2. The I/O field updates within the next acquisition cycle without any imperative OutputValue = assignment.

For write-back, add a second script to the Process value write path that dispatches the operator's entry to the active instance:

// Process value WRITE script of IOField_Speed
let iSel = Tags("Tag_ActiveMotor").Read();
let v    = Item.Value;   // operator-entered value
if (iSel === 1) {
    Tags("Tag_Motor1_Speed").Write(v);
} else if (iSel === 2) {
    Tags("Tag_Motor2_Speed").Write(v);
}

Refer to the official example in the TIA Portal V20 docs: Example: Configuring an IO field (RT Unified).

Method 5 — Faceplate Instance Tag Swap (Multi-Instance Reuse)

For a true faceplate (WinCC V7 faceplates, or Unified faceplate types in TIA Portal), the cleanest "one picture, many instances" pattern is to expose a tag interface on the faceplate type and re-instantiate it with a different instance name from the calling screen. There is no runtime tag swap — the faceplate is destroyed and re-instantiated with a new tag container.

  1. In the faceplate type, define an interface tag container (e.g. FP_Instance) holding the standard set of tags (Speed, Current, Voltage, State).
  2. Each instance of the faceplate on the calling screen is bound to a different instance DB in the PLC (e.g. IDB_Motor1, IDB_Motor2).
  3. On button click, use the WinCC V7 SetPropChar / SetPropWord family of functions, or in Unified the faceplate container's Properties API, to set the instance pointer on the host screen's faceplate placeholder.
  4. The faceplate re-loads with the new instance's data on the next cycle.
When to use faceplates vs. swap-on-click: If the operator can change the active motor 5+ times per minute, use the direct-connection or VBScript swap. If the active motor changes a few times per shift (e.g. on a multi-pump skid where only one pump is being commissioned at a time), use a true faceplate with instance re-binding. Faceplate re-instantiation is heavier (50–200 ms load time per swap on a Comfort Panel) and not suitable for rapid operator switching.

Internal vs. External Tags in Dynamic Assignment

The dynamic tag swap can target either an HMI internal tag (resident only in the panel's memory) or an HMI external tag (mapped to a PLC address via the connection). Mixing the two is a common commissioning defect:

Tag type Where it lives Survives restart Use case for swap Common mistake
Internal HMI tag Panel RAM No (volatile unless marked retentive) Mode-switch / instance-select Bound to a PLC address — internal tags must NOT be linked to a controller
External HMI tag PLC address (mapped at connection level) Yes (backed by PLC) Live process value Trying to re-point to a non-existent PLC address at runtime
Script-internal variable Within a single VBScript handler No Loop counters, name strings Expecting the variable to persist between events

Use an internal HMI tag as the "active instance pointer" (e.g. Tag_ActiveMotor as an INT, or Tag_ActivePrefix as a STRING). Use external HMI tags as the live data carriers. The runtime only allows the swap to point at tags that have been declared in the HMI tag table — it cannot resolve a name that exists only in the PLC.

Parameter Table — Configuration Items by Method

Item Direct Connection (V7) VBScript (V7 / Comfort) C-Script (V7) WinCC Unified (V20) Faceplate Instance
Trigger event Mouse click Mouse click Mouse click or tag trigger Tag change / acquisition cycle Instance rebind
Object addressed by Name (point-and-click) ScreenItems("Name") lpszPictureName, "Name" Tag name in script Instance name
Authoring complexity Low Low–Medium Medium Medium High (initial)
Runtime cost per swap 1 PLC poll cycle ~1–5 ms <1 ms 1 acquisition cycle (default 1 s) 50–200 ms
Write-back supported Yes (separate direct conn.) Yes (InputValue) Yes (SetOutputValueDouble) Yes (process value write script) Yes (faceplate interface)
Reusable across screens No (per-screen wiring) Yes (central VB module) Yes (central C include) Yes (central JS module) Yes (one faceplate type)
Comfort Panel support Yes Yes No Yes (Unified Comfort) Yes

Verification and Commissioning Steps

  1. Compile the project (TIA Portal: Project > Compile > Software (rebuild all); WinCC V7: Tools > Compiler > Compile OS). Resolve all errors before continuing.
  2. Start the runtime simulator (TIA Portal: Start simulation; WinCC V7: Start Runtime) and confirm the screen opens without an "object not found" alarm.
  3. Confirm the I/O field's Output value property appears in bold in the Graphics Designer — this is the visual confirmation that the direct connection / script is wired.
  4. In the runtime, press Btn_Motor1; verify the value changes to the value of Tag_Motor1_Speed within 1–2 acquisition cycles.
  5. Press Btn_Motor2; verify the same I/O field now displays Tag_Motor2_Speed.
  6. Edit the I/O field's display-only mode: in Miscellaneous > Display, set it to No on the placeholder configuration. The I/O field will only show the swapped value, not the placeholder text.
  7. Write a value into the I/O field when bound to Tag_Motor1_Speed; switch to Btn_Motor2; verify that Tag_Motor1_Speed retained the written value (write-back) and that Tag_Motor2_Speed is now displayed.
  8. Cycle the HMI runtime (Stop > Start) and confirm the last-selected source remains bound if you stored the active-instance pointer in a retentive internal tag, or reverts to the default if non-retentive.
  9. For Unified, also check the Quality indicator on the I/O field — "Bad" quality means the script referenced a tag that does not exist in the HMI tag table.

Troubleshooting Matrix

Symptom Likely cause Fix
I/O field value never changes on click Button event is bound to Mouse Down, not Mouse Action (Press) Re-bind the script / direct connection to the standard Press event
"Object not found: IOField_Speed" in RT alarm log I/O field name mismatch (case-sensitive in RT) Verify the name in Graphics Designer matches the string in ScreenItems()
Bold property disappears after recompile Static binding reasserted by editor Re-author the direct connection / script after each compile cycle
Value updates but does not write back Only OutputValue is set in the handler Set InputValue as well, or use a faceplate interface for round-trip
Tag prefix pattern returns wrong value Tag name does not actually exist in HMI tag table Confirm Tag_PumpB_Speed exists; WinCC RT cannot resolve tags that exist only in the PLC
Direct connection disabled (greyed out) Project-level setting has direct connections disabled WinCC V7: Computer Properties > Runtime > Active — enable direct connections
VBScript runs but value flickers between two tags Two scripts are firing (e.g. one on click, one on tag change) Disable redundant handlers; use a single source of truth for the active-instance pointer
Unified I/O field does not refresh after script change Acquisition cycle too slow for the tag Reduce the tag's acquisition cycle (default 1 s; try 100 ms)
"Quality: Bad" on the I/O field in Unified Source tag is not connected / PLC not reachable Check the HMI connection in Devices & Networks and confirm the PLC is online
Operator entry routes to wrong instance after swap Write-back script missing or refers to old pointer Add Process value write script (Unified) or InputValue assignment (V7 VBScript) for the new active instance

Best Practices and Field-Proven Caveats

  • Prefer the direct-connection method for simple two-tag swaps. It survives project upgrades, doesn't depend on the script interpreter version, and is self-documenting in the Properties window (the bold property).
  • Use VBScript only when the swap must be programmatic — e.g. you have 20+ fields that need to swap in one click, or the new tag name is computed at runtime from a string prefix.
  • In WinCC Unified, prefer the script-based dynamization over the legacy faceplate-rebind pattern. The acquisition-cycle-based re-evaluation is faster and survives faceplate container renames.
  • Always name the I/O field explicitly. WinCC auto-generates names like IOField_1; renaming to a functional name (IOField_Speed) makes the script, the direct connection, and the cross-reference in TIA Portal all readable.
  • Test write-back separately from read. The most common defect in a swap is that the display updates but the operator's entry is routed to the wrong instance. Verify with two distinct write tests on each button.
  • Audit the bold properties before each FAT. Any I/O field with a non-bold Output value after a swap wiring exercise means the direct connection / script was not saved into the compiled project.
  • On Comfort Panels, the script interpreter is VBScript only — no C-Script. For WinCC Comfort/Advanced, skip Method 3 entirely.
  • For Unified projects, the legacy direct connection does not exist. Use the Process value dynamization (Method 4) per the TIA Portal V20 documentation.
  • Mind the tag-prefix collision in WinCC V7. If two tags have similar names (e.g. Tag_Motor_Speed and Tag_MotorBackup_Speed), Left(sName, 5) = "IOFld" in the VBScript loop will match them both. Add an explicit suffix-length check or use a delimiter like IOFld_Speed / IOFld_Current with an exact-name dictionary instead of a string match.
  • Keep the active-instance pointer tag retentive only if the operator expects the last selection to survive a power cycle. Marking it retentive in the HMI tag table will preserve the last active motor across reboots; the PLC startup will see a "stale" selection until the first cycle, so coordinate with the PLC program.

FAQ

Can I assign two different tags to a single WinCC I/O field and switch between them at runtime?

Yes. In WinCC V7, use a direct connection on each button's Mouse Action (Press) event with the I/O field as the target object and the tag as the source. In WinCC Unified (TIA Portal V20), use a script on the I/O field's Process value property that returns the value of the active tag based on a control tag. See Methods 1 and 4 above for full code and step-by-step.

How do I re-bind all I/O fields in a faceplate screen to a different pump instance?

Use the tag-prefix pattern: configure the PLC so each pump exposes tags with the same suffix (Speed, Current, Voltage...). Author a single VBScript on the selection button that loops over the screen items and reassigns each I/O field's OutputValue and InputValue to Tag_PumpN_Suffix. This is the standard pre-faceplate technique for one-picture-many-pump HMI screens.

Why does my I/O field's Output value property appear in bold after I wire a direct connection?

Bold in the WinCC Properties window indicates that the property is being driven at runtime by an event (direct connection, VBScript, or C-Script) and is no longer statically owned by the screen editor. This is the correct state for a dynamic-tag-assignment configuration and is your visual confirmation that the swap will work in runtime.

Does the dynamic tag assignment work on a Comfort Panel with WinCC Comfort V15.1?

Yes. Comfort Panels support VBScript on button events and the direct-connection method. They do not support C-Script. For Unified Comfort Panels (MTP/Comfort Unified), use the Process value script dynamization on the I/O field per the TIA Portal V20 documentation.

Can the operator's entry in the swapped I/O field be written back to the correct PLC tag?

Yes. In WinCC V7, set both OutputValue (read) and InputValue (write) of the I/O field in the VBScript handler, or add a second direct connection per button pointing at the Input value property. In WinCC Unified, attach a write-path script to the I/O field's Process value that dispatches Tags("Tag_MotorN_Speed").Write(value) based on the active-instance pointer.

Back to blog