Overview: When VBScript Becomes Necessary in WinCC Flexible
Most routine HMI tasks in WinCC Flexible are handled without scripts: tag connections, animations, screen navigation, alarms, recipes, and the integrated data log are all configured through the engineering interface. VBScript becomes necessary when a task cannot be expressed declaratively—typically when an application must produce a free-form text or CSV file, react to a sequence of events with custom logic, communicate with a COM object, or persist operator-entered values that the recipe system cannot model efficiently. Two of the most common production scenarios that require VBScript are (1) logging machine commissioning positions to a removable storage card so they survive a PLC database download, and (2) writing audit-trail entries to a network share for traceability.
WinCC Flexible embeds Microsoft's VBScript 5.x engine in a constrained sandbox. The runtime is a strict subset of full VBScript: late binding via CreateObject is permitted only for objects the runtime explicitly exposes (notably FileCtl.File, FileSystem, and a small set of automation objects), and classic file I/O using Open ... As #1 is not available. All file work on panels is performed through the FileCtl automation server supplied with the WinCC Flexible Runtime.
Prerequisites: Runtime, Panels, and Storage Media
Before writing any script, confirm the engineering station and target panel satisfy the following:
- Engineering tool: SIMATIC WinCC Flexible 2008 SP5 (or later SP) with the matching panel image installed. The scripting editor is available under Project > Scripts > VBScripts.
- Runtime: WinCC Flexible Runtime 2008 SP2 or higher, or a panel firmware that bundles the same runtime (TP/OP 177B, TP/OP 277, MP 270B, MP 277, MP 370, MP 377, Comfort Panel migration projects, and PC Runtime).
- Storage media: An MMC or SD card formatted FAT16/FAT32, inserted before the panel boots. Industrial-grade cards (Siemens 6AV6 671-1CB00-0AX2 or equivalent) are recommended for write-intensive logging. Commercial consumer cards fail quickly under continuous logging.
- Panel ≥ MP 270B: Older OP 77B and TP 170A color units do not support VBScript. Use the matrix below to verify the target.
| Panel family | Script support | MMC/CF slot | USB host | Ethernet |
|---|---|---|---|---|
| OP 77B | No | No | No | No |
| TP 170A / TP 170B (mono) | No / Limited | No | No | No |
| TP 177B / OP 177B | Yes (SP4+) | MMC/SD | No | Option |
| TP 277 / OP 277 | Yes | MMC/SD | No | Yes |
| MP 270B / MP 277 | Yes | CF | Yes (MP 277 8") | Yes |
| MP 370 / MP 377 | Yes | CF + MMC/SD | Yes | Yes |
| PC Runtime | Yes (full VBScript) | Host file system | Host | Yes |
The VBScript Environment in WinCC Flexible
Scripts are bound to events on objects (screens, tags, screen items) or scheduled on a cyclic or one-shot trigger. Every script has access to a built-in object model documented in the WinCC Information System. The relevant objects for file work are:
-
HMI runtimeobject —Tags,Screens,SmartTagscollections used to read/write process values. -
FileCtl.File— sequential text file with line-oriented I/O. The only file object the runtime exposes for arbitrary path access. -
FileSystem— directory operations (Dir,FileLen,Kill,Name) on FAT volumes only. -
HMIRuntime.Trace— writes to the diagnostic log file (development tool only).
The runtime does not support WScript, Shell.Application, ADODB, or network drive mapping. Any attempt to instantiate these returns error 0x800401E3 (operation not supported). For database access from a panel, use PC Runtime with an OPC tunnel or migrate to WinCC (TIA Portal) Unified where available.
The FileCtl.File Object Reference
The automation server FileCtl.File implements a sequential, line-oriented text file. The following methods and properties are defined for the WinCC Flexible runtime:
| Member | Type | Description |
|---|---|---|
Open path, mode |
Sub | Opens a file. mode 1 = read, mode 2 = write/overwrite, mode 8 = append. mode 32 = random (not all panels). |
LinePrint s |
Sub | Writes s followed by CRLF. |
LineInput |
Property | Reads the next line (string). |
EOF |
Property | True when no more lines can be read. |
Close |
Sub | Closes the file. Always call, even on error. |
Path |
Property | Current file path. |
LineCount |
Property | Number of lines in the file. |
LoopCount |
Property | Line index of the current read/write position. |
Kill |
Sub | Static method that deletes a file at the supplied path. |
Long file names are supported on MP 270B and later. Filenames follow 8.3 on OP/TP 177B panels; plan storage paths accordingly when shipping to mixed fleets. Character encoding is ANSI; unicode BOMs in source files are not supported inside script bodies.
Step-by-Step: Logging PLC Tag Positions to an MMC File
The original use case—saving ≈ 35 machine positions plus a stamp—maps cleanly to a single script bound to a button's Click event. The procedure below walks through the recommended implementation.
- Open the project in WinCC Flexible and create the tag list with the position tags:
Pos_A_neg,Pos_A_0throughPos_A_18,Pos_P_1throughPos_P_3,Pos_F_neg,Pos_F_0throughPos_F_12. All tags should be of type Real (32-bit float, IEEE-754) to match the S7 DB layout. - Navigate to Project > Scripts > VBScripts > Add new. Name the script
Save_Positions. - Open the screen that hosts the operator button. In the events list for the button, select Click and assign
Save_Positions. - Paste the script body shown in the listing below. Note the explicit path constant, the
On Error Resume Nextblock, theErr.Cleardiscipline, and theSet f = Nothingat the end. - Compile the project (Project > Compiler > Check consistency) and download the runtime to the panel.
' --- Save_Positions.vbs ---
' Bound to: Button "Save positions" - Event: Click
Dim f, path, ts
path = "\Storage Card MMC\Posities.txt"
On Error Resume Next
Set f = CreateObject("FileCtl.File")
If Err.Number <> 0 Then
ShowSystemAlarm "Error #" & CStr(Err.Number) & " " & Err.Description
Err.Clear
Exit Sub
End If
' Always overwrite; use mode 8 to append instead.
f.Open path, 2
If Err.Number <> 0 Then
ShowSystemAlarm "Error #" & CStr(Err.Number) & " " & Err.Description
Err.Clear
Set f = Nothing
Exit Sub
End If
' Build a single timestamp string once.
ts = Year(Now) & "-" & Right("0" & Month(Now), 2) & "-" & _
Right("0" & Day(Now), 2) & " " & _
Right("0" & Hour(Now), 2) & ":" & _
Right("0" & Minute(Now), 2) & ":" & _
Right("0" & Second(Now), 2)
f.LinePrint "=== Save run at " & ts & " ==="
f.LinePrint "Positie Aanvoer Pneg: " & Pos_A_neg
f.LinePrint "Positie Aanvoer P0: " & Pos_A_0
f.LinePrint "Positie Aanvoer P1: " & Pos_A_1
f.LinePrint "Positie Aanvoer P2: " & Pos_A_2
f.LinePrint "Positie Aanvoer P3: " & Pos_A_3
f.LinePrint "Positie Aanvoer P4: " & Pos_A_4
f.LinePrint "Positie Aanvoer P5: " & Pos_A_5
f.LinePrint "Positie Aanvoer P6: " & Pos_A_6
f.LinePrint "Positie Aanvoer P7: " & Pos_A_7
f.LinePrint "Positie Aanvoer P8: " & Pos_A_8
f.LinePrint "Positie Aanvoer P9: " & Pos_A_9
f.LinePrint "Positie Aanvoer P10: " & Pos_A_10
f.LinePrint "Positie Aanvoer P11: " & Pos_A_11
f.LinePrint "Positie Aanvoer P12: " & Pos_A_12
f.LinePrint "Positie Aanvoer P13: " & Pos_A_13
f.LinePrint "Positie Aanvoer P14: " & Pos_A_14
f.LinePrint "Positie Aanvoer P15: " & Pos_A_15
f.LinePrint "Positie Aanvoer P16: " & Pos_A_16
f.LinePrint "Positie Aanvoer P17: " & Pos_A_17
f.LinePrint "Positie Aanvoer P18: " & Pos_A_18
f.LinePrint "Positie Ponsbank P1: " & Pos_P_1
f.LinePrint "Positie Ponsbank P2: " & Pos_P_2
f.LinePrint "Positie Ponsbank P3: " & Pos_P_3
f.LinePrint "Positie Afvoer Pneg: " & Pos_F_neg
f.LinePrint "Positie Afvoer P0: " & Pos_F_0
f.LinePrint "Positie Afvoer P1: " & Pos_F_1
f.LinePrint "Positie Afvoer P2: " & Pos_F_2
f.LinePrint "Positie Afvoer P3: " & Pos_F_3
f.LinePrint "Positie Afvoer P4: " & Pos_F_4
f.LinePrint "Positie Afvoer P5: " & Pos_F_5
f.LinePrint "Positie Afvoer P6: " & Pos_F_6
f.LinePrint "Positie Afvoer P7: " & Pos_F_7
f.LinePrint "Positie Afvoer P8: " & Pos_F_8
f.LinePrint "Positie Afvoer P9: " & Pos_F_9
f.LinePrint "Positie Afvoer P10: " & Pos_F_10
f.LinePrint "Positie Afvoer P11: " & Pos_F_11
f.LinePrint "Positie Afvoer P12: " & Pos_F_12
If Err.Number <> 0 Then
ShowSystemAlarm "Error #" & CStr(Err.Number) & " " & Err.Description
Err.Clear
Else
ShowSystemAlarm "Storage of the data was successful!"
End If
f.Close
Set f = Nothing
Use ShowSystemAlarm to surface script status to the operator, but be aware that every call generates an alarm log entry. Reserve the call for failure paths or success of a destructive action such as a save.
Adding Time and Date Stamps
You do not need to convert the PLC DATE_AND_TIME (B#16#0A) format into integers for the file—WinCC Flexible exposes the panel's own clock through the standard VBScript Now, Date, and Time functions. If you require a deterministic, network-synchronized timestamp, drive the panel's clock from the PLC using the Date/Time PLC area in Project > Device Settings > Date/Time. The runtime will then reflect the S7 system time within ≈ 1 s of the synchronization interval.
The ts string built in the listing above produces ISO-8601-compatible stamps such as 2024-03-14 09:42:07. If the operator's region uses a non-Gregorian calendar or a day-first convention, substitute FormatDateTime(Now, vbShortDate) and FormatDateTime(Now, vbLongTime) and concatenate the results.
For per-line stamps (for example, one stamp per LinePrint), wrap a helper:
Function Stamp()
Stamp = Year(Now) & "-" & Right("0" & Month(Now), 2) & "-" & _
Right("0" & Day(Now), 2) & " " & _
Right("0" & Hour(Now), 2) & ":" & _
Right("0" & Minute(Now), 2) & ":" & _
Right("0" & Second(Now), 2) & ": "
End Function
Calling Stamp() before each LinePrint yields a CSV file directly consumable by Excel's Data > From Text wizard.
Network File Access over Ethernet
Yes—text files can be reached from a PC on the same Ethernet network. There are two distinct mechanisms and the choice depends on the panel class.
1. SMB / UNC path on PC Runtime or MP 377 with Windows CE 6
On PC Runtime, the standard UNC syntax works as long as the runtime Windows service has share access rights:
path = "\\engineering-pc\HMI_Logs\Machine42_Posities.txt"
For Windows CE panels, the path must use the \Host\Share convention with a net share created on the engineering station. Authentication is the panel's default user; map the share to allow Everyone if the machine is on a closed network, or create a dedicated panel user with a known password and call WNetAddConnection2—note that the latter is not exposed in the WinCC Flexible script sandbox.
2. Direct file retrieval from the panel
The ProSave / WinCC Flexible backup tool can read files from \Storage Card MMC\ and the internal flash over Ethernet using the S7ONLINE / TCP port 102 (ISO-on-TCP) and 103 (S7 communication). The operator simply opens ProSave, selects File > Transfer > Read files from the panel, browses to Storage Card MMC, and copies the file. No script changes are required.
Error Handling, Diagnostic Codes, and Recovery
The runtime sets Err.Number on every failed FileCtl call. The most common values are:
| Err.Number (hex) | Meaning | Likely cause | Recovery |
|---|---|---|---|
| 0x800A0044 | Path not found | Card removed, wrong drive prefix, or file in subdirectory that does not exist | Verify \Storage Card MMC\ is present; FileSystem.Dir the parent folder before opening. |
| 0x800A0035 | File not found | Mode 1 used on a file that does not exist | Create the file with mode 2 first or check FileSystem.FileLen > 0. |
| 0x800A0005 | Invalid procedure call or argument | Bad mode, unsupported path, invalid filename characters | Confirm mode is 1/2/8; strip : * ? " < > | from names. |
| 0x80070020 | Sharing violation | File is open in another process (e.g. ProSave) | Close the file in the other tool; add a retry loop with 250 ms backoff. |
| 0x80070070 | Disk full | MMC/CF is full | Archive or Kill old logs; check FileSystem.FreeSpace before writing. |
| 0x800704C7 | Path too long | UNC path exceeds ~120 characters on CE | Map a drive letter or shorten folder names. |
| 0x800401E3 | Operation not supported | Instantiated an unsupported COM object | Restrict to FileCtl.File and FileSystem. |
Wrap each FileCtl call in its own If Err.Number <> 0 Then test. Pair this with a centralized status tag (e.g. SaveStatus as a Word tag) so an external SCADA can monitor failures without parsing alarm history.
Storage Media: Path Conventions, Endurance, and Limits
| Prefix | Media | Notes |
|---|---|---|
\Flash\ |
Internal flash | ≤ 6 MB free on most panels. Reserve for runtime files. Not for logs. |
\Storage Card MMC\ |
MMC / SD card | Recommended for log files. Up to 2 GB (FAT16) or 32 GB (FAT32) on MP 377. |
\Storage Card CF\ |
CompactFlash | MP 270B / MP 370 / MP 377. Higher write endurance than MMC. |
\Storage Card USB\ |
USB stick | MP 277 8" and MP 377. Hot-swap supported only when script is not holding a handle. |
\Storage Card HD\ |
Internal hard disk | PC Runtime only. |
Industrial MMC cards are rated for ≈ 100,000 write cycles per block and support wear-leveling controllers. A 35-line save performed once per shift for 5 years yields < 2,000 writes per block—comfortably within rated life. By contrast, saving every 100 ms (a common mistake) reaches 1.4×109 writes per block and will kill a consumer card in days.
Scripts vs. Native Functions: When to Use Each
Before writing a script, check whether the built-in mechanisms cover the requirement. The table summarizes the decision boundaries.
| Requirement | Best tool | Reason |
|---|---|---|
| Time-stamped process log of a small set of tags | Data Log (alarm or value logging) | Circular buffer, viewer, export to CSV, no scripting. |
| Structured set of operator-edited parameters | Recipe view + Recipe data records | Type-safe, transferable to PLC DBs, supports Save to file / Read from file. |
| Free-form text report with computed fields | VBScript + FileCtl
|
Native functions do not allow concatenation or computed strings. |
| Audit trail with operator, timestamp, and reason | Audit Trail (option) or VBScript | Audit Trail is GMP-ready; scripting requires a custom schema. |
| External database write | Migrate to WinCC Unified / OPC UA | WinCC Flexible has no ADODB or database automation. |
| Web service call from the panel | Not supported | No HTTP client in WinCC Flexible runtime. |
Verification and Commissioning Checklist
- Insert a freshly formatted MMC card (FAT32, 32 KB cluster) and power-cycle the panel.
- Boot the runtime and open the operator screen. Press the save button.
- Confirm the alarm line Storage of the data was successful! appears and clears within 5 s.
- Pull the card, mount it on a PC, and verify
Posities.txtcontains the expected number of lines, the timestamp matches the panel clock, and the float values match the PLC online view to within 0.001 mm. - Force a failure: remove the card, press the button, confirm a system alarm with the proper
Err.Numberis raised and the script does not hang the panel. - Reinsert the card, re-run, and confirm the file is rewritten (mode 2) or appended correctly (mode 8).
- Reboot the panel and confirm the runtime still starts with the same card in place—
FileCtlhandles must not be left open across warm restarts. - Back up the runtime project to the same MMC card under
\Storage Card MMC\ProjectBackupso the data file and project version travel together.
FAQ
Does the panel clock need to be synchronized with the PLC for the timestamp to be correct?
No. The Now function returns the panel's local time, which is set from Panel Settings > Date/Time or synchronized from the PLC via the Date/Time PLC area. If both remain unsynchronized, logs from the PLC and HMI will diverge—enable PLC master clock synchronization for traceable timestamps.
Can I append to the same file across multiple panel reboots?
Yes. Change the open mode from 2 to 8 in f.Open path, 8. Each save then appends a new block; include a timestamped header line (as in the example) to delimit blocks. For automatic rotation, use a filename that includes the date (Posities_" & Year(Now) & Month(Now) & Day(Now) & ".txt) and bind the save event to a one-second-of-day trigger.
Why does my script fail with error 0x800A0044 even though the card is inserted?
The most common cause on TP/OP 177B panels is the prefix spelling: use \Storage Card MMC\ (with the leading double backslash and trailing backslash) and not /Storage Card MMC/. The runtime expects backslashes and the exact string. On PC Runtime, mount the SD card with a drive letter and use D:\Posities.txt instead.
How large can the log file become before performance suffers?
On MP 277-class hardware, opening a single FileCtl.File handle is O(1) regardless of size, but each LineInput call walks the file linearly. Keep read loops under 5,000 lines per script invocation; for larger files, use a binary access pattern or split the data into daily files. A 1 MB text file holds ≈ 30,000 lines of the position report above.
Is there a way to write directly to a SQL database from the panel?
Not with WinCC Flexible on a Windows CE panel. The runtime does not expose ADODB, ODBC, or HTTP. For database logging, use the panel's Value Log with a circular buffer, transfer the resulting CSV to a PC with ProSave, and import it server-side; or migrate to PC Runtime / WinCC Unified where OPC UA tunneling or a separate service can perform the write.
What is the correct way to retrieve the saved file over Ethernet?
Use ProSave on a PC connected to the same subnet, choose File > Read files from the panel with the panel's IP and the S7ONLINE access point, and browse to \Storage Card MMC\Posities.txt. ProSave uses port 102 (ISO-on-TCP) and 103 (S7) and requires no shared folder on the panel. The script itself does not need to change.