Resolving WinCC VBScript Nested Group Name Retrieval on HMI

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

Problem Statement: Identifying the Top-Level Compound Group from a Nested Child

On Siemens HMI panels configured with WinCC in the TIA Portal (Comfort Panels, Unified Comfort Panels, and WinCC Runtime Advanced / Professional), a common engineering pattern is to assemble a complex symbol from multiple primitives, then group the primitives into a single selectable object. When the same compound symbol is reused dozens or hundreds of times on a process screen, each instance is typically renamed at the top group level (for example ES123, ES124, ES125) so that event handlers, dynamization functions, and tag prefixes can be derived from the instance name.

The problem surfaces when a VBScript function is attached to a deeply nested child element of the compound group (for example, a small valve disc embedded inside a larger frame that also contains a label and a unit readout). At runtime, the VBS handler receives the innermost clicked object via the implicit Item reference, but the built-in Item.Parent traversal either:

  1. Stops at the first enclosing group (returning the immediate subgroup name, not the top-level compound group), or
  2. Returns the surrounding picture (Screen) when the child is already inside the top-level group.

The engineer therefore cannot reliably resolve the name ES123 from inside a single shared VBS function, breaking the pattern of "one function, many renamed instances."

Symptom summary: A shared VBS dynamization or click handler returns the wrong name (immediate subgroup or empty string) when invoked on a nested child of a renamed compound group, so the tag prefix derived from the name is wrong, the color is wrong, or the click routes to the wrong valve.

Root Cause: How the WinCC Object Model Exposes Groups

To choose the correct fix it is necessary to understand exactly what the WinCC VBS object model exposes at the moment an event fires. The model follows the TIA Portal WinCC documentation for the WinCC VBScript object model and the Graphics Designer help.

The Implicit Item Reference

Every VBS action, dynamization, or event configured on a screen object receives an implicit parameter named Item that points to the object the script is bound to. The Item object exposes:

  • Item.ObjectName — the configured Name property of the object that owns the script (for a group, the group name; for a primitive, the primitive name).
  • Item.Parent — the parent in the Graphics Designer hierarchy. For a primitive nested in one group, Item.Parent is the group. For an object at the top level of the screen, Item.Parent is the picture itself.
  • Item.Type — the runtime type identifier, useful for filtering with TypeName(Item) or comparing against known group types.

Group Hierarchy vs. Picture Hierarchy

A compound group created in the Graphics Designer is a single object whose ObjectName is whatever the engineer typed in the Name field. Its children are the original primitives or subgroups, but the parent of the top-level group is the picture, not another group. This is the structural reason that:

  • Item.Parent.ObjectName on a top-level group returns the picture name (for example Screen_1), not ES123.
  • Climbing a fixed number of .Parent levels (e.g. Item.Parent.Parent.ObjectName) is not portable, because the same compound group may be instanced with different nesting depths in different screens.

Solution 1 — Walk the Parent Chain Until a Group Is Found

The most portable approach is to walk .Parent repeatedly until the runtime detects that the parent is the picture rather than a group. The TypeName of the picture is Screen (or HmiScreen on Unified panels), so the walk terminates at the first object whose TypeName is not a group type.

' VBS action: GetTopGroupName
' Returns the ObjectName of the topmost group that contains Item.
Function GetTopGroupName(obj)
    Dim cur
    Set cur = obj
    Do While Not (cur Is Nothing)
        ' Stop when the next parent is no longer a group
        If IsNull(cur.Parent) Then
            GetTopGroupName = cur.ObjectName
            Exit Function
        End If
        If TypeName(cur.Parent) = "Screen" Or _
           TypeName(cur.Parent) = "HmiScreen" Or _
           TypeName(cur.Parent) = "Document" Then
            GetTopGroupName = cur.ObjectName
            Exit Function
        End If
        Set cur = cur.Parent
    Loop
    GetTopGroupName = ""
End Function

' Usage in a mouse-click action on a nested valve symbol:
Dim topName
topName = GetTopGroupName(Item)
HMIRuntime.Trace "Top group is: " & topName & vbCrLf

Place the function in a project-wide script module (Project library → Scripts → Standard modules) so it is available to every screen. The shared function can then be called from any dynamization, mouse event, or value-change event.

Solution 2 — Use a Custom User-Defined Property on the Compound Group

Walking .Parent is reliable but adds runtime overhead on every event. A cleaner design is to store the name on the group itself using a user-defined property and read it directly from the child.

