Writing Values to Internal Tags in WinCC TIA Portal VBScript

David Krause13 min read
HMI / SCADASiemensTutorial / 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

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

  1. 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.
  2. 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.
  3. 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.
  4. 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.
Edition rule of thumb: Panels and PC Runtime Comfort / Advanced → use 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

  1. Create the internal tag. In the project tree, expand the HMI device, open HMI Tags, and add a tag with name INT2, data type Int, and connection Internal. Save and compile the HMI station.
  2. Add a VBS procedure. Right-click the HMI device → ScriptsVBS proceduresAdd new. Name it WriteINT2.
  3. Use the correct object model.
    • Comfort/Advanced/Panel:
      SmartTags("INT2") = 9
    • Professional/IPC:
      Set t = HMIRuntime.Tags("INT2") : t.Write 9 : Set t = Nothing
  4. Wire the procedure to an event. The most common wiring is a button Press event: HMI tag → select the button → EventsPress → 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.
  5. 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.
  6. 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.
  7. 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:

  1. 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 Write call back into the SmartTags dispatcher.
  2. 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.
  3. Time and locale divergence. VBScript DateSerial and 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 writing WString internal tags.
Recommendation: Do not develop WinCC runtime images in a VMware guest. Use a native Windows installation (or a Hyper-V Gen-2 VM with full integration services enabled) for the engineering station, and provision the runtime on physical hardware for production. If a virtualized engineering station is unavoidable, install VMware Tools, run the WinCC installer with Run as administrator, and verify the SIMATIC WinCC RT service is Automatic and Started before opening TIA Portal.

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:

  1. 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.Tags with a slightly different signature, e.g., Tags("Tag1").Write(6) with parentheses. Existing VBS projects migrate transparently.
  2. 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

  1. Offline compile. Right-click the HMI → Compile → Software (rebuild all). No syntax errors in the output window.
  2. Tag simulator (Comfort/Advanced). Start the panel simulator (Start Runtime). Open Tools → Tag simulator (or use the HMI tag table → Simulate). Set INT1 to 23, fire the script via a button, and observe INT2 becoming 9.
  3. Watch table (Professional). In the HMI tag table, add INT2 to the watch table and use Online → Monitor. Trigger the script and confirm the value transitions from 0 (or current) to 9.
  4. Trace output. Add an HMIRuntime.Trace line 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.

Back to blog