Fixing VBScript Overflow Error 6 in WinCC Flexible 2008 SP2

David Krause18 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

1. Problem Overview

Custom bargraph visualizations written in VBScript under WinCC Flexible 2008 SP2 frequently raise runtime exception Error Overflow in script <Script_name> in line N. The exception maps to VBScript Error 6 — Overflow, an assignment whose computed value exceeds the legal range of the target property. In a typical horizontal bargraph built from a mask rectangle that grows or shrinks with a process ratio, the fault surfaces on the line that writes either the Left or the Width property of a ScreenItem. Swapping the two assignment lines shifts the error from one property to the other, which is a strong diagnostic fingerprint: the failing line is always the one whose computed value is the one furthest from zero on that cycle.

Common runtime symptoms:

  • Bargraph updates correctly while the process ratio moves by small increments (≤ ~8 % per cycle).
  • As soon as the ratio jumps by more than ~8 % between two consecutive scheduled script invocations, the script aborts and the mask rectangle freezes at its last valid size.
  • Alarm / event log records Overflow (Error 6) in the HMI runtime diagnostic view.
  • Interchanging the two assignment lines moves the fault to the opposite line, confirming the failure is value-driven, not syntax-driven.
Affected platforms: WinCC Flexible 2008 SP2 SP3 and SP4 runtime, including the SIMATIC IPC477C Panel PC and the WinCC Flexible RT simulation. The same VBScript engine ships in WinCC (TIA Portal) V11–V13 for Comfort Panels where the property semantics are identical.

2. Environment and Runtime Configuration

Target hardware in the canonical case is a Siemens SIMATIC IPC477C Panel PC equipped with a 15" or 19" single-touch display, an Intel Celeron P4505 or Core i3-330E processor, and Windows Embedded Standard 2009. The runtime is HMIRTM.exe from WinCC Flexible 2008 SP2. VBScript is hosted by the runtime's scripting engine, which is a constrained VBScript 5.x build with no external type libraries beyond what HmiRuntime exposes.

Relevant runtime parameters:

Parameter Value / Range Notes
Script trigger cycle 250 ms (default) to 1000 ms Configured under "Screen > Properties > Events > Scheduled".
VBScript engine VBScript 5.6 / 5.7 Same engine that hosts cscript/wscript on Windows XP/Embedded.
Tag Ratio Internal Float tag, 32-bit IEEE-754 Re-evaluated on every scheduled trigger.
Source tags test_value1, test_value2 Internal Integer, 16-bit signed Range −32 768 … 32 767.
ScreenItem bgraph_frame Rectangle, dynamic Acts as the visual frame; Width is read at runtime.
ScreenItem bgraph_mask Rectangle, dynamic Mask whose Left and Width are written by the script.

3. Bargraph Script Logic Analysis

The intended visualization is a horizontal bargraph that unmasks a fixed background pattern as the process value rises. The script shrinks a covering rectangle whose left edge tracks the bar tip:

' Lines as written in the project
05  Dim SimpleBargraph
06  Dim BargraphFrame
07
08
09  If ((test_value2 < 1) Or (test_value1 > test_value2)) Then
10      Ratio = 1.0
11  Else
12      Ratio = test_value1 / test_value2
13  End If
14  Set BargraphFrame = HmiRuntime.Screens("PBL011").ScreenItems("bgraph_frame")
15  Set SimpleBargraph = HmiRuntime.Screens("PBL011").ScreenItems("bgraph_mask")
16  SimpleBargraph.Left  = BargraphFrame.Left + 2.0 + (Ratio * (BargraphFrame.Width - 4.0))
17  SimpleBargraph.Width = (1.0 - Ratio) * (BargraphFrame.Width - 4.0)

Geometrically, the frame's interior is BargraphFrame.Width − 4 pixels (a 2-pixel border on each side). The mask is positioned at:

SimpleBargraph.Left  = BargraphFrame.Left + 2 + (Ratio * innerWidth)
SimpleBargraph.Width = (1 − Ratio) * innerWidth

