Creating Structure Tags in WinCC VBA: Limitations and Workarounds

David Krause12 min read
SiemensTroubleshootingWinCC
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 Overview

Engineers scripting WinCC V7 (and earlier WinCC V6) tag automation through the graphical editor's VBA host often hit the same wall: the HMIGO.CreateTag method accepts a tag name, tag type constant, connection, address, and group name, but it cannot bind a structure type definition to the resulting tag. When you pass TAG_STRUCT as the tag type constant, the WinCC tag management creates a tag shell with no associated data type, no member list, and no usable quality code. The tag exists in the tag database, the address appears in the export, and the tag name resolves in the graphics runtime—but every read returns 0 because no structure layout has been linked.

This limitation is documented by Siemens in FAQ entry 28369620, which states that structure creation through the VBA automation interface is not supported. The constraint has been carried through multiple major WinCC versions without a programmatic resolution. Engineers who need to provision hundreds of structure-instance tags (for example, motor faceplate UDTs, valve blocks, or recipe parameters) cannot rely on HMIGO.CreateTag alone.

Root Cause: What HMIGO.CreateTag Can and Cannot Do

The HMIGO COM object is a thin wrapper around the WinCC Tag Management database. Its CreateTag method was originally designed for atomic data types (binary, signed 16/32-bit, float, double, text tags, raw). The WinCC engineering team exposed only the parameters needed for those types: name, type constant, process connection, address string, and group path. The internal call ultimately writes a row into the tag database; for atomic types, that row contains a complete type descriptor.

For structure tags, the WinCC data model requires an additional pointer to a structure type definition that lives in a separate registry table (STRUCT_DEF). The HMIGO.CreateTag signature does not accept a structure-type name parameter, so the database row is written with the structure-type pointer field empty. The tag becomes visible in the Tag Management editor, but the type column is blank, and any subsequent VBA property access on the tag's data type fails with error -2147220480 (automation error, type not assigned).

The standard VBA call looks like this:

Dim objHMIGO As HMIGO
Set objHMIGO = New HMIGO

' Atomic tag works as expected
objHMIGO.CreateTag "Motor1_Speed", TAG_DOUBLE, "S7Connection_1", "DB20.DBD 0", "Motors"

' Structure tag is created but has no data type bound
objHMIGO.CreateTag "Motor1_Struct", TAG_STRUCT, "S7Connection_1", "DB20", "Motors"

The first line creates a fully usable DOUBLE tag. The second line creates a structure tag shell, but WinCC does not know which structure type to instantiate. The Tag property (used to assign a custom identification string to objects in VBA—see Microsoft Learn: Tag property) has no relationship to the WinCC structure type; the word overlap is a frequent source of confusion in search results.

Affected Versions and Products

Product Version Range VBA Host Available Structure Tag via VBA
WinCC V6.2 / V6.4 All SP levels Yes (Graphics Designer) Not supported
WinCC V7.0 SP0–SP4 Yes Not supported
WinCC V7.2 SP0–SP2 Yes Not supported
WinCC V7.3 SP0–SP3 (incl. Upd4/5) Yes Not supported
WinCC V7.4 SP0–SP1 Yes Not supported
WinCC V7.5 SP0–SP2 Yes Not supported
WinCC Professional (TIA Portal) V14–V18 (WinCC Comfort/Advanced/Professional) VBA via VBScript only Not supported; use Openness API
WinCC Unified (TIA Portal) V16+ JavaScript / C# via Openness Supported via Openness HmiTag and Structure types

The limitation is consistent across the WinCC V7 line. Newer WinCC Unified projects (V16 onward) address the gap through the TIA Portal Openness API, but the legacy WinCC V7 scripting path remains constrained to atomic types only.

Workaround 1: CSV Import (Recommended for Bulk Operations)

The most reliable approach for legacy WinCC V7 projects is to export a template tag list, edit it externally, and re-import it through the Tag Management import/export interface. WinCC supports comma-separated import of atomic and structure tags as long as the structure type already exists in the project.