Step-by-Step Configuration

  1. In the Graphics Designer, select the top-level compound group.
  2. Open Properties > Miscellaneous and click the User-defined category.
  3. Add a new property, e.g. CompoundName of type String.
  4. Set its value to the same string as the group Name (for example ES123).
  5. From the nested child's VBS handler, read Item.Parent.CompoundName — but only if the immediate parent is the group, otherwise walk one level up.
' Read the custom property from the top-level group containing Item
Function GetCompoundName(obj)
    Dim cur, probe
    Set cur = obj
    Do While Not (cur Is Nothing)
        On Error Resume Next
        probe = cur.CompoundName
        If Err.Number = 0 And probe <> "" Then
            GetCompoundName = probe
            Exit Function
        End If
        On Error Goto 0
        If TypeName(cur) = "Screen" Or TypeName(cur) = "HmiScreen" Then Exit Do
        Set cur = cur.Parent
    Loop
    GetCompoundName = ""
End Function

User-defined properties are visible in VBS exactly as built-in properties, and the runtime evaluates them with a simple lookup rather than a hierarchy walk. This is the recommended pattern for screens with hundreds of compound groups.

Solution 3 — Pass the Group Name as an Explicit Parameter

When the click target is fixed (for example, the click is on the top group itself, not on a child), the VBS function can simply read Item.ObjectName — no traversal is needed. The trade-off is that the clickable hit area becomes the bounding box of the entire group, which may be undesirable when the group contains a large invisible frame.

To keep the click on a small child but still pass the group name, configure the dynamization as a function call instead of a direct VBS action:

  1. Create a function ColorByTag(groupName, state) in a project script module.
  2. On the nested child's Appearance dynamization, choose Dynamization → Function → ColorByTag.
  3. For the groupName argument, bind it to the top group's name (drag the group onto the parameter slot, or type the literal name once and replicate by renaming the group instance).

This approach avoids both traversal and custom properties, but it requires the engineer to bind the parameter explicitly for every instance, so it scales less well than Solution 1 or Solution 2.

Comparison of the Three Solutions

Criterion Solution 1: Parent walk Solution 2: User-defined property Solution 3: Explicit parameter
Configuration effort None per instance One user-defined property per group type One parameter binding per instance
Runtime cost Several .Parent calls per event One property lookup No traversal
Scales to many instances Yes Yes Limited (manual binding)
Robust to nesting changes Yes (terminates on picture) Yes (property moves with group) Yes (parameter is explicit)
Requires fixed click target No No Yes (parameter must be bound)
Best for Ad-hoc debugging, prototypes Production screens with hundreds of instances A handful of named instances

Verification Procedure

After implementing any of the solutions above, run the following verification sequence in the WinCC Runtime to confirm the correct top-group name is returned.

  1. Compile and download the project to the HMI panel (or start the WinCC Runtime simulation on the engineering station).
  2. Open the screen that contains the compound groups and open the diagnostic trace window (Start → Programs → Siemens Automation → WinCC → Trace Viewer, or use HMIRuntime.Trace).
  3. Click on a nested child of a renamed compound group (for example, the valve disc inside ES123). The trace should display Top group is: ES123.
  4. Click on a child of a different compound group (ES124) and confirm the trace returns ES124 — this proves the function is reading the instance name and not a hard-coded value.
  5. Click on a child of an unnamed or default-named group and confirm the function returns the actual default name (e.g. Group1) without raising an error.
  6. For Solution 2, change the value of the CompoundName user-defined property at runtime (via a tag connection) and verify the dynamization follows — this confirms the property is being read, not the static group name.

Edge Cases and Field-Proven Caveats

1. Group vs. Faceplate vs. Screen Window

If the compound symbol is implemented as a faceplate (an instance of a faceplate type) rather than a simple group, the Item reference in a faceplate script refers to the faceplate instance, and the top-level container is a screen window. Item.Parent from inside a faceplate instance is the screen window, not the screen. For faceplates, prefer Solution 2 with a tag-prefix tag of the faceplate type, or use the HmiRuntime APIs to resolve the container name explicitly.

2. Renamed vs. Default Group Names

The Graphics Designer assigns sequential default names (Group1, Group2...) when the engineer does not explicitly rename. Item.ObjectName returns these defaults verbatim. The traversal solutions still work, but any tag-derivation logic (for example, "T" & Mid(name, 3) to map ES123 → T123) must be guarded against empty or default names.

3. Touch Targets Smaller Than the Group