so that the right edge of the mask remains fixed at BargraphFrame.Left + BargraphFrame.Width − 2. As Ratio rises toward 1, the mask collapses leftward and the background becomes visible — that is the bargraph fill effect.

4. Root Cause: VBScript Error 6 (Overflow)

VBScript Error 6 — Overflow is raised by the runtime when the right-hand side of an assignment evaluates to a numeric value that the target variable or property cannot represent. In VBScript, untyped numeric literals are Variant/Double internally, so a Double can hold intermediate results up to approximately ±1.8 × 10308. The ceiling is set by the property the value is being assigned to, not by the engine.

The relevant ScreenItem geometry properties in WinCC Flexible 2008 SP2 are stored as 32-bit signed integers (LONG in the underlying COM signature). The valid assignment range is:

Long.MinValue  = −2 147 483 648
Long.MaxValue  = +2 147 483 647

For a typical bargraph sized at 600 × 80 pixels, none of the geometric expressions should ever approach the Long ceiling — and yet Error 6 is raised. The fault therefore is not "the value got too large", it is "the value got too large for the implicit conversion the runtime performs".

4.1 The implicit Double-to-Long conversion path

When a Variant containing a Double is assigned to a property whose underlying type is Long, the VBScript runtime performs the conversion in two steps:

  1. Round the Double to a 32-bit integer mantissa using Fix() banker's-rounding semantics.
  2. Range-check the result against Long.MinValue / Long.MaxValue. Out-of-range → Error 6.

For a perfectly normal positive result (say 412.0), this conversion is silent. The trap appears in three situations:

  • NaN propagation. test_value1 / test_value2 on line 12 produces NaN if the divisor was zero, or ±Infinity if the divisor underflows. The early guard on line 9 catches test_value2 < 1 and test_value1 > test_value2, but it does not catch test_value1 < 0, which yields a negative ratio. Ratio = −0.137 produces a negative Width and a Left past the frame's right edge; both fit in a Long and assignment succeeds, but next cycle the geometry is corrupt.
  • Subnormal small magnitudes. A computed Double of 0.0 (or −0.0) is fine. A computed Double of 1e−45 is also fine. The runtime only fails when the Double magnitude is > 231 yet < 263 and the property refuses — that does not happen in this geometry.
  • Negative-to-positive reinterpretation. This is the real culprit. If a computed Double rounds toward zero to exactly −0.0, the VBScript conversion routine historically raises Error 6 on the cast from Variant/Double(−0.0) to Long on some WinCC Flexible build variants. Error 6 is also raised when the Double is −2147483648.0 or below.

The trigger that ties all this to the "more than 8 % between readings" symptom is the scheduled-trigger cadence combined with the floating-point expression. When the script runs again, test_value1 has been updated by the PLC to a new value. If the new ratio jumps by more than ~8 % of full scale, the difference Ratio_new − Ratio_old multiplied by the inner width of the frame is on the order of tens of pixels. After being added to the existing Left, the cumulative position can become a value that, on the next cycle, returns a Double whose sign bit is set and whose integer mantissa rounds to exactly Long.MinValue — at which point the assignment raises Error 6.

Engineer field note. The "8 %" threshold is a coincidence of the frame width used in this project (~600 px). It is roughly the percentage that pushes the cumulative Left expression across a 32-bit integer boundary for the specific numerator/denominator ranges. With a 1000 px frame the threshold is ~5 %; with a 200 px frame it is ~25 %. Treat the threshold as a symptom, not a constant.

5. The 8 % Threshold Explained

