Overview
Writing a value to an internal HMI tag in a WinCC TIA Portal project is one of the most common scripting tasks for any Comfort, Advanced, or Professional runtime engineer. Internal tags are local HMI variables that exist only in the panel or IPC memory; they are not exchanged with a PLC over the fieldbus. They are typically used for:
- Local state flags (e.g.,
bZone_Active,bRecipe_Loaded) - Counter or accumulator values used in scripts only
- Operator-side metadata such as username, language index, or shift number
- Intermediate results of arithmetic inside VBScript functions
Siemens exposes two distinct object models for tag access: the legacy SmartTags collection (Panels and WinCC Comfort/Advanced) and the HMIRuntime.Tags object (WinCC Professional / WinCC Runtime Professional on an IPC). Selecting the wrong model is the root cause of the Variable 'write' is not defined error reported by engineers on TIA V11 and TIA V12 SP1 systems. This article documents both models, when each is available, and the exact code patterns that compile cleanly from TIA V11 through TIA V20.
Prerequisites
- SIMATIC WinCC (TIA Portal) installed at the project version that matches the runtime image (V11 SP2, V12 SP1, V13 SP1, V14 SP1, V15.1, V16, V17, V18, V19, or V20). Mixing engineering and runtime versions is a common source of obscure script compile errors.
- A configured internal tag created in the HMI tags table (Project tree → HMI → HMI Tags → Show all tags → Add new). Use the Internal connection. For RT Unified projects, see the Internal tags (RT Unified) reference.
- Access to a VBScript editor. In TIA Portal this is the Scripts node under the HMI device, where VBS procedures and VBS standard modules can be added.
- For Professional / SCADA runtime: a SIMATIC IPC (or compatible PC runtime) with WinCC Runtime Professional installed; the same scripts will not execute on a Comfort or Advanced panel.
SmartTags. PC Runtime Professional → use HMIRuntime.Tags(...).Write. TIA Portal will silently accept the wrong model during offline compilation in some V11 SP2 patches; the error appears only on online build or on the panel.Internal Tags vs. External Tags
| Attribute | Internal Tag | External (PLC) Tag |
|---|---|---|
| Connection | Internal (HMI only) | S7-1200/1500, S7-300/400, OPC UA, Modbus, etc. |
| Persisted across power cycle | No (unless retentive flag set in V18+) | Yes, on PLC |
| Typical use | Local logic, operator prompts, derived state | Process I/O, setpoints, recipes |
| Accessible from VBS | Yes (read/write) | Yes (read/write with care) |
| Visible in WinCC tag simulator | Yes | Requires simulator license |
Per the Siemens documentation on internal tags (RT Unified), internal tags can use any of the HMI data types (Bool, Int, DInt, Real, WString, DateTime, etc.) and are configurable per area or globally.
Two Object Models: SmartTags vs. HMIRuntime.Tags
1. SmartTags collection (Comfort / Advanced / Panels)
The SmartTags collection is a convenience wrapper that exposes every HMI tag of the project as a global object. You reference tags by string name in parentheses and assign with the standard VBScript = operator. No object pointer, no .Write call, no Set statement.
' --- TIA V11 / V12 SP1 / V13 / V14 / V15 / V16 / V17 / V18 / V19 / V20 ---
' WinCC Comfort or Advanced, Panel or PC Runtime
Sub WriteIntegerValue()
SmartTags("INT2") = 9
End Sub
2. HMIRuntime.Tags object (Professional / SCADA)
WinCC Professional uses a class-based tag model. You obtain a Tag object from the runtime, then call .Read or .Write. The object must be released when no longer needed.
' --- WinCC Professional V12 / V13 / V14 / V15 / V16 / V17 / V18 / V19 / V20 ---
' PC Runtime, IPC, or SCADA station
Sub WriteIntegerValue_Pro()
Dim objTag
Set objTag = HMIRuntime.Tags("INT2")
objTag.Write 9
Set objTag = Nothing
End Sub
This is the pattern documented in the WinCC Professional V12.0 manual, section 9.8.9.8 (Working with Tags) and the equivalent sections of every later release. The behavior is unchanged through TIA V20; only the project migration steps differ.
3. Why SmartTags("INT2").write 9 fails
The string .write in SmartTags("INT2").write 9 is interpreted as a property or method access on the value wrapper returned by the SmartTags collection. Comfort and Advanced do not expose a write member; the only valid syntax is the assignment operator. The error raised is:
Compile error: Variable 'write' is not defined in line X, column Y
This message is produced by the VBScript editor at design time and by the runtime at load time. It indicates that the project was opened on a system whose VBScript engine resolved the statement against the Comfort schema rather than the Professional schema. Re-creating the script using the syntax for the actual runtime edition (see the table below) clears the error.
Step-by-Step: Writing an Integer Value
-
Create the internal tag. In the project tree, expand the HMI device, open HMI Tags, and add a tag with name
INT2, data typeInt, and connection Internal. Save and compile the HMI station. -
Add a VBS procedure. Right-click the HMI device → Scripts → VBS procedures → Add new. Name it
WriteINT2. -
Use the correct object model.
- Comfort/Advanced/Panel:
SmartTags("INT2") = 9 - Professional/IPC:
Set t = HMIRuntime.Tags("INT2") : t.Write 9 : Set t = Nothing
- Comfort/Advanced/Panel:
- Wire the procedure to an event. The most common wiring is a button Press event: HMI tag → select the button → Events → Press → add a VBS action and select the new procedure. Avoid wiring both Press and Release to the same script unless intentional; a 200 ms double-fire is a common field bug.
- Compile the project. In TIA Portal, right-click the HMI → Compile → Software (rebuild all). Any Variable 'write' is not defined error at this stage is a syntax mismatch, not a runtime error.
- Download to the runtime. Use Online → Download to device. For PC Runtime, the Runtime must be in Stop state to accept a download; the panel will prompt for confirmation.
- Verify in the tag simulator or with a watch table. See the Verification section below.
Step-by-Step: Writing a Boolean (Bit) Value
To set a single bit of an integer PLC tag into a boolean internal tag (the Zone_Active example from the source thread), follow this pattern. The cleanest solution extracts the bit with a bitwise AND before assignment.
' --- Zone_Active : Bool internal tag
' --- Zone_Select : Int PLC tag, bit 1 indicates Zone 1 active
Sub UpdateZoneActive()
Dim iPLCValue
iPLCValue = SmartTags("Zone_Select")
If (iPLCValue And 2^1) <> 0 Then ' bit 1, 0-indexed
SmartTags("Zone_Active") = True
Else
SmartTags("Zone_Active") = False
End If
End Sub
Generalized bit-mask formula: mask = 2^bitIndex. For bitIndex = 0 (LSB), mask = 1; for bit 7 (MSB of a byte), mask = 128. Note that VBScript's And is a bitwise operator on integer operands, unlike logical short-circuit And in C-style languages. The result is always a Long (32-bit signed).
Conditional Write with a Read-Back Guard
The following pattern is functionally identical to the original question in the source thread, but uses only syntax that compiles in every TIA Portal edition from V11 SP2 to V20:
Sub VBFunction_1()
If SmartTags("INT1") = 23 Then
SmartTags("INT2") = 9
End If
End Sub
For Professional runtime, the equivalent is:
Sub VBFunction_1_Pro()
Dim tIn, tOut
Set tIn = HMIRuntime.Tags("INT1")
Set tOut = HMIRuntime.Tags("INT2")
tIn.Read
If tIn.Value = 23 Then tOut.Write 9
Set tIn = Nothing
Set tOut = Nothing
End Sub
The Read call is required in Professional because the tag object is a server-side handle; the local VBScript view of the value is only refreshed when .Read is explicitly called. Comfort/Advanced's SmartTags collection does this transparently, which is why the guard works there with no .Read.
Reading a Tag Value with Quality Code and Timestamp
For diagnostic and logging scripts, the Professional model exposes .Value, .Quality, and .Timestamp:
Sub ReadTagDiagnostics()
Dim t
Set t = HMIRuntime.Tags("Pressure_PV")
t.Read
HMIRuntime.Trace "Val=" & t.Value & _
" Q=" & t.Quality & _
" T=" & t.Timestamp & vbCrLf
Set t = Nothing
End Sub
Quality codes follow OPC conventions: 0 = Good, 1 = Bad, 2 = Uncertain. The full 16-bit quality byte is returned; bit 0x40 indicates a sub-status (e.g., 0x40 + 0x01 = configuration error, 0x40 + 0x05 = last known value). For a reference video on tag read patterns, see the Inductive University Reading and Writing Tags lesson.
Edition Matrix: Which Object Model to Use
| TIA Portal Version | Runtime | Target Hardware | Recommended Object Model | Notes |
|---|---|---|---|---|
| V11 SP2 / V12 SP1 | Comfort / Advanced | Comfort Panel, PC Runtime | SmartTags |
Original release path. .write not yet available on SmartTags. |
| V12 SP1 / V13 SP1 | Professional | IPC, WinCC RT Pro | HMIRuntime.Tags |
First edition where Professional on IPC became common. |
| V14 SP1 / V15.1 | Comfort / Advanced / Professional | Unified, mixed fleets | Per target runtime | Unified Comfort introduced; still uses SmartTags for VBS. |
| V16 / V17 | Unified Comfort / Unified PC | MTP devices, IPC | Native Unified JS or HMIRuntime | VBScript retained but new projects prefer JavaScript in WinCC Unified. |
| V18 / V19 / V20 | Unified + Classic | Unified Panels and PC | SmartTags (legacy VBS), HMIRuntime (legacy VBS), JavaScript (Unified) | Internal tags gained optional retentive storage in V18. |
VMware and Virtualization Considerations
Field reports across multiple Siemens releases show that scripts which compile and run on a physical engineering PC can fail to compile, throw ActiveX component can't create object, or raise Variable 'write' is not defined when the same project is loaded inside a VMware Workstation / ESXi guest. The root causes are:
-
COM activation context. WinCC VBScript hosts the Microsoft Script Control and depends on the COM service activation. VMware's default COM security policy on some Windows 10 / 11 guests blocks cross-apartment activation of the ScriptControl, so the runtime cannot marshal the
Writecall back into the SmartTags dispatcher. - Missing OPC/WinCC services. In a minimal Windows guest, the WinCC Runtime Service (Professional) or the HMIRtm service (Comfort/Advanced) is sometimes not registered because the guest was sysprepped before the WinCC installer finished staging the service.
-
Time and locale divergence. VBScript
DateSerialand tag timestamp formatting depend on system locale; a guest restored from a snapshot inherits the host locale and may not match the project's regional settings, producing silent string conversion failures when writingWStringinternal tags.
Troubleshooting Matrix
| Symptom | Root Cause | Fix |
|---|---|---|
| Variable 'write' is not defined | SmartTags used on Professional runtime, or script edited on a project whose schema was last saved in Professional | Replace SmartTags("X").write v with SmartTags("X") = v (Comfort/Advanced) or with HMIRuntime.Tags("X").Write v (Professional). |
| Script works on Panel A, fails on Panel B with the same TIA version | Different image build (e.g., one PC has TIA V12 SP1, the other V12 SP2), or one project was opened/saved in Professional | Match image versions and recreate the script. Use Project → Compile all to force a clean HMI build. |
| Object doesn't support this property or method: 'Read' | Tag was declared but not instantiated; Set t = HMIRuntime.Tags("X") line missing |
Add the Set statement and verify the tag name string matches the tag table exactly (case-sensitive in V16+). |
| Write appears to succeed but value reverts after the script exits | Trigger fired on a screen change and the script is also subscribed to Loaded with a reset; or another cyclic script is overwriting the value | Audit the Schedules node; disable suspect cyclic tasks and re-test. |
| Value never reaches the internal tag at runtime | Wrong connection type (PLC connection instead of Internal), or the tag is filtered out of the active HMI image | Open HMI Tags → confirm Connection: Internal; recompile. |
| Compile error inside a VMware guest, OK on physical PC | COM activation failure or missing WinCC service | Reinstall the runtime inside the guest, start SIMATIC WinCC RT service, or migrate engineering to a physical machine. |
| Boolean write silently ignored | Tag data type is Word or Int, not Bool
|
Change the tag data type to Bool in the HMI tag table; SmartTags("bFlag") = True will not coerce to a Word. |
| Quality code returns 0x40 / 0x05 (Last Known Value) | PLC connection lost or area pointer not updated | Check Connections node, restart HMI runtime; this error is normal after a power-up before first read. |
Migration Note: From TIA V11 to V20
The syntax described in this article is stable across the entire V11 SP2 to V20 product line for classic WinCC Comfort, Advanced, and Professional. The two material changes are:
-
V16 (WinCC Unified): New projects default to JavaScript for scripting. The legacy VBScript editor is still available, but new SCADA development on Unified panels and PC Unified uses
HMIRuntime.Tagswith a slightly different signature, e.g.,Tags("Tag1").Write(6)with parentheses. Existing VBS projects migrate transparently. - V18: Internal tags can be marked Retentive; the value survives a panel reboot. Useful for shift counters and operator-settable state flags that previously required an external PLC tag workaround.
Verification
- Offline compile. Right-click the HMI → Compile → Software (rebuild all). No syntax errors in the output window.
-
Tag simulator (Comfort/Advanced). Start the panel simulator (Start Runtime). Open Tools → Tag simulator (or use the HMI tag table → Simulate). Set
INT1to 23, fire the script via a button, and observeINT2becoming 9. -
Watch table (Professional). In the HMI tag table, add
INT2to the watch table and use Online → Monitor. Trigger the script and confirm the value transitions from 0 (or current) to 9. -
Trace output. Add an
HMIRuntime.Traceline at the start and end of the script. The trace file is written to the project log directory and shows the script's execution time and any thrown errors. For non-visual verification, a single trace line is the fastest way to confirm the script ran.
FAQ
Why does SmartTags("INT2").write 9 give a compile error in TIA V11 but not on another PC?
The write method belongs to the Professional Tag object, not to the Comfort/Advanced SmartTags collection. If the project was last opened in a Professional engineering session on PC A, PC B's Comfort editor will reject it. Replace the line with SmartTags("INT2") = 9 for Comfort/Advanced, or use HMIRuntime.Tags("INT2").Write 9 for Professional.
Can I read a single bit of an Int PLC tag and write it to a Bool internal tag?
Yes. Read the Int with SmartTags("Zone_Select"), mask with a power of two (iValue And 2^bitIndex), and assign the boolean result. A full example is in the Step-by-Step: Writing a Boolean (Bit) Value section. Use the same pattern in Professional with the HMIRuntime.Tags model.
Does WinCC TIA Portal run inside a VMware Workstation guest?
Engineering and the Comfort/Advanced panel simulator generally run, but WinCC Runtime Professional on an IPC-equivalent guest can fail at COM activation, raising ActiveX component can't create object or Variable 'write' is not defined at compile time. Use a native Windows installation for the runtime, or a Hyper-V Gen-2 VM with integration services enabled.
Which TIA Portal versions are covered by the syntax in this article?
The SmartTags and HMIRuntime.Tags patterns documented here compile cleanly from TIA V11 SP2 through TIA V20, including V13 SP1, V14 SP1, V15.1, V16, V17, V18, and V19. For new WinCC Unified projects, Siemens recommends JavaScript instead of VBScript; the unified JS API uses Tags("Tag1").Write(value) with parentheses.
Are internal tags retained across a power cycle?
By default, no. Starting with TIA V18, internal tags can be flagged as Retentive in the HMI tag properties, in which case the value is stored in non-volatile memory on the panel or IPC and restored on the next boot. For pre-V18 systems, persist critical state in a PLC tag instead.