Resolving MP277 SmartTags Zero-Value Bug in VBScript Loops

David Krause12 min read
HMI ProgrammingSiemensTroubleshooting
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

Resolving MP277 SmartTags Zero-Value Bug in VBScript Loops

The Siemens SIMATIC MP 277 (Mobile Panel 277) family, when running WinCC Flexible 2008 SP2 / SP3 / SP4 image builds, exhibits a silent runtime failure when VBScript code accesses HMI tags through dynamically constructed names inside a For-Next loop. The tag is read, the file is written, the line count is correct, and yet every numeric column resolves to 0. The behavior is reproducible, has no HMI alarm entry, and disappears the moment each tag is touched by name at least once in the same script session. The pattern is frequently seen when a maintenance engineer batches 100–500 process values into a CSV or plain-text file on a network share using fFileWrite.LinePrint, and it is the most common cause of "ghost zeros" in operator log files generated by MP 277 panels.

Field observation. The bug does not surface in WinCC Comfort / TIA Portal V16+ runtime environments that ship a different tag-caching model; it is specific to the legacy WinCC Flexible script runtime that ships on the MP 277 6AV6 645 series.

1. Problem Statement and Scope

A VBScript routine of the following form is requested by the operator:

For i = 1 To 200
    fFileWrite.LinePrint "Pressione_US_" & addZero(i) & "=" & SmartTags("Pressione_US_" & addZero(i))
Next

Observable outcomes:

  1. The destination file is created and the correct number of lines (200) is written.
  2. The literal tag name portion is correct on every line (e.g., Pressione_US_001, Pressione_US_002).
  3. Every value column reads 0 on the first invocation of the script after a project transfer or a panel reboot.
  4. If a single literal reference such as SmartTags("Pressione_US_001") is executed anywhere earlier in the same script, the Pressione_US_001 value resolves correctly while the remaining 199 indices still return 0.
  5. After touching every tag by name once, subsequent runs of the same loop return correct values for the lifetime of the runtime.

This is not a logic bug in the engineer's script. It is a tag-cache initialization artifact of the MP 277 WinCC Flexible script runtime that becomes visible only when the tag name is constructed dynamically rather than appearing literally in source code.

2. Affected Hardware, Image Versions, and Runtime

Component Identifier Notes
Panel family SIMATIC MP 277 7.5" and 10.4" Mobile Panel variants
Part numbers 6AV6 645-0BA01-0AX0
6AV6 645-0BC01-0AX0
6AV6 645-0DC01-0AX0
6AV6 645-0EC01-0AX0
Image revision is stamped on the rear label; older images show the bug more often
HMI image WinCC Flexible 2008 SP2 / SP3 / SP4 Compact / Standard image, CE 5.0 / CE 6.0 underlying OS
Script engine Microsoft VBScript 5.6 runtime on Windows CE No Constrained Language Mode; legacy behavior
Configuration tool WinCC Flexible 2008 SP3 / SP4 ES Project must be compiled and transferred via ProSave / Ethernet

The official MP 277 operating instructions describe the panel's connectivity, file-system support, and the WinCC Flexible integration model. Reference the published manual for hardware limits before applying the workarounds in this article: MP 277 Operating Instructions (Siemens Support, attachment 23337820).

3. Root Cause Analysis

The MP 277 VBScript runtime pre-compiles a tag reference table the first time the panel boots into the project. Tags whose names appear as literal string constants in any compiled script are entered into the table during compilation. Tags accessed only through string concatenation (e.g., SmartTags("Pressione_US_" & i)) are not statically resolvable, so they are absent from the table.

Two cache layers cooperate to produce the symptom:

  1. Compile-time literal cache. Populated from literal SmartTags("...") accesses found by the WinCC Flexible script compiler. Tag names constructed via concatenation cannot be resolved statically and never enter this cache.
  2. Runtime value cache. Populated from PLC poll cycles and from on-demand acquisition triggered the first time the runtime requires a tag value. Tags whose acquisition mode is set to On demand or Cyclic on use are not polled from the PLC until first reference, and the very first reference returns the default value before the acquisition completes.

Inside a tight For-Next loop the runtime encounters SmartTags("Pressione_US_" & addZero(i)) for the first time. The value pointer has not been initialized in the connected PLC area; the runtime returns the default value (0 for numerics, empty string for alphanumeric tags). The line is written to the file with this default value, and because no project rebuild has occurred, the runtime does not retry the acquisition for subsequent loop iterations until the next script execution cycle.

Once the same script (or any script that touches the tag literally) explicitly references the same tag name, the cache is populated with the live PLC value, and future indirect access via concatenation returns the live value for the remainder of the runtime session. A panel reboot resets the cache and reproduces the bug.

4. Workarounds

Five approaches are field-proven. They are listed from least invasive (A) to most invasive (E).

4.1 Workaround A — Pre-touch subroutine (the canonical fix)