Moving the click event from the large top group to a small child (as in the original use case) reduces accidental hits on adjacent valves. The trade-off is that the entire bounding box of the child becomes the hit area, including transparent areas. To shrink the hit area to a small visible shape, embed only the visible valve disc as the click target and keep the frame and label as non-interactive group members.

4. Runtime vs. Configuration Behavior

In the Engineering System (ES) preview of a VBS function bound to a screen object, the Item reference is the same as at runtime, so the function can be unit-tested from the script editor. Trace output, however, only appears in the Runtime; the ES does not collect it. Plan trace-based verification for the RT simulation rather than the ES preview.

5. Unified vs. Classic Comfort Panels

On Unified Comfort Panels (WinCC Unified, TIA Portal V17 and later), the VBScript object model is the same in concept but the type names may differ (for example, HmiScreen rather than Screen). The traversal logic above accounts for both. If a project must run on both classic Comfort Panels and Unified Panels, wrap the type-name comparison in a small helper that returns True for any of the known picture types.

Troubleshooting Matrix

Symptom Likely cause Fix
Function returns the picture name (e.g. Screen_1) Walk terminated too early; picture type not recognized Add the project's picture type to the TypeName check in Solution 1
Function returns the immediate subgroup name (e.g. Group3) Walk stopped at first group; only one .Parent step taken Use the full Do loop in Solution 1; confirm cur.Parent is not null
Function returns empty string Top group has no name, or the custom property is unset Rename the group; or set the user-defined CompoundName property (Solution 2)
Runtime error "Object doesn't support this property or method" on cur.CompoundName The user-defined property was not added to the group in the Graphics Designer Re-open the group, add the property under Miscellaneous → User-defined, recompile, download
Tag prefix derived from the name is wrong at runtime but correct in the ES Tag prefix logic was hard-coded for a single instance, not derived from Item.ObjectName Replace hard-coded strings with a function call that returns the prefix from the resolved name
Click on a frame around the valve hits the wrong valve Click target is the large top group, hit area overlaps neighbours Move the click event to the small visible child inside the group and use Solution 1 or 2 to recover the name

Best-Practice Recommendation

For production screens that replicate a compound symbol many times and rely on the symbol name to drive tag prefixes, faceplate instances, or color dynamization, the recommended pattern is:

  1. Add a single user-defined string property (e.g. CompoundName) on the top-level group inside the Graphics Designer master.
  2. Set CompoundName equal to the group Name for every instance, either by hand or via a small project script that runs on screen load.
  3. Place a single shared VBS function in a project-wide standard module that walks .Parent until it finds an object with a non-empty CompoundName, falling back to ObjectName if the property is absent (so the function works on legacy groups that have not yet been migrated).
  4. Bind click events and dynamizations to the small visible child, not to the large bounding group, to keep the hit area tight and predictable.

This combination keeps the click target small, the name resolution O(1) in the common case, and the function portable across nesting depths and across classic Comfort / Unified panels.

FAQ

Why does Item.Parent.ObjectName on a nested child return the picture name and not the compound group?

In the WinCC VBScript object model, Item.Parent returns the immediate parent in the Graphics Designer hierarchy. The immediate parent of a top-level compound group is the picture itself (type Screen or HmiScreen), so reading Item.Parent.ObjectName yields the picture name, not the group name. Walk the chain in a loop until the parent is no longer a group to find the top-level compound group.

How do I add a custom property to a group in the Graphics Designer?

Select the group, open its Properties dialog, switch to the Miscellaneous → User-defined category, click Add, and define a string property (for example CompoundName). The property is then readable from VBS as obj.CompoundName on the group and on any object inside it that walks up to the group.

Does the same VBS function work on both Comfort Panels and Unified Comfort Panels?

Yes, provided the function uses type-name checks that cover both the classic picture type (Screen) and the Unified picture type (HmiScreen). Wrap the comparison in a helper that returns True for any known picture type so the loop terminates correctly on both platforms.

Can I derive a tag name from the group name inside a single shared VBS function?

Yes. Once the top-level group name is resolved (for example ES123), use string functions to extract the trailing numeric portion and concatenate a prefix: tagName = "T" & Mid(topName, 3). Guard the extraction against empty or default group names to avoid generating invalid tag references at runtime.

What is the difference between a group and a faceplate for this scenario?

A group is a single object that contains primitives and subgroups; it lives entirely on one screen and has a flat ObjectName. A faceplate is a typed, reusable instance with its own property interface and tag-prefix mechanism; inside a faceplate, Item.Parent is a screen window, not the host screen. The traversal solutions above target groups; for faceplates, prefer tag-prefix tags and the faceplate type's own property interface.

Back to blog