Procedure

  1. Open the WinCC Explorer and navigate to Tag Management.
  2. Right-click the connection (e.g., S7Connection_1) and select Export Tags. Save the file as tags_template.csv.
  3. Inspect the CSV header. A typical WinCC export uses the columns Name;Type;Address;Group;Format;Comment with semicolon delimiters in German locale or comma delimiters in English locale.
  4. For each structure-instance tag, set the Type column to the name of an existing structure type (e.g., Motor_Struct) and the Address column to the DB block root (e.g., DB 20).
  5. Save the edited CSV and use Import Tags in Tag Management to load the file. WinCC prompts you to back up the existing tag database—accept the prompt.
  6. Verify by opening Tag Management and confirming that the imported tags show the structure type in the Data Type column and that the structure members are addressable.

Automating the CSV Edit with VBA

You can drive the export/import cycle from VBA by calling TagManagement.Export and TagManagement.Import on the HMIGO object, then using the FileSystemObject to edit the file between calls:

Dim objHMIGO As HMIGO
Dim fso As Object, ts As Object
Dim csvPath As String, line As String, lines() As String, i As Long

Set objHMIGO = New HMIGO
csvPath = "C:\WinCC_Export\tags_template.csv"

' Step 1: Export existing tags to seed the file
objHMIGO.Export csvPath

' Step 2: Read and append structure-instance rows
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.OpenTextFile(csvPath, 8, True) ' ForAppending
ts.WriteLine "Motor1_Struct;Motor_Struct;DB 20;Motors;;;;"
ts.WriteLine "Motor2_Struct;Motor_Struct;DB 22;Motors;;;;"
ts.WriteLine "Motor3_Struct;Motor_Struct;DB 24;Motors;;;;"
ts.Close

' Step 3: Re-import to commit the new structure tags
objHMIGO.Import csvPath

The import path accepts the structure-type name as the type column value, which is exactly what the direct CreateTag call refuses to do. Note that the structure type itself must already be defined in the project—you cannot import a new structure definition through CSV.

Important: Always close the Graphics Designer and any runtime instances before running the import. The Tag Management database is locked while the editor is open, and the import will fail with error 0x80004005 if a write lock is held.

Workaround 2: Manual Tag Creation with Template Duplication