Declare a sub that explicitly assigns every tag name to a local variable. The WinCC Flexible script compiler registers each literal name in the tag cache; subsequent SmartTags() calls using string concatenation return the live value.

Sub loadVar()
    Dim a
    a = Pressione_Avanti_001
    a = Pressione_Avanti_002
    ' ... literal access up to ...
    a = Pressione_Avanti_200
End Sub

Call loadVar() at the top of any script that uses dynamic tag name construction. The sub body looks verbose but compiles to a no-op at runtime: the only side effect is cache registration. The pattern is the same workaround applied in WinCC Professional and TIA Portal V13–V15 when late-bound tag access is needed but the runtime cache is empty.

4.2 Workaround B — Pre-touch through an array

When the tag list is large (500+ tags) or generated dynamically, build an array of tag names and touch each entry once:

Dim tagNames(199)
For i = 0 To 199
    tagNames(i) = "Pressione_US_" & addZero(i + 1)
Next

' Force compile-time registration through explicit literal in a generator sub
Sub PreTouchAll
    Dim x
    x = SmartTags("Pressione_US_001")
    x = SmartTags("Pressione_US_100")
    x = SmartTags("Pressione_US_200")
End Sub

Workaround B reduces typing for very long ranges but still requires at least one literal reference for each unique tag name format. Use it together with the WinCC Flexible tag export to mechanically generate the literal list.

4.3 Workaround C — Continuous tag acquisition

Switch the acquisition mode of the connection to Continuous so the runtime keeps every tag current at the configured update rate:

  1. In WinCC Flexible project tree, right-click the connection to the PLC.
  2. Open Properties → Tags → Acquisition mode.
  3. Select Continuous for the connection.
  4. Rebuild the project and transfer to the MP 277.

Cost: higher network and PLC scan load. On a large project (1000+ tags) the PLC-side communication buffer can become saturated, increasing the risk of lost update events. Apply Continuous acquisition only on connections that handle the dynamically-tagged dataset, and keep On-demand acquisition elsewhere.

4.4 Workaround D — Recipe export with checksum

For batch recording of 100+ values, the documented Siemens pattern is a recipe with built-in export:

' Trigger built-in export from script
SmartTags("RecipeExportTrigger") = 1
' HMI writes a CSV with checksum via ExportDataRecordWithChecksum

Configure the recipe in WinCC Flexible → Recipes → define elements → Data record → Export path = \\server\share\file.csv. The runtime handles variable marshalling, includes timestamps, and computes the optional checksum. The advantage is that no dynamic SmartTags() access is needed; recipe elements are statically known to the runtime.

4.5 Workaround E — Archive export

For long-term logging, configure a tag archive and use the archive export functions:

' From the script runtime
SmartTags("ArchiveExportTrigger") = 1
' Configured export function: ExportTagLogCSV or ExportTagLogBinary

Archive exports operate on the internal archive database and are independent of the SmartTags cache. They are the recommended approach for shift reports, monthly logs, and any scenario in which the same tag is written multiple times with a timestamp.

5. Complete Working Example

The corrected script below writes 200 pressure values to a network file, applies Workaround A, and uses the Siemens FileCtl.File object (not desktop FileSystemObject, which is unavailable on Windows CE).

Sub WritePressureLog
    Dim i, f, sPath, sName, v
    sPath = "\\nas01\hmi_logs\Pressione_US_" & Year(Now) & _
            Right("0" & Month(Now), 2) & ".txt"

    ' --- Workaround A: force tag cache to populate ---
    Call loadVar()

    ' --- Open file in write mode ---
    Set f = CreateObject("FileCtl.File")
    f.FileName = sPath
    f.Mode = 8          ' fmOpenWrite (write + create if missing)
    f.Open

    f.LinePrint "Index;Tag;Value;Timestamp"

    For i = 1 To 200
        sName = "Pressione_US_" & addZero(i)
        v = SmartTags(sName)
        f.LinePrint i & ";" & sName & ";" & v & ";" & Now
    Next

    f.Close
    Set f = Nothing
End Sub

' --- Pre-touch sub: every tag name appears literally here ---
Sub loadVar
    Dim a
    a = Pressione_US_001
    a = Pressione_US_002
    ' ... (literal access lines 003 through 199 omitted for brevity) ...
    a = Pressione_US_200
End Sub

Function addZero(i)
    If i < 10 Then
        addZero = "00" & i
    ElseIf i < 100 Then
        addZero = "0" & i
    Else
        addZero = CStr(i)
    End If
End Function
Object naming. On the MP 277 the runtime only exposes the FileCtl.File COM object. Calls to CreateObject("Scripting.FileSystemObject") fail with error 429 — ActiveX component can't create object. If migrating from desktop VBScript, replace every FileSystemObject reference with FileCtl.File.

