WinCC 7 I/O Field Not Updating Dynamically: SetTagDWord Fix
This technical reference covers a recurring WinCC 7.0 SP3 (and later WinCC 7.x) issue where an I/O Field bound to a process tag stops updating dynamically when a C-Script attempts to write a value. The displayed value is the literal hardcoded constant inside the script, not the variable value the operator is supposed to be entering. The root cause is a common misuse of the I/O Field's Output Value property and the wrong C-API call path. The fix is to write to the tag with SetTagDWord (or the appropriate typed variant), to leave the I/O Field's tag binding intact, and to avoid overwriting the Output property at runtime.
1. Problem Description
Symptom observed in WinCC V7.0 SP3 (and reproducible on WinCC V7.2, V7.3, V7.4, and V7.5 with identical C-API behavior):
- Two I/O Fields (Box 1 and Box 2) are placed on a Graphics Designer PDL screen.
- Box 1 is configured with an Input property bound to a process tag (e.g.
THIS_IS_MY_TAG) so the operator can type a value. - A C-Script attached to the Mouse Click (or OnClick) event of Box 1 invokes
SetTagDWord("THIS_IS_MY_TAG", 563); - Box 2 has its Output Value property bound to the same tag
THIS_IS_MY_TAG. - Expected behavior: Box 2 always reflects whatever value the operator enters in Box 1.
- Observed behavior: Box 2 displays
563regardless of what the operator types. Editing the constant in the script changes the displayed value, confirming the script overwrites the binding rather than the tag.
2. Root Cause Analysis
There are three independent faults that can produce the symptom, all of which are present or latent in the source case:
2.1 Script writes the literal, not the entered value
The source script is:
SetTagDWord("THIS_IS_MY_TAG", 563); // 563 is a dummy value
The literal 563 is passed as the value argument. To forward whatever the operator has typed into Box 1, the script must read the current Input Value (or simply read the tag itself after the I/O Field committed it) and pass that value to SetTagDWord. A typical working pattern is:
DWORD v = GetTagDWord("THIS_IS_MY_TAG");
SetTagDWord("THIS_IS_MY_TAG", v); // no-op echo, demonstrates round-trip
If Box 1 is an input I/O Field with Update on Exit or Update on Input, the operator's keystrokes are committed to the tag only on leaving the field. Calling GetTagDWord in the same script that fires on the I/O Field event can race the commit. Use the dedicated event-driven helper described in §4.
2.2 Tag binding direction confusion
The I/O Field dialog has two slots under Output/Input:
| Slot | Direction | Effect at runtime |
|---|---|---|
| Output Value | Tag → I/O Field | Writes from PLC/Internal to display. This is where Box 2 must bind to the tag. |
| Input Value | I/O Field → Tag | Writes from operator to PLC/Internal. This is where Box 1 must bind to the tag. |
If both boxes have the tag configured in Output Value, then both display whatever the script wrote last. The operator's typed input is silently dropped because Box 1's Input slot is empty.
2.3 Hardcoding in the script overrides runtime binding
A separate but related failure mode is when a developer accidentally selects Output Value on Box 2 and types a literal number (563) into the configuration dialog instead of using the tag browser. Once the literal is present, the C-Script can still call SetTagDWord, but the I/O Field's Output property is statically bound to 563 at compile time and never re-evaluates. This is the precise failure mode described in the field report.
3. Reference Architecture
The correct data flow for the two-I/O-Field case is:
+----------------+ Input binding +---------+
| I/O Field 1 | --------------------> | Tag |
| (operator I/P) | | THIS_IS|
+----------------+ | _MY_TAG|
+----+----+
|
Output binding |
v
+---------------+
| I/O Field 2 |
| (display O/P) |
+---------------+
The script's role is optional here. If Box 1 has Input Value bound to the tag, the runtime writes to the tag the moment the operator confirms the entry. The script is only needed when additional logic (scaling, validation, dual-write to a second tag) is required.
4. Step-by-Step Solution
- Open the PDL in Graphics Designer. Right-click each I/O Field and select Configuration Dialog.
-
Box 1 - Input slot: Under Output/Input > Input Value, click the tag browser (button with three dots) and select
THIS_IS_MY_TAG. Leave Output Value empty unless you also want a default display. - Box 1 - Update mode: In Miscellaneous, choose Update on Exit for confirmation-on-leave-field semantics, or Update on Input for keystroke-by-keystroke updates. Update on Exit is the safer choice for numeric entry.
-
Box 2 - Output slot: Under Output/Input > Output Value, bind to
THIS_IS_MY_TAG. Do not bind Input Value unless you want Box 2 to also be operable. -
Replace the C-Script on Box 1. Remove the hardcoded
563. If you need to forward the entered value to a second tag, read from the first and write to the second:// Forward operator input to a destination tag DWORD entered = GetTagDWord("THIS_IS_MY_TAG"); // read what Box 1 committed SetTagDWord("DESTINATION_TAG", entered); // write to Box 2's tag if different - If Box 1 must push immediately on click: Attach the script to the Mouse Click event of Box 1, not to a property change event. Use the I/O Field's Output/Input tag internally; do not write to the Output Value property of Box 1 itself.
- Compile and save the PDL. Use File > Save As with a new revision number to force a full redeploy.
- Restart WinCC Runtime (or use the RT > Restart toolbar button) so the Graphics Runtime re-reads the PDL.
5. C-API Reference for I/O Field Tag Updates
The C-API exposes typed setters matched to the tag's underlying data type. Choosing the wrong setter returns FALSE and silently leaves the tag unchanged. The mapping is:
| Tag data type (WinCC) | Setter | Getter | C literal type |
|---|---|---|---|
| Binary Tag | SetTagBit |
GetTagBit |
BOOL |
| Signed 8-bit | SetTagSByte |
GetTagSByte |
char |
| Unsigned 8-bit | SetTagByte |
GetTagByte |
BYTE |
| Signed 16-bit | SetTagShort |
GetTagShort |
short |
| Unsigned 16-bit | SetTagWord |
GetTagWord |
WORD |
| Signed 32-bit | SetTagSDWord |
GetTagSDWord |
long |
| Unsigned 32-bit | SetTagDWord |
GetTagDWord |
DWORD |
| Float 32-bit (IEEE-754) | SetTagFloat |
GetTagFloat |
float |
| Double 64-bit (IEEE-754) | SetTagDouble |
GetTagDouble |
double |
| Text tag, 8-bit char | SetTagChar |
GetTagChar |
char[N] |
| Text tag, 16-bit char | SetTagText |
GetTagText |
wchar_t[N] / LPCWSTR
|
| Raw (opaque) | SetTagRaw |
GetTagRaw |
BYTE* + length |
THIS_IS_MY_TAG is defined as a Signed 32-bit tag in WinCC Tag Management and the script uses SetTagDWord (unsigned), WinCC accepts the call but may display negative wrap-around values above 2,147,483,648. Always match the setter to the tag's declared type.6. Common Pitfalls and Edge Cases
6.1 Mixing Output and Input in one slot
Some users place the tag in the Output Value slot of both boxes, expecting the runtime to echo the input. WinCC only writes to Output Value at PDL load. After that, the static literal or initial tag value is frozen. Always bind Input Value on Box 1.
6.2 Update mode interaction
With Update on Input, every keystroke writes to the tag. With Update on Exit, the tag is only written when the field loses focus. A script attached to Mouse Click outside Box 1 may fire before the I/O Field commits the value when Update on Exit is selected. In that case, GetTagDWord returns the prior value. Use the On Change event of the tag (via a tag trigger) instead of Mouse Click on the field, or call GetInputValueDouble/GetOutputValueDouble on the field object directly inside the script.
6.3 Numeric format string
An I/O Field with a Format like s9999 will reject values above 9999. The setter returns TRUE, but the display remains at the configured maximum. Check the Properties > Output/Input > Output Format / Input Format entries before chasing scripting bugs.
6.4 Internal vs. external tag
SetTagDWord works on internal tags and on process tags when the underlying connection (S7, OPC, Modbus) is online. If the connection is in Simulation or Stop, writes to process tags may be dropped by the channel. Verify with WinCC Explorer > Tag Management > [Connection] > Status.
6.5 Mouse event vs. property trigger
Attaching a script to Mouse Click on Box 1 means the script fires whenever the operator clicks, even if the value did not change. Replace with OnPropertyChange on the Output Value property, or with the Tag trigger on THIS_IS_MY_TAG, for an event-driven design.
7. Verification Procedure
- Compile check: In Graphics Designer, File > Check Project Consistency. A wrong tag name shows as a missing reference.
-
Tag simulator: Open WinCC Explorer > Tag Management > Internal Tags. Add
THIS_IS_MY_TAGif not already present and set the data type to Unsigned 32-bit. -
Runtime test: Start Runtime. Type
100in Box 1 and press Tab. Box 2 must update to100within one PDL refresh cycle (default 250 ms). - Script test: Click Box 1 (if the script is retained). Check the value at Box 2 equals the value entered at Box 1, not the literal in the script.
-
Gdiag output: Add
printf("Tag=%lu\n", GetTagDWord("THIS_IS_MY_TAG"));in the C-Script and enable APDIAG logging via computer properties > Graphics Runtime > APDiag. Confirm the printf shows the entered value, not the literal. -
Tag logging check: Add
THIS_IS_MY_TAGto the Tag Logging archive with a 1 s cycle and verify the curve reflects operator entries.
8. Equivalent VBScript Pattern
Modern WinCC 7.4+ projects often prefer VBScript for event handlers. The equivalent working pattern is:
' OnClick event of I/O Field 1
Dim v
v = HMIRuntime.Tags("THIS_IS_MY_TAG").Read
HMIRuntime.Tags("DESTINATION_TAG").Write v
Or, to write the typed value back to itself with no transformation:
HMIRuntime.Tags("THIS_IS_MY_TAG").Write HMIRuntime.Tags("THIS_IS_MY_TAG").Read
The VBScript HMIRuntime.Tags object enforces data type matching at runtime; passing a String to a DWord tag raises a type-mismatch error in the diagnostic view.
9. WinCC Unified Equivalent
For projects on WinCC Unified V17 / V18 / V19 / V20 / V21 (TIA Portal), the I/O Field is configured under HMIIOField. The same binding rules apply, but the scripting API uses JavaScript and the Tags interface:
// Unified JavaScript on the OutputValueChanged event
let v = Tags("THIS_IS_MY_TAG").Read();
Tags("DESTINATION_TAG").Write(v);
Reference: IO field (RT Unified) - WinCC Unified V21 documentation. The Unified I/O Field uses separate ProcessValue, OutputValue, and Value properties rather than the Classic dialog's two-slot model; the underlying principle (bind to the tag, never to a literal) is identical.
10. Diagnostic Checklist
| Symptom | Likely cause | Fix |
|---|---|---|
| Box 2 always shows the script's hardcoded constant | Output Value property bound to literal, not tag | Re-bind Output Value to THIS_IS_MY_TAG via tag browser |
| Box 2 does not update when operator types | Box 1 Input Value is empty | Bind Box 1 Input Value to THIS_IS_MY_TAG
|
| Box 2 shows old value | Update on Exit, script fires before commit | Switch to Update on Input, or use OnPropertyChange trigger |
| SetTagDWord returns FALSE | Tag data type mismatch | Match setter to tag type (see §5 table) |
| Script does not fire | Event attached to wrong object property | Attach to Mouse Click event of Box 1, not its Output Value |
| Box 2 maxes out at format limit | Output format string clamps value | Widen format string (e.g. 9999999 for s, 0.00 for floats) |
| Process tag writes ignored | Channel is stopped or in simulation | Restore channel in WinCC Explorer; verify with Status dialog |
| VBScript type-mismatch error | Passing String to numeric tag | Use CInt/CLng/CDbl explicitly |
11. Best-Practice Recommendations
- Bind the tag via the tag browser; never type the tag name as a string in the configuration dialog.
- Use C-API setters only when scripting logic is required (scaling, validation, multi-tag writes). If the only requirement is display, the runtime's native tag binding is faster and more reliable than any script.
- Prefer VBScript or C-Script event handlers on the I/O Field's tag-trigger event over Mouse Click events for value-driven logic.
- Always declare the tag's data type in Tag Management before writing the C-Script, and match the
SetTag*function accordingly. - Use Update on Exit for numeric fields to prevent intermediate invalid states (e.g. empty string between digits).
- Document the tag binding direction (Input vs. Output) in the PDL comment field so future editors do not reverse it.
- When migrating from WinCC 7.x to WinCC Unified, port both the tag binding and the script; do not assume the script is automatically reusable.
Why does my WinCC 7 I/O Field always show 563 no matter what I type?
The Output Value property of the second I/O Field is bound to the literal 563 rather than to the tag THIS_IS_MY_TAG. Open the Configuration Dialog of the second I/O Field, click the tag browser on Output/Input > Output Value, and select the tag. Also bind the first I/O Field's Input Value to the same tag so the operator's entry is committed.
Should I use SetTagDWord or SetTagWord for a 16-bit WinCC tag?
Match the setter to the tag's declared data type. For an Unsigned 16-bit tag use SetTagWord / GetTagWord, for Signed 16-bit use SetTagShort / GetTagShort. Using SetTagDWord on a 16-bit tag returns FALSE and the value does not change.
Why does my C-Script on Mouse Click read a stale tag value?
The I/O Field is configured with Update on Exit, so the tag is written only when the field loses focus. The Mouse Click event on the field can fire before the commit. Switch the field to Update on Input, or move the script to a tag-trigger event on the tag itself so it fires after the commit.
How do I forward an I/O Field entry to a second tag in C?
Read the entered value with GetTagDWord("THIS_IS_MY_TAG"); and write it to the destination with SetTagDWord("DESTINATION_TAG", v);. Do not write to the Output Value property of any I/O Field from the script; let the runtime's tag binding handle the display.
Does the same pattern apply to WinCC Unified?
Yes, the principle is identical: bind the I/O Field to the tag and avoid overwriting its display property. In Unified V17+ the JavaScript API is Tags("NAME").Read() / Tags("NAME").Write(value). See the WinCC Unified V21 IO Field documentation for property names.