1. Overview: Why Screen-Bound Updates Fail in WinCC
WinCC V6/V7 (and the modern TIA Portal variant WinCC Unified) handle tag updates through a layer that is intrinsically tied to the picture (screen) lifecycle. When a developer binds an Output or Input/Output field on a picture to a tag, the field is registered as a picture-internal event consumer. The runtime update path is then scheduled by the picture window manager. As soon as the picture is unloaded, all consumers on that picture are de-registered, and any read/write or transfer actions attached to those controls stop being executed.
This behaviour causes a classic failure mode when WinCC is used as a gateway between an upstream data source (e.g. a third-party OPC DA/UA server polling counters on a machine) and a downstream controller (an S7-400 PLC that monitors the production line). While the operator happens to be viewing the picture that contains the I/O fields, the transfer runs. The moment the operator navigates away to a process overview, alarm page, or any other picture, the data flow halts silently. The OPC tags continue to update internally, but no value is written to the S7-400.
The solution is to decouple the data transfer from the picture layer. Three options exist:
- Global Script actions (VBS or ANSI-C) scheduled by the WinCC runtime scheduler, independent of any picture.
- TagLogging archive configuration, which keeps the runtime polling the tag continuously as a side effect of archiving.
- WinCC Unified UpdateTag system function with an explicit Update ID, which forces a one-shot update of the tag and any tag bound to it.
This article focuses on the classic WinCC V6/V7 environment (VBS Global Actions, C Global Actions, TagLogging Editor) and adds the WinCC Unified equivalent at the end for migration projects.
2. Prerequisites
| Item | Requirement |
|---|---|
| Engineering station | WinCC Explorer V6.2 SP3 / V7.0 SP3 / V7.4 SP1 or later with WinCC Configuration Studio |
| Runtime licence | WinCC RT 2,048 / 8,192 / 64,512 PowerTags as appropriate; VBS Action licence (RT 128 / 256 / 512 / 1,024 / 2,048 / 4,096) is required to execute Global VBS Actions |
| Data source | OPC DA server (e.g. SIMATIC NET OPC, third-party) configured as a WinCC channel and connected to the OPC runtime |
| PLC | S7-400 (CPU 41x / 416 / 417) with an ISO-on-TCP (RFC1006) or TCP connection; HMI tags bound to PLC DBs/Merkers via the SIMATIC S7 Protocol Suite |
| Network | Ethernet between WinCC server, OPC server(s) and S7-400 CPU(s); recommended 100 Mbps or higher, switched |
| Authorisation | Local administrator on the WinCC server (the Global Script editor and TagLogging editor require it) |
3. The Wrong Pattern: Picture-Local VBS on I/O Field Events
Developers coming from WinCC flexible often try the following pattern, which is the root cause of the reported failure:
' Picture-local VBS, attached to the "OnChange" event of an I/O field
Dim srcValue
srcValue = HMIRuntime.Tags("OPC_Counter_01").Read
HMIRuntime.Tags("PLC_DB100_DBD0").Write srcValue
This script executes only when the I/O field is instantiated, that is, while the picture that hosts it is open and visible. Once the operator navigates to a different picture, the I/O field is destroyed, the OnChange subscription is removed, and the script never fires again. The PLC tag simply stops being updated.
The picture-local layer cannot be promoted to "background" in WinCC V7. It is always bound to a picture. Therefore, the transfer logic must be moved out of the picture scope and into the project scope.
4. Solution A - Global VBS Action on a Timer
4.1 Open the Global Script Editor
In the WinCC Explorer, right-click the project node and choose Global Script > C or VBScript Editor. Switch to the VBScript view using the toolbar dropdown. The left-hand tree groups scripts into Project Modules (subroutines and functions callable from any picture) and Actions (scheduled procedures).
4.2 Write the Transfer Subroutine in a Project Module
Create a new module (e.g. mod_OPC_To_PLC.bas) and add a public procedure. Using project modules keeps the logic reusable and unit-testable.
' mod_OPC_To_PLC.bas - project module, project scope
Option Explicit
Public Sub Transfer_OPC_To_PLC()
Dim tSrc, tDst
Set tSrc = HMIRuntime.Tags("OPC_Counter_01")
Set tDst = HMIRuntime.Tags("PLC_DB100_DBD0")
tSrc.Read
If tSrc.LastError = 0 Then
tDst.Value = tSrc.Value
tDst.Write
End If
End Sub
Public Sub Transfer_All()
Transfer_OPC_To_PLC
End Sub
HMIRuntime.Tags(...).Read populates .Value only when the read succeeds. Always inspect LastError (0 = success) before writing downstream, or stale data will be propagated.4.3 Create the Scheduled Action
In the VBS Action tree, create a new action (e.g. act_PollOPC_5s) and add a single call to your project module routine. Then set the trigger:
- Open the action's properties (right-click > Properties or use the Info/Properties dialog).
- In the Trigger tab, click Add and select Timer.
- Choose the trigger interval. For a 5-10 s poll cadence as described in the source, set the cycle to
00:00:05(5 seconds) or00:00:10(10 seconds). - Confirm that Start in Runtime is enabled and the trigger type is Cyclic (not Once).
The action body looks like this:
' act_PollOPC_5s.vbs - global action, cyclic 5 s
Transfer_All
4.4 Batch-Transfer Pattern (Recommended for Many Tags)
For more than a handful of tags, perform one OPC read round-trip and one PLC write round-trip per cycle to minimise network chatter and reduce WinCC tag acquisition latency:
Public Sub Transfer_All()
Dim tags
tags = Array("OPC_Counter_01", "OPC_Counter_02", "OPC_Counter_03", _
"OPC_Status_Word_1", "OPC_Speed_Actual")
Dim dstTags
dstTags = Array("PLC_DB100_DBD0", "PLC_DB100_DBD4", "PLC_DB100_DBD8", _
"PLC_DB100_DBW12", "PLC_DB100_DBD14")
Dim i, src, dst
For i = LBound(tags) To UBound(tags)
Set src = HMIRuntime.Tags(tags(i))
Set dst = HMIRuntime.Tags(dstTags(i))
src.Read
If src.LastError = 0 Then
dst.Value = src.Value
End If
Next i
' single consolidated write cycle
For i = LBound(dstTags) To UBound(dstTags)
HMIRuntime.Tags(dstTags(i)).Write
Next i
End Sub
The single write loop benefits from the WinCC runtime's tag-acquisition batching: the data manager flushes all pending writes during the next acquisition cycle (default 250 ms), which is significantly more efficient than one read+write per tag inside a tight loop.
5. Solution B - Global ANSI-C Action on a Timer
If the project is on an older build where C is the dominant scripting language, the same logic is implemented as follows:
// act_PollOPC_5s.c - global C action, cyclic 5 s
#include "apdefap.h"
int gscAction(void)
{
DWORD dwValue;
float fValue;
if (GetTagDWord("OPC_Counter_01", &dwValue) == 0)
SetTagDWord("PLC_DB100_DBD0", dwValue);
if (GetTagFloat("OPC_Speed_Actual", &fValue) == 0)
SetTagFloat("PLC_DB100_DBD14", fValue);
return 0;
}
C actions are slightly faster than VBS but lose the COM-based flexibility of HMIRuntime.Tags(...). The trigger setup (5 s cyclic) is identical to the VBS path.
6. Solution C - TagLogging as a Side-Effect Polling Mechanism
Configuring a tag inside the TagLogging Editor is an alternative that some engineers prefer because it does not require writing any script. The WinCC runtime will poll the tag on its configured acquisition cycle as a side effect of the archive subscription, keeping the value "warm" and ready for any read or write.
- Open the TagLogging editor from the WinCC Explorer tree.
- Create a new archive (e.g. ProcessValuesArchive) of type Process Value Archive.
- Add the OPC tags you want to keep warm as archive tags. Set Acquisition to Cyclic and the cycle to your polling interval (5 s or 10 s).
- Optionally add a Compression rule if you also want long-term history.
- Activate the project.
7. Solution D - WinCC Unified UpdateTag (TIA Portal V17+)
For new builds on TIA Portal V17 or later with WinCC Unified (or Comfort/Advanced panels), the runtime is built on a different stack. By default, an internal tag in WinCC Unified is not updated continuously; updates are on demand. To force a periodic refresh you use the UpdateTag system function with an explicit Update ID.
- In the HMI Tags editor, open the Update ID column on the OPC/internal tag that you want refreshed.
- Assign a numeric Update ID (e.g.
1) to every tag that should be updated in the same batch. - From a scheduler (VBScript/JavaScript scheduled task on the Unified RT, or a PLC-triggered tag), call
Tags.SysFct.UpdateTag(1). The runtime refreshes all tags with Update ID = 1 in a single operation.
Documentation reference: Updating the tag value in runtime (RT Unified) and Job 46: Update tag - WinCC Unified.
A typical scheduled task in Unified looks like this (JavaScript, scheduled at 5 s cyclic):
// Scheduled task, 5 s cyclic
Tags.SysFct.UpdateTag(1);
This pattern is the conceptual equivalent of the V7 VBS Global Action, but it uses an explicit ID-based dispatch instead of a free-form script body. The Update ID column lives next to the tag name in the HMI Tags table of TIA Portal; in WinCC Comfort/Advanced the same field is exposed as Update ID in the tag properties.
8. Comparison of the Four Approaches
| Criterion | VBS Global Action | C Global Action | TagLogging | Unified UpdateTag |
|---|---|---|---|---|
| Platform | WinCC V6.2 / V7.x | WinCC V6.2 / V7.x | WinCC V6.2 / V7.x | TIA Portal V17+, WinCC Unified / Comfort / Advanced |
| Polling cycle | Any (typical 1-10 s) | Any (typical 1-10 s) | Bound to acquisition cycle of archive tag | Any, scheduled externally |
| Licence cost | VBS Action option (PowerTag count) | C Action option (PowerTag count) | Archive tag licence (per tag/cycle) | RT Unified tags |
| History | No | No | Yes (built-in) | No (use Logging tags separately) |
| Code location | Global Script > VBS Actions | Global Script > C Actions | TagLogging editor (no code) | Scripts > Scheduled Tasks |
| Read error handling | Check LastError
|
Check return value (0 = OK) | Quality code in archive | Check Tags(tag).Quality
|
| Best for | Gateway / transfer use cases | High-volume, latency-sensitive polling | Polling + history with no scripting | Modern Unified projects |
9. Verification Procedure
- Open the WinCC project on the engineering station and start WinCC Runtime from the Explorer.
- Confirm the VBS Action shows a green icon in the Global Script editor status bar (red = compilation error).
- Open the Diagnostics tool in the WinCC Explorer (Tools > Diagnostics). Activate the Connections view and confirm both OPC channels and the SIMATIC S7 Protocol Suite channel report OK.
- Use Tools > Tag Simulation or the Gdiag tool to set a known value into the source OPC tag. With the source picture closed, monitor the destination PLC tag in the WinCC tag management (right-click > Properties > Update). It should refresh within one trigger cycle (5-10 s).
- From the S7-400 side, use STEP 7 / TIA Portal to monitor the destination DB. The value should mirror the OPC tag.
- Navigate through every picture in the project. The transfer must not pause on any screen change.
- Force a tag-acquisition drop by disabling the OPC channel momentarily. The Global Action should continue to run (it will simply skip the write on
LastError <> 0) and resume automatically when the channel comes back. - Inspect the APLog file under
<Project>\<ComputerName>\<ComputerName>.logfor any "Action stopped", "Licence exceeded", or "Script error" entries.
10. Field-Proven Caveats
| Symptom | Root cause | Fix |
|---|---|---|
| Action does not fire at all | Trigger not set, or "Start in Runtime" disabled, or licence missing for VBS Action | Re-open the action properties, set the trigger, confirm runtime start, check the licence diagnostic dialog |
| Action fires only on picture change | The script was placed in a picture-level action or a property event instead of a global action | Move the script to Global Script > Actions (VBS) with a cyclic trigger |
| Stale value always written | Read is not checked with LastError; LastError = -1 leaves .Value untouched but a subsequent write is sometimes forced by the data manager |
Always read first, then check LastError = 0, then write |
| PLC receives value with 1-2 s delay | Tag acquisition cycle on the S7 channel is 1 s, write cycle on OPC channel is 2 s | Reduce both acquisition and write cycles in the channel properties |
| Archive licence exceeded after enabling TagLogging | Every tag counts; the 5,000 archive points / s limit was exceeded | Switch to Global VBS action, or reduce polling cycle, or upsize archive licence |
| Unified UpdateTag returns "invalid Update ID" | The tag has not been assigned that Update ID in the HMI Tags table | Open the tag properties, set the Update ID, recompile, download |
| Unified tag never updates | Internal tags in Unified are on-demand by default; nobody calls UpdateTag | Schedule a task that calls Tags.SysFct.UpdateTag(n)
|
11. Performance and Sizing Notes
The default WinCC tag acquisition cycle is 250 ms for both read and write directions on the SIMATIC S7 channel. If the OPC source is polled at 5 s and the PLC write happens once per cycle, the actual end-to-end latency is bounded by max(OPC_acq, PLC_write_acq) + poll_cycle, which is typically 5.5 s in practice.
For higher update rates:
- Drop the VBS trigger to 1-2 s.
- Set the OPC channel's write cycle to 1 s and the S7 channel's write cycle to 500 ms.
- Use the batched read/write pattern from Section 4.4 to amortise the per-call overhead.
Each global VBS action is dispatched on the WinCC scheduler thread. Avoid heavy loops inside the action body (more than ~1,000 tag operations per cycle); split into multiple actions with non-overlapping time slices if needed.
12. Migration Notes for Projects Upgrading from V6 to V7 to Unified
- Export the global action from the V6 project via Project Migrator before opening in V7.
- Re-compile in V7. C actions are forward compatible. VBS actions typically migrate without change but the licence key changes; a fresh "WinCC Scripting" licence is required.
- When moving from V7 to WinCC Unified, the COM-based
HMIRuntimeobject is replaced by theTagsJavaScript API. The script body must be rewritten; the polling pattern usingUpdateTag(n)is the closest conceptual match. - Re-test all picture independence: the VBS Global Action logic moves to a Unified Scheduled Task. The fundamental decoupling from the picture layer is preserved.
13. FAQ
Why does my WinCC tag transfer stop working when I leave the picture?
Picture-level VBS actions and I/O field events are bound to the picture lifecycle. As soon as the picture is unloaded, the event subscription is removed and the script never fires again. Move the transfer logic to a Global Script action (project scope) with a cyclic trigger so it runs independently of which picture is open.
What is the difference between a Global VBS Action and a project module routine?
A project module routine is a callable subroutine or function that has no trigger of its own. A Global Action is a wrapper that the WinCC scheduler invokes on a configured trigger (timer, tag change, variable). The common pattern is to put the reusable transfer code in a project module and call it from a small Global Action body that only contains the call and the trigger configuration.
How do I poll WinCC tags every 5 seconds without writing a script?
Add the tags to a TagLogging process value archive and set the acquisition cycle to 5 seconds. The runtime will keep polling the tag for the archive, so any code that reads the tag sees a fresh value. This approach costs an archive tag licence per polled tag.
How do I force a one-shot update in WinCC Unified?
Assign an Update ID to the HMI tag in the TIA Portal tag table, then call Tags.SysFct.UpdateTag(updateID) from a scheduled task or from PLC logic. All tags that share the same Update ID are refreshed in a single call. See the WinCC Unified update tag documentation.
What licence do I need for Global VBS Actions?
WinCC Runtime requires the "WinCC Scripting" option in the appropriate PowerTag tier (128, 256, 512, 1,024, 2,048 or 4,096). C Global Actions share the same option. Without it, the action will be marked as unlicensed in the diagnostics and the runtime will not execute it.