6. Verification Procedure

  1. Save the script in WinCC Flexible and rebuild the project (Project → Compiler → All).
  2. Transfer the compiled project to the MP 277 using ProSave over Ethernet or USB.
  3. Cycle power on the panel to clear the runtime tag cache.
  4. Trigger WritePressureLog from a button configured with the Click event.
  5. From a PC, open the destination file \\nas01\hmi_logs\Pressione_US_YYYY_MM.txt and verify:
    • File size > 0 bytes.
    • Number of data rows = 200 (excluding header).
    • Value column contains non-zero data for at least one active channel.
  6. Run a regression test: set acquisition mode to On demand, re-transfer, reboot, and trigger the script with the loadVar() call commented out. The expected result is the regression to zero — confirming the cache root cause.
  7. Restore acquisition mode to the original setting.

7. Diagnostic Matrix

Symptom Likely Cause Recommended Action
All numeric values in output file are 0; row count is correct First-time indirect access via string concatenation; on-demand tags not yet polled Add loadVar() pre-touch sub at top of script
Some values correct, others 0 Partial cache fill: only the touched indices resolve Pre-touch every index, or switch acquisition mode to Continuous
Script compile error in WinCC Flexible Tag missing from project, or data type mismatch between SmartTags() return and the assigned variable Verify tag exists in the project tree and matches the data type expected by the script
f.Open returns error 76 (path not found) Network share not reachable from the panel, or UNC path typo Map the share in Control Panel → Network on the MP 277 and store credentials
Error 429 on CreateObject("Scripting.FileSystemObject") Windows CE image lacks the Scripting runtime Replace with FileCtl.File as shown in section 5
File written but timestamp column shows default date Panel date/time not synchronized with the project Set the panel date/time via Control Panel → Date/Time, or use NTP via ProSave
Loop runs slowly (> 5 s for 200 iterations) PLC-side scan time plus per-tag acquisition Reduce acquisition rate, use Continuous mode with a longer cycle, or export via recipe

8. Operational and Safety Considerations

  • Maintenance mode. Place the MP 277 in maintenance mode before invoking CSV export scripts that take > 500 ms to complete. A long-running script on the operator panel blocks the HMI update thread and can mask alarms.
  • Network credentials. The MP 277 stores share credentials in the registry of the Windows CE image. Use a service account with write-only access to the share; never embed interactive domain credentials.
  • File retention. Implement a file rotation policy on the share. A 200-tag log written every minute produces ~30 MB per day; without rotation the share will exhaust its quota.
  • Acquisition mode side effects. Continuous acquisition on a connection carrying 1000+ tags increases PLC-side communication load. Confirm the PLC supports the resulting scan rate using the WinCC Flexible diagnostics view.
  • Migration path. The legacy WinCC Flexible runtime is end-of-life. New deployments should evaluate migration to a TIA Portal-based Comfort Panel with the modern VBScript / C scripting runtime, where the tag-cache limitation has been resolved.

9. References and Related Documentation

FAQ

Why does SmartTags() return zero the first time inside my For-Next loop on the MP277?

The WinCC Flexible VBScript runtime pre-compiles a tag reference table from literal SmartTags("...") calls. Tag names constructed by string concatenation are not statically resolvable and therefore are absent from the cache. Combined with On-demand acquisition, the first indirect reference returns the default value 0 before the runtime polls the PLC. Calling each tag literally once (Workaround A) populates the cache and forces the runtime to acquire the live value.

Do I have to declare all 200 tags in loadVar() or is there a smarter approach?

At minimum, each unique tag name format must appear literally in source code so the compiler can register it. For very long ranges you can use the project tag export to mechanically generate the pre-touch sub, or switch the connection to Continuous acquisition (Workaround C). For 100+ values recorded in batches, recipes (Workaround D) and archive exports (Workaround E) are the documented Siemens alternatives and avoid dynamic tag access entirely.

Can I use FileSystemObject on the MP277?

No. The Windows CE image on the MP 277 does not include the Microsoft Scripting Runtime, and CreateObject("Scripting.FileSystemObject") returns error 429 — ActiveX component can't create object. Use the FileCtl.File COM object that ships with the WinCC Flexible runtime for all file operations including open, line print, and close.

Is changing the tag acquisition mode to Continuous safer than the loadVar() workaround?

Continuous acquisition eliminates the cache cold-start symptom for every script on the connection, but it increases PLC-side communication load proportionally to the number of tags and the configured update rate. For a connection carrying 1000+ tags, verify with the WinCC Flexible diagnostics view that the PLC cycle time stays within budget before committing to Continuous. The loadVar() workaround is local to a single script and has no global performance impact.

Should I use Recipes instead of writing my own CSV from a script?

Yes, if the use case is recording a snapshot of 100+ values at a defined moment (shift end, batch end, alarm). Recipes are statically configured, generate CSVs with the optional checksum via ExportDataRecordWithChecksum, and do not rely on dynamic SmartTags access. Custom scripts are justified only when the dataset is not known at project compile time, when timestamps per row are required, or when the destination format is non-standard.

Back to blog