Force-Refresh the Active Screen in Siemens WinCC HMI Runtime
When real-format tags update on a Siemens WinCC Comfort/Advanced or WinCC Flexible panel, the HMI does not always redraw the visible screen immediately. Dynamic objects bound to those tags only repaint when the value actually changes by the configured trigger threshold, when the runtime detects a layout invalidation, or when the screen window is reactivated. A common field symptom is stale trend values, frozen bar graphs, or an IO field that holds the previous number until the operator touches it. This article documents the generic VBScript pattern to force a refresh of the active screen, explains why naive approaches cause all screens to flash, and gives a verified, scalable solution.
1. Problem Description
The original requirement is straightforward: bind a VBScript routine to the ChangeValue event of a real-format tag (for example, a 32-bit floating point tag with a 200 ms acquisition cycle) and force the currently displayed screen to repaint its dynamic contents. Two naïve approaches fail in production:
-
Hard-coded screen name. Calling
ActivateScreen "Screen_1", 0inside the tag event always jumps to the screen that contains the tag, regardless of the screen the operator is viewing. On panels that host several process screens (overview, detail, alarm), the operator is yanked out of the active context every time the tag updates. -
Full enumeration with flash side effect. Looping over
HmiRuntime.Screensand callingActivateScreenByNumberon every matching screen causes the runtime to repaint each screen in turn. On a panel with 25+ screens, the user sees a rapid sequence of screen flashes that mimics a fault condition and floods the operator log.
The desired behavior is a silent, in-place repaint of the screen that is actually open. The fix is to identify the active screen index once and reactivate that single screen.
2. Root Cause
WinCC Comfort/Advanced and WinCC Flexible RT expose the active screen through the HmiRuntime.ActiveScreen object, which carries the ObjectName (the configured screen name) and the ScreenNumber (the 1-based runtime index). The ActivateScreenByNumber function performs two actions: it issues a screen change and a screen redraw. If the same screen number is supplied as the currently active one, the runtime tears down the screen window and re-instantiates it, which forces every screen item to refresh its visual state. This is the only built-in, documented mechanism in the classic WinCC scripting API that performs a full screen repaint on demand. See the Siemens WinCC Engineering V15 manual collection and the WinCC V17 scripting reference for the canonical API list.
Because the API does not expose a Refresh() method on the screen object (the VBScript surface is intentionally restricted to maintain deterministic runtime behavior on panels), the reactivate-by-number pattern is the only generic mechanism. The loop in the original code is correct in intent; the bug is that it reactivates every screen with a matching name, which on a properly configured project is every screen in the project.
3. Generic VBScript Solution
The following function is project-agnostic, supports any number of screens, and only repaints the active one. Place it as a Project Function in the HMI scripts node and call it from any tag ChangeValue event.
' ForceRefreshActiveScreen
' Reactivates the currently active WinCC HMI screen to trigger a repaint.
' Safe to call from ChangeValue events of real-format tags.
Sub ForceRefreshActiveScreen()
Dim curIndex
curIndex = HmiRuntime.ActiveScreen.ScreenNumber
' Guard: if no valid screen, exit
If curIndex < 1 Or curIndex > HmiRuntime.Screens.Count Then
Exit Sub
End If
' Reactivate the same screen: runtime tears it down and rebuilds it,
' which forces all dynamic objects to re-render with current tag values.
ActivateScreenByNumber curIndex, 0
End Sub
Wire it from the tag's Value change event:
- Open the HMI tag (for example,
ProcessFlow_AI_401). - Switch to the Events tab and add a Value change event.
- Select Script as the function and choose
ForceRefreshActiveScreen. - Compile the project (Project > Compile > All) and download to the panel.
ActivateScreenByNumber takes the 1-based screen number and a field (window) number. Field 0 is the main screen window. Use the index returned by HmiRuntime.ActiveScreen.ScreenNumber directly; do not assume 1-based ordering matches the configured screen order in the project tree, because screens added later are appended in runtime order.4. Why the Original Loop Flickers
The original snippet compared ObjectName strings across the entire HmiRuntime.Screens collection. Because the comparison matched the active screen, it then issued ActivateScreenByNumber counter, 0 for the active screen and continued the loop. The remaining iterations still matched the same object name when the runtime aliasing reflected the rebuild, causing repeated reactivations until the loop terminated. Each reactivation is a screen tear-down and rebuild event that the panel paints frame by frame, producing the visible flicker.
The corrected pattern reads the active screen index exactly once, breaks out of the loop implicitly by exiting, and performs a single repaint. If a guard against duplicate execution is required (for example, when the tag updates more than ten times per second), wrap the call in a debounce routine:
Dim g_lastRefresh
g_lastRefresh = 0
Sub ForceRefreshActiveScreen_Debounced()
Dim now, minIntervalMs
minIntervalMs = 250 ' 4 Hz maximum repaint rate
now = Timer * 1000
If (now - g_lastRefresh) < minIntervalMs Then Exit Sub
g_lastRefresh = now
ForceRefreshActiveScreen
End Sub
5. Alternative Refresh Strategies
For projects that cannot tolerate a screen tear-down (because animations or video overlays are bound to the screen window), use one of the targeted alternatives below.
5.1 Refresh a single screen item
Most WinCC screen items inherit the Refresh VBScript method (bar, IO field, trend view, alarm view, status/force, recipe view). Call it directly on the item instance:
Sub RefreshTrendView_AI401()
Dim scr, tv
Set scr = HmiRuntime.ActiveScreen
Set tv = scr.ScreenItems("TrendView_AI401")
tv.Refresh
End Sub
Refer to the WinCC V17 scripting reference for the complete Refresh support matrix per control type. Trend views of type Log require a tag re-read first; pass HmiRuntime.Tags("ProcessFlow_AI_401").Read to force a fresh value before calling tv.Refresh.
5.2 Force a tag re-read
Real-format tags configured with Update on request acquisition mode only update when the runtime issues a Read call. Use this when the controller cycles slowly and the panel needs the latest value before drawing:
HmiRuntime.Tags("ProcessFlow_AI_401").Read
Combine with a direct screen item Refresh to redraw only the affected object. This pattern avoids any screen tear-down and is preferred for panels running WinCC Comfort on KP700/KP1200 hardware with limited CPU headroom.
5.3 Use a property trigger to force a re-render
WinCC supports dynamic dialogs and property-trigger animations bound to tag quality codes. Toggling the tag's Quality Code property through a C# or SCL function on the PLC briefly invalidates the value path, which the runtime treats as a value change and repaints bound items. This is an advanced pattern; see the Siemens FAQ on screen update behavior for vendor guidance on forced invalidation.
6. WinCC Unified (TIA Portal V17+) Considerations
WinCC Unified runtime (Unified PC and Unified Comfort Panels from firmware V17 onwards) introduces the HMIRuntime namespace and the UI.SysFct module. The VBScript surface is replaced by JavaScript and C# script objects. The equivalent refresh call is:
// JavaScript in a Unified screen script
import {HMIRuntime} from "HMIRuntime";
const screens = HMIRuntime.UI.ActiveScreen;
// Reactivate the active screen by name
HMIRuntime.UI.SysFct.ChangeScreen(screens.ObjectName, 1);
Unified also exposes a Refresh() method on screen items, which is the preferred mechanism. The VBScript reactivate-by-index pattern does not port directly; rewrite the project function using the Unified API. Refer to the WinCC Unified V18 scripting manual for the full object model and the Siemens WinCC Unified system manual for runtime behavior on Unified Comfort Panels.
7. Parameter Table
| Parameter | Type | Value range | Description |
|---|---|---|---|
HmiRuntime.Screens.Count |
Long (int32) | 1 to 65535 | Number of configured screens at runtime. |
HmiRuntime.ActiveScreen.ObjectName |
String | Max 128 chars | Configured screen name (case-sensitive match required). |
HmiRuntime.ActiveScreen.ScreenNumber |
Long (int32) | 1 to Screens.Count | 1-based runtime index used with ActivateScreenByNumber. |
ActivateScreenByNumber screenNumber, fieldNumber |
Sub call | screenNumber: 1..Count; fieldNumber: 0..15 | Switches to a screen and forces repaint. Field 0 is the main window. |
| Debounce interval (recommended) | Integer ms | 200 to 500 | Throttle repaints to avoid CPU spikes on high-update tags. |
8. Performance and Stability Notes
- CPU load. A full screen repaint on a Comfort Panel scales with the number of dynamic objects on that screen. A 200-object detail screen with 30 IO fields and 5 trend views typically repaints in 80 to 120 ms on a TP700; throttle ChangeValue events to no more than 5 Hz to stay under 50% sustained CPU.
- Operator input latency. During the repaint, soft-key events are queued. A 250 ms debounce is a good compromise between visual freshness and tactile responsiveness.
- Audit trail. On panels with Audit option enabled, every screen change creates an audit entry. Avoid placing the refresh on tags that change more than once per second on audited projects, or configure the audit to suppress consecutive same-screen entries.
- Tag acquisition mode. Real-format tags default to Cyclic continuous with a 1 s update. If the requirement is sub-second visual update, switch the tag to Cyclic continuous with 200 ms, or use the debounced refresh to avoid flooding the bus.
9. Edge Cases and Field-Proven Caveats
-
Popup screens. If the active screen is a popup (field number 1 to 15),
HmiRuntime.ActiveScreen.ScreenNumberstill returns the base screen number. The repaint will close the popup. UseHmiRuntime.BaseScreenNameandHmiRuntime.GetCurrentPopupName(WinCC V16+) to detect popups and call a popup-specific refresh instead. -
Screen during startup. During RT startup the
ActiveScreenobject isNothinguntil the first scheduled screen loads. Wrap the access inIf Not HmiRuntime.ActiveScreen Is Nothing Then. -
Tag in a faceplate. A tag inside a faceplate instance updates the faceplate instance automatically; the parent screen does not need a refresh unless other screen items depend on the same tag indirectly. Calling
ForceRefreshActiveScreenon a faceplate-heavy screen is wasteful and should be avoided. -
Multilingual projects.
ObjectNameis the engineering name, not the displayed title. The string is invariant across languages, so the comparison logic is language-safe. -
Migration from WinCC Flexible. The same
HmiRuntime.ScreensandActivateScreenByNumbersurface is preserved; project functions written for WinCC Flexible 2008 SP5 port to TIA Portal V13+ with no code changes. See the migration guide.
10. Verification Procedure
After deploying the project function, validate the behavior with the following steps:
- Download the project to the panel and start runtime.
- Open the detail screen that contains the target IO field, and confirm the current value.
- Force a tag value change from the PLC or the simulator (for example, set
ProcessFlow_AI_401to a new value in the watch table). - Confirm the IO field updates within 500 ms without a screen change or flash.
- Open the system diagnostics view (Control Panel > System > Runtime Diagnostics) and check that
ForceRefreshActiveScreenappears once per value change, not multiple times. - Repeat with a 100 ms cyclic tag to stress-test the debounce. The runtime should log at most 4 to 5 refresh events per second.
- Open a popup over the detail screen and trigger a tag change. Verify the popup remains open and only the faceplate or value display inside it updates. If the popup closes unexpectedly, switch to the popup-aware pattern in Section 9.
11. Troubleshooting Matrix
| Symptom | Likely cause | Correction |
|---|---|---|
| All screens flash on tag change | Original loop reactivates every screen with a matching name | Use the single-index pattern in Section 3 |
| Screen repaints but the value is still old | Tag is in Update on request mode and no Read was issued |
Call HmiRuntime.Tags(...).Read before the refresh |
| Popup closes on refresh | Repaint of the base screen tears down child windows | Refresh the specific item inside the popup |
| VBScript error "Object required: HmiRuntime.ActiveScreen" | Tag event fires before runtime finishes startup | Add If Not HmiRuntime.ActiveScreen Is Nothing Then guard |
| Runtime freezes for 2 to 3 seconds on refresh | High-frequency tag fires on every PLC scan; debounce missing | Apply the 250 ms debounce in Section 4 |
| WinCC Unified project does not compile | Code uses VBScript API; Unified uses JavaScript and C# | Port to HMIRuntime.UI.SysFct calls (Section 6) |
12. Related Standards and References
For projects under GAMP 5 or IEC 62443, document the screen-refresh mechanism as part of the HMI software architecture. The pattern uses only the documented WinCC scripting API and does not require registry edits, DLL injections, or undocumented runtime hooks. For panels connected to a PROFINET network, ensure the tag update rate does not exceed the configured PROFINET update time; the typical 1 ms update time on IRT allows up to 1 kHz tag changes, well above any HMI refresh requirement. The PROFINET specification (IEC 61784-2) governs cycle timing; the HMI refresh rate should be configured slower than the configured PROFINET send clock to avoid bus saturation.
How do I refresh only the active screen without flashing other screens?
Read HmiRuntime.ActiveScreen.ScreenNumber once and call ActivateScreenByNumber with that exact index and field 0. Do not loop over HmiRuntime.Screens or compare by ObjectName, because that reactivates every matching screen. The single-index reactivate forces one in-place repaint.
Why does my IO field not update when the real-format tag changes?
The tag is likely configured with Update on request acquisition or the IO field has a configured update threshold larger than the tag delta. Call HmiRuntime.Tags("TagName").Read from the ChangeValue script before the screen refresh, or lower the IO field's trigger threshold to 0 in the properties dialog.
Does the refresh pattern work on WinCC Unified Comfort Panels?
No. Unified uses JavaScript and the HMIRuntime.UI namespace. Use HMIRuntime.UI.SysFct.ChangeScreen with the active screen's ObjectName, or call Refresh() directly on the Unified screen item. See the Unified V18 scripting manual.
How do I throttle the refresh to avoid CPU spikes?
Use the Timer function in a project-level variable to record the last refresh timestamp, and skip the repaint if the elapsed time is below 250 ms. This caps the repaint rate at 4 Hz and is sufficient for operator visibility on most process screens.
Can I refresh a faceplate instance without repainting the parent screen?
Yes. Access the faceplate through HmiRuntime.ActiveScreen.ScreenItems("FaceplateInstanceName") and call its Refresh method, or bind the dynamic property to the same tag with a configured property trigger. The faceplate instance is a self-contained screen object and does not require a full screen repaint.