For projects with a small number of structure instances (typically fewer than 50), manual creation through the Tag Management editor is faster than scripting and avoids the import overhead. The fastest manual workflow:

  1. Define the structure type once via Tag Management → Structure Types → New Structure Type. Add all members with their offsets, data types, and AS-OS station mapping where applicable.
  2. Create one instance tag of that structure type manually, pointing at a sample DB.
  3. Right-click the tag, choose Copy, then Paste. WinCC prompts for a name pattern (e.g., Motor_Struct_###), a DB offset increment, and the number of copies.
  4. Confirm the bulk paste. WinCC assigns sequential DB offsets and increments the tag name.

This paste-multiply workflow uses the same underlying database write as a CSV import but keeps the operation inside the GUI, which avoids locale-dependent delimiter issues.

Workaround 3: TIA Portal Openness (WinCC Unified / Professional)

For projects on TIA Portal V16 or later with WinCC Unified or WinCC Professional, the Openness API provides full programmatic control over structure types and structure tags. The C# example below creates a structure type and three instance tags under it:

using Siemens.Engineering;
using Siemens.Engineering.Hmi;
using Siemens.Engineering.Hmi.Tag;
using Siemens.Engineering.Hmi.Tag.Structures;

public static void CreateMotorStructure(TiaPortal tia, HmiTarget hmi)
{
    HmiSoftware hmiSw = hmi as HmiSoftware;
    var tagTableGroup = hmiSw.TagTables[0];

    // Step 1: Create the structure type
    StructureType motorType = tagTableGroup.StructureTypes.Create("Motor_Struct");
    motorType.Members.Create("Speed", HmiTagDataType.Real);
    motorType.Members.Create("Current", HmiTagDataType.Real);
    motorType.Members.Create("Running", HmiTagDataType.Bool);
    motorType.Members.Create("Fault", HmiTagDataType.Bool);

    // Step 2: Create instance tags bound to the structure type
    for (int i = 0; i < 3; i++)
    {
        HmiTag tag = tagTableGroup.Tags.Create("Motor" + (i + 1) + "_Struct");
        tag.StructureTypeName = "Motor_Struct";
        tag.PlcAddress = "DB" + (20 + i * 2) + ".DBW 0";
        tag.Connection = hmi.Connections[0];
    }
}

The StructureTypeName property is the missing parameter that HMIGO.CreateTag never exposed. Openness writes the structure-type pointer atomically with the tag row, so the resulting tag is fully populated. Openness requires the TIA Portal to be running with the project open, and the assembly Siemens.Engineering.Hmi.dll must be referenced. For deployment scripting, Openness can run headless via the TiaPortalProcess wrapper.

Workaround 4: WinCC Configuration Tool and Custom Export Filters

WinCC V7 ships with the WinCC Configuration Tool (also called the Tag Export/Import Tool) that runs as a standalone executable outside the Graphics Designer. The tool reads a text-based tag definition file in the same CSV format described above but operates without locking the Tag Management GUI. Engineers can wrap the tool in a batch script:

@echo off
set WINCC=C:\Siemens\Automation\WinCC\WinCC_Projects\MyProject
set EXPORT=%WINCC%\tags_export.csv

REM Close runtime
net stop "WinCC_Runtime" >nul 2>&1

REM Export current tags
"%ProgramFiles(x86)%\Siemens\Automation\WinCC\Bin\TagExport.exe" "%WINCC%" "%EXPORT%"

REM Append new structure rows via PowerShell
powershell -Command "Add-Content '%EXPORT%' 'Motor1_Struct;Motor_Struct;DB 20;Motors;;;;'"
powershell -Command "Add-Content '%EXPORT%' 'Motor2_Struct;Motor_Struct;DB 22;Motors;;;;'"

REM Re-import
"%ProgramFiles(x86)%\Siemens\Automation\WinCC\Bin\TagImport.exe" "%WINCC%" "%EXPORT%"

This batch approach is well suited to build-server scenarios where the project is regenerated from source control on every commit. The tool paths vary by WinCC version; always verify against the installed directory before scripting.

Why Siemens Has Not Added Direct VBA Support

The WinCC Tag Management database stores structure types in a binary registry with versioned schema identifiers. Adding a parameter to HMIGO.CreateTag would require synchronizing the schema version, regenerating COM type libraries, and re-validating every engineering tool that consumes the database. For each WinCC V7 service pack, that re-validation cost outweighs the engineering benefit, especially when CSV import and Openness cover the use case. WinCC Unified's Openness API was designed ground-up to avoid this limitation, which is why new projects are recommended to migrate where feasible.

The WinCC scripting interface still exposes a number of related objects that engineers occasionally confuse with structure creation:

Method / Property Object Purpose Creates Structure Tag?
CreateTag HMIGO Add tag row to database No (creates shell)
CreateTagEx HMIGO Add tag with extended properties (limits, scaling) No
Tag.Quality HMIRuntime Read quality code of existing tag N/A
Tag.Read / Tag.Write HMIRuntime Read/write tag value at runtime N/A
TagSimulation HMIGO Drive a tag with simulated values No
GetTagType HMIGO Return the data type constant of an existing tag No

Verification After Workaround Application

After any workaround, validate that the structure tags are usable from both the configuration and runtime sides.

  1. Open WinCC Explorer → Tag Management → the relevant connection. Confirm the new tags appear in the tree.
  2. Click each tag and verify that the Data Type column shows the expected structure name (e.g., Motor_Struct), not STRUCTURE_TYPE_NOT_SET.
  3. Expand the tag in the editor—if the data type is bound, the member list (Speed, Current, Running, Fault) appears inline.
  4. Open a graphics screen, drop a tag-prefixed I/O field bound to Motor1_Struct.Speed, and run the project in RT (or simulation mode). The I/O field should display the live value from the PLC.
  5. From the runtime script console (WinCC V7) or a C# test harness (WinCC Unified), call GetTag("Motor1_Struct.Speed") or HmiTag.Lookup("Motor1_Struct.Speed").Read() to confirm member access works.
  6. If the runtime returns 0 with quality code 0x0000001C (bad—configuration error), the structure type was not bound; re-run the workaround with care.

Troubleshooting Matrix

Symptom Likely Cause Corrective Action
HMIGO.CreateTag succeeds but tag has no data type Limitation of the VBA interface (FAQ 28369620) Use CSV import, paste-multiply, or Openness
CSV import rejects structure type column Structure type does not exist in the project Define the structure type first, then re-import
Import fails with error 0x80004005 Graphics Designer or RT holds a write lock on the tag database Close all WinCC editors and stop the runtime before importing
Tag exists but runtime read returns 0 Structure-type pointer is empty (only tag shell was created) Delete the tag and recreate via CSV import or Openness
StructureTypeName property missing in Openness Referencing the wrong assembly version Reference Siemens.Engineering.Hmi.dll from the TIA Portal install directory
Member address offset wrong after paste-multiply DB increment step misconfigured during paste Delete tags, set the DB step explicitly, repaste
Tag visible in Tag Management but absent from PLC connection diagnostics Connection assignment was lost during import Open the tag, reassign the connection, save

Field-Commissioning Notes

For projects where the tag database is regenerated repeatedly during commissioning (for example, when the PLC engineer adds new structure members), drive the regeneration from a single source of truth: a CSV file in version control, an Excel template, or an Openness script in the build pipeline. Avoid letting operators or commissioning engineers create structure tags manually through the Graphics Designer—every manual tag breaks the reproducibility contract and makes future migrations harder.

For WinCC V7 deployments that must remain on the legacy engine, prefer the CSV import workflow because it round-trips cleanly through Git and supports diff-based review. Always commit the structure-type definition changes in the same commit as the tag CSV, so a fresh checkout of the project can be regenerated without manual intervention.

For new deployments, evaluate WinCC Unified with TIA Portal Openness from the outset. The Openness StructureType and HmiTag.StructureTypeName properties eliminate the workaround chain entirely and provide a path to fully automated tag provisioning in CI/CD pipelines.

Can HMIGO.CreateTag in WinCC V7 create structure-typed tags?

No. The HMIGO.CreateTag VBA method supports atomic types (binary, signed 16/32-bit, float, double, text) but cannot bind a structure type definition. Passing TAG_STRUCT creates a tag shell with no data type, which is documented in Siemens FAQ 28369620 as an unsupported operation.

What is the best workaround for bulk structure tag creation in WinCC V7?

Use the CSV export/import workflow in Tag Management. Export the existing tag list, append rows with the structure-type name in the Type column, then re-import. The structure type must already exist in the project; CSV cannot define new structure types.

Does TIA Portal Openness support structure tag creation programmatically?

Yes. From TIA Portal V16 onward, the Openness API exposes StructureType.Members and HmiTag.StructureTypeName, which let you define a structure type and create instance tags bound to it in a single C# or VB.NET script. This is the recommended path for new WinCC Unified or WinCC Professional projects.

Why does my VBA-created structure tag return 0 at runtime?

The tag was created as a shell without a structure type binding, so every member access resolves to the default value (0). Delete the tag and recreate it through CSV import, manual paste-multiply, or TIA Portal Openness—any method that writes the structure-type pointer to the tag database.

How do I delete a phantom structure tag created by HMIGO.CreateTag?

Open Tag Management, locate the tag under its group, right-click and select Delete. If the GUI refuses the delete (which happens occasionally when the structure-type pointer is malformed), close the project, edit the project XML database file directly under a backup, or regenerate the tag database from a clean CSV import.

Back to blog