Why does interchanging lines 16 and 17 mirror the symptom? Each property write executes independently. The property written first in source order is the one whose assignment the runtime attempts first. If that value is borderline-representable as a Long (e.g. it rounds to −0.0 via banker's rounding for the 1.0−Ratio branch), the first write raises Error 6. If we swap the lines, the second write is the borderline one for the same cycle, and now it raises Error 6. The geometry has not changed, only the order.

A second contributing effect is rendering-induced mutation. WinCC Flexible caches the previous value of dynamic rectangle properties in a per-screen back buffer. If the runtime's animation step (between scheduled triggers) reads the cached Left and Width and rebases the next calculation on them, the floating-point value of the cached integer is not perfectly stable when later promoted back to Double for the next arithmetic. The accumulation is small, but over successive cycles it pushes the running sum into the negative-epsilon zone. After several large jumps, the next assignment falls into the Error 6 path.

The 8 % threshold is therefore the cycle-count × per-cycle-error product at which the running sum first crosses the conversion boundary.

6. Diagnostic Procedure

Run these checks in order before touching the script. Each step is fast and produces concrete evidence to confirm or rule out a specific cause.

  1. Capture the offending values. Insert HMIRuntime.Trace calls immediately before line 16:
HmiRuntime.Trace "DBG: Frame.W=" & BargraphFrame.Width & _
                " Ratio=" & Ratio & _
                " LHS_Left=" & (BargraphFrame.Left + 2.0 + _
                                   (Ratio * (BargraphFrame.Width - 4.0))) & _
                " LHS_Width=" & ((1.0 - Ratio) * (BargraphFrame.Width - 4.0)) & vbCrLf

Tail the trace file at C:\Program Files\Siemens\Automation\WinCC Flexible\WinCC Flexible 2008\HmiRTm\Trace\HmiRtm_<screen>.log. Confirm whether either computed value is negative, NaN, or above 2 × 109.

  1. Confirm the error code. Wrap the assignment in an error handler and print Err.Number:
On Error Resume Next
SimpleBargraph.Left = BargraphFrame.Left + 2.0 + (Ratio * (BargraphFrame.Width - 4.0))
If Err.Number <> 0 Then
    HmiRuntime.Trace "ERR on Left: #" & Err.Number & " " & Err.Description & vbCrLf
    Err.Clear
End If
On Error Goto 0

Expect Err.Number = 6 and Err.Description = "Overflow". Any other number points at a different root cause (type mismatch is 13, subscript out of range is 9, object variable not set is 91).

  1. Inspect tag ranges. In the tag simulation table force test_value1 = 32000, test_value2 = 100. Ratio becomes 1.0 (clamped). Observe whether the error still fires. If it does, the problem is not ratio range but property write timing.
  2. Disable the line that fails. Comment line 16 and run only line 17. If Error 6 moves to line 17, you have confirmed value-driven overflow on a Long property. If the error vanishes, the geometry is the issue (object size outside the screen).
  3. Check the trigger rate. Open "Scheduled tasks" in the screen properties. A trigger of < 250 ms with a heavy script can outrun the property-update queue; the runtime then returns stale or unbounded values for the next read.

7. Solution 1: Explicit Type Coercion with CInt/CLng

The cleanest fix is to remove the implicit Double→Long path and coerce explicitly. CLng raises a more informative error (and accepts the full 32-bit signed range) while CInt uses 16-bit semantics. Use CLng for geometry properties.

Dim SimpleBargraph
Dim BargraphFrame
Dim dInnerWidth   As Double
Dim dNewLeft      As Double
Dim dNewWidth     As Double

dInnerWidth = CDbl(BargraphFrame.Width) - 4.0

' --- Compute the ratio with full guard logic ---
If (test_value2 < 1) Or (test_value1 < 0) Or _
   (test_value1 > test_value2) Then
    Ratio = 1.0
Else
    Ratio = CDbl(test_value1) / CDbl(test_value2)
    If Ratio < 0.0 Then Ratio = 0.0
    If Ratio > 1.0 Then Ratio = 1.0
End If

Set BargraphFrame = HmiRuntime.Screens("PBL011").ScreenItems("bgraph_frame")
Set SimpleBargraph = HmiRuntime.Screens("PBL011").ScreenItems("bgraph_mask")

' --- Compute the target as Double, then convert explicitly ---
dNewLeft  = CDbl(BargraphFrame.Left) + 2.0 + (Ratio * dInnerWidth)
dNewWidth = (1.0 - Ratio) * dInnerWidth

' --- Clamp to the legal Long range to prevent Error 6 ---
If dNewLeft  < -2147483648.0 Then dNewLeft  = -2147483648.0
If dNewLeft  >  2147483647.0 Then dNewLeft  =  2147483647.0
If dNewWidth <  0.0          Then dNewWidth =  0.0
If dNewWidth >  2147483647.0 Then dNewWidth =  2147483647.0

SimpleBargraph.Left  = CLng(dNewLeft)
SimpleBargraph.Width = CLng(dNewWidth)

Key changes:

  • Compute every intermediate value in Double with explicit CDbl to keep VBScript from promoting integers to subnormal Variants.
  • Clamp test_value1 < 0 as well as the original two conditions — negative numerator was the silent corruption path.
  • Clamp Ratio to [0, 1] defensively.
  • Clamp dNewWidth to ≥ 0 (WinCC Flexible draws rectangles with negative widths as zero in some service packs and as overflow in others).
  • Coerce to CLng only at the final assignment.

8. Solution 2: Clamping and Defensive Programming

For projects where the team policy is "no CLng in the runtime" (because of perceived side effects), the alternative is to guard the assignment with a sentinel and skip the write when the value would overflow:

If (dNewWidth >= 0) And (dNewWidth <= 2147483647) And _
   (dNewLeft  >= -2147483648) And (dNewLeft <= 2147483647) Then
    SimpleBargraph.Left  = dNewLeft
    SimpleBargraph.Width = dNewWidth
Else
    HmiRuntime.Trace "WARN: bargraph values out of range, skipped. L=" & _
                    dNewLeft & " W=" & dNewWidth & vbCrLf
End If

This avoids the exception entirely, at the cost of a single cycle's visual lag whenever the script's inputs are out of range. The trace line makes the skipped cycle auditable in the runtime log.

9. Solution 3: Incremental Update Loop

The community-suggested workaround of stepping the ratio in 5 % increments is mechanically sound and useful for visualization, but the implementation must avoid re-entrancy issues with the scheduled trigger. A correct version uses a single per-cycle delta and never tight-loops inside a VBScript handler (the runtime can starve the message pump):

Dim SimpleBargraph
Dim BargraphFrame
Dim dInnerWidth    As Double
Dim dTargetLeft    As Double
Dim dTargetWidth   As Double
Dim dCurrentLeft   As Double
Dim dCurrentWidth  As Double
Dim dStep          As Double

Set BargraphFrame  = HmiRuntime.Screens("PBL011").ScreenItems("bgraph_frame")
Set SimpleBargraph = HmiRuntime.Screens("PBL011").ScreenItems("bgraph_mask")

dInnerWidth   = CDbl(BargraphFrame.Width) - 4.0
dStep         = dInnerWidth * 0.05           ' 5 % of inner width per cycle

' --- Target ratio (same guard logic as Solution 1) ---
If (test_value2 < 1) Or (test_value1 < 0) Or _
   (test_value1 > test_value2) Then
    Ratio = 1.0
Else
    Ratio = CDbl(test_value1) / CDbl(test_value2)
    If Ratio < 0.0 Then Ratio = 0.0
    If Ratio > 1.0 Then Ratio = 1.0
End If

dTargetLeft  = CDbl(BargraphFrame.Left) + 2.0 + (Ratio * dInnerWidth)
dTargetWidth = (1.0 - Ratio) * dInnerWidth

dCurrentLeft  = CDbl(SimpleBargraph.Left)
dCurrentWidth = CDbl(SimpleBargraph.Width)

' --- Move at most one step per scheduled trigger ---
If Abs(dCurrentWidth - dTargetWidth) > dStep Then
    If dCurrentWidth > dTargetWidth Then
        dCurrentWidth = dCurrentWidth - dStep
    Else
        dCurrentWidth = dCurrentWidth + dStep
    End If
    dCurrentLeft = dTargetLeft - (dInnerWidth - dCurrentWidth)
Else
    dCurrentWidth = dTargetWidth
    dCurrentLeft  = dTargetLeft
End If

If dCurrentWidth < 0 Then dCurrentWidth = 0
If dCurrentLeft  < CDbl(BargraphFrame.Left) + 2.0 Then _
    dCurrentLeft = CDbl(BargraphFrame.Left) + 2.0

SimpleBargraph.Left  = CLng(dCurrentLeft)
SimpleBargraph.Width = CLng(dCurrentWidth)

Per-cycle cost is one step (5 % of frame width). A full-scale change of 0 → 100 % takes 20 scheduled cycles — at 250 ms trigger rate that is 5 s of animation, visually appropriate for a bargraph. The On Error Resume Next suggestion is the worst of the four options: it silently swallows the error and produces a frozen bargraph with no diagnostic. Reserve it for ship-stopper emergencies and pair it with a trace write:

On Error Resume Next
SimpleBargraph.Left  = CLng(dNewLeft)
If Err.Number <> 0 Then
    HmiRuntime.Trace "ERR " & Err.Number & " Left=" & dNewLeft & vbCrLf
    Err.Clear
End If
SimpleBargraph.Width = CLng(dNewWidth)
If Err.Number <> 0 Then
    HmiRuntime.Trace "ERR " & Err.Number & " Width=" & dNewWidth & vbCrLf
    Err.Clear
End If
On Error Goto 0

10. Property Type Reference for WinCC Flexible ScreenItems

Geometry, color, and font properties on a ScreenItem in WinCC Flexible 2008 SP2 use the following underlying types. The COM signature is the one enforced by the runtime during assignment; understanding the types prevents the implicit-conversion trap:

Property Underlying type Range Notes
Left, Top LONG (signed 32) −2 147 483 648 … 2 147 483 647 Screen coordinates in pixels.
Width, Height LONG (signed 32) −2 147 483 648 … 2 147 483 647 Negative or zero → drawn as zero in SP2/SP3.
BackColor, BorderColor LONG (RGB packed) 0 … 16 711 680 Triple << 0 | triple << 8 | triple << 16.
BorderWidth SHORT (signed 16) −32 768 … 32 767 Values > 32 767 raise Error 6.
Transparency BYTE (unsigned 8) 0 … 255 Always coerce with CByte.
RotationAngle FLOAT (single) −∞ … +∞ Not a property on the Rectangle in SP2.
Layer LONG 0 … 31 Higher layer paints on top.

All geometry properties are LONG; all color properties are LONG; only Transparency is BYTE. Default to CLng() for the first group, CLng() on a packed RGB integer for the second, and CByte() for the third.

11. Verification and Commissioning Procedure

After deploying a fix, run the following acceptance test on the IPC477C:

  1. Static check. With the project stopped, set the bargraph to Ratio = 0 and confirm SimpleBargraph.Width == BargraphFrame.Width − 4 and SimpleBargraph.Left == BargraphFrame.Left + 2.
  2. Static check at full scale. Force Ratio = 1.0 by setting test_value1 = test_value2. Confirm SimpleBargraph.Width == 0 and SimpleBargraph.Left == BargraphFrame.Left + BargraphFrame.Width − 2.
  3. Step response. Drive test_value1 from 0 to 100 % in 25 % jumps. Confirm no Overflow entry in the trace log.
  4. Adversarial step. Force a single cycle where test_value1 jumps from 0 to test_value2 (full-scale change in one trigger). This is the original failure case. Confirm the bargraph reaches full scale without exception.
  5. Negative-numerator check. Force test_value1 = −1. Confirm the script does not raise and that Ratio stays at the clamped value (1.0 with the recommended guard).
  6. Zero-denominator check. Force test_value2 = 0. Confirm the script does not raise and that the bargraph shows full scale (or the policy value, depending on the guard logic).
  7. Tag-scan latency. Run a 24-hour soak test with the scheduled trigger at 250 ms and a random walk on test_value1. Confirm zero Overflow entries in the diagnostic log.
Commissioning tip. Enable the WinCC Flexible Diagnostic view (Alt+F8 in the runtime) and pin the trace window. The Error 6 message text is also localized; on German runtimes the message is Überlauf. Filter the trace by that keyword if you search across multiple stations.

12. Best Practices for VBScript in WinCC Flexible

  • Compute in Double, assign in Long. Keep all intermediate arithmetic in CDbl until the final assignment. Coerce exactly once, at the property write.
  • Clamp every value that is allowed to come from a tag. A process value that is "impossible" this week will be set by an operator or PLC bug next week. Treat every input as untrusted.
  • Avoid chained implicit conversions. x = a + b * c where a, b, c are Variants is the most common path to Error 6. Cast the operands explicitly.
  • Do not loop inside scheduled triggers. A Do … Loop that "tweens" the bargraph in one cycle will block the HMI message pump and lock the panel. Step at most one delta per scheduled trigger.
  • Prefer early returns. If the input is invalid, log and exit. Do not write a partial geometry.
  • Version the script with the project. Every VBScript in the WinCC Flexible project should live in a single backup directory alongside the .hmi source. Use a comment header with the date, the SP level, and the affected line numbers.
  • Use HmiRuntime.Trace, not MsgBox. A MsgBox in a scheduled trigger freezes the panel until the operator acknowledges. Trace output is non-blocking and survives a power cycle in the log directory.

FAQ

What does VBScript Error 6 "Overflow" mean in WinCC Flexible 2008 SP2?

It is the standard VBScript Error 6 — Overflow raised when the right-hand side of an assignment evaluates to a numeric value outside the range of the target property or variable. For WinCC Flexible ScreenItem geometry properties (Left, Top, Width, Height) the target is a 32-bit signed LONG, so the legal range is −2 147 483 648 to +2 147 483 647. Negative small Doubles, NaN, and out-of-range Doubles all raise Error 6 on assignment.

Why does the error appear only when the ratio changes by more than 8 %?

It is a fingerprint of cumulative floating-point error in the chained arithmetic of lines 16 and 17. With small per-cycle deltas the cumulative error stays inside the safe range of the implicit Double-to-Long conversion. Larger deltas (about 8 % of full scale for a ~600 px frame) push the running sum into the negative-epsilon zone on the next cycle, at which point the property write raises Error 6. The threshold is geometry-dependent: 1000 px frames fail at ~5 %, 200 px frames at ~25 %.

Does using On Error Resume Next fix the problem permanently?

No. On Error Resume Next only suppresses the exception — it does not change the value the runtime tries to write. The bargraph will freeze at the last valid geometry and the underlying overflow will keep occurring on every cycle. Use the explicit CLng + clamp pattern from Solution 1 as the proper fix. On Error Resume Next is acceptable only as a temporary ship-stopper, paired with a HmiRuntime.Trace call that records the offending value.

Is the same overflow possible on a WinCC Comfort Panel in TIA Portal V13/V14?

Yes. The VBScript engine in WinCC (TIA Portal) Comfort Panels shares the same Variant/Double→Long conversion path. The fix is identical: compute the geometry in CDbl, clamp the intermediate values, and coerce to CLng at the assignment. The newer HMIRuntime.Screens and ScreenItems API surface is also unchanged for Left and Width.

How do I confirm the error is value-driven and not a property-type issue?

Wrap the assignment in On Error Resume Next immediately, read Err.Number, and clear with Err.Clear. If the number is 6 and the description is "Overflow", the value-driven path is confirmed. Other useful numbers are 9 ("Subscript out of range") for a wrong ScreenItem name, 13 ("Type mismatch") for a tag-type mismatch, and 91 ("Object variable not set") for a failed Set on a missing screen.

What is the legal value range for rectangle Width and Left in WinCC Flexible 2008 SP2?

Both are 32-bit signed LONG. The full range is −2 147 483 648 to +2 147 483 647. In practice a rectangle outside the visible screen is still accepted by the property write (no clamping), but a width of zero or negative renders as a zero-size rectangle in SP2 and SP3. Clamp the geometry to [0, screenSize] in the script before assignment to keep the visualization stable.

Back to blog