Problem Details
The TIA Portal Openness Scripter (and any external .NET client driving the Openness API) fails when exporting PLC blocks to XML. The runtime reports "Inconsistent block or UDT is used" in the Openness output window, and only a partial set of blocks is written to the target directory. The user-visible behavior is asymmetric: a subset of ProgramBlocks (FB, FC, OB, DB) is serialized to .xml, while the remainder is silently skipped because the API refuses to serialize a block whose reference graph still points to a non-compiled UDT, an unresolved instance DB, or an unmapped tag.
The error is raised by the Openness export pipeline at the moment the engine attempts to resolve symbol references for the candidate block. TIA Portal distinguishes between loadable consistency (compilable to a download artifact) and openness consistency (all symbols and dependent types resolved to a serializable form). A block may compile for download but still fail Openness export if a referenced UDT, PLC data type, or system data type has unresolved attributes.
"Inconsistent block or UDT is used" appears in the Openness output pane, partial XML files are written, no exception is thrown to the calling script until the transaction completes.Affected Versions
| TIA Portal Version | Openness DLL | Behavior |
|---|---|---|
| V15.1 / V16 | Siemens.Engineering.dll V15.1 / V16 | Export fails on UDT references unless the containing program block is consistent |
| V17 | Siemens.Engineering.dll V17 | Reports "Inconsistent block or UDT is used" on partial compilations |
| V18 | Siemens.Engineering.dll V18 | Same error class; stricter UDT validation in the export pipeline |
| V19 / V20 | Siemens.Engineering.dll V19 / V20 | Adds typed export flags; same consistency precondition applies (Exporting blocks – TIA Portal V20 documentation) |
| V21 | Siemens.Engineering.dll V21 | Behavior unchanged; documented in Export/Import – TIA Portal V21 |
Root Cause Analysis
The Openness export engine performs a graph-walk over the dependency closure of each candidate block. The walk fails when it encounters a node whose internal state is not equivalent to the post-compilation state stored in the offline project. Typical root-cause categories are listed below.
| Category | Mechanism | Diagnostic Signal |
|---|---|---|
| Uncompiled program block | Source edits saved but full project compile never executed | Yellow warning icons in the project tree, no "Compiled" timestamp on the software unit |
| Unresolved UDT reference | DB references a UDT that was renamed, deleted, or never compiled | Red squiggle under the type declaration in the affected DB |
| Uncompiled UDT itself | PLC data type was edited; dependent blocks now reference a stale snapshot | UDT shows "modified" badge; Openness serializes only the prior compiled version |
| Multiple software units / master copy | Openness exports only the active software unit; cross-references to other units are not resolved | No error in the source unit; missing instances in the export |
| Version-bound type mismatch | Block compiled against one firmware version, project opened under another | Compile log shows version conversion warnings |
The export entry point PlcBlock.Export(string path, ExportOptions options) does not perform a project-wide consistency rebuild. It serializes the in-memory representation of the block as compiled the last time the user (or a previous script) invoked the compiler. If the Openness script selects blocks via PlcSoftware.SystemTypeGroups and ProgramBlocks without first forcing a recompile, the engine reads stale state and rejects the inconsistent subset.
Solution: Compile Before Export
The deterministic fix is to invoke the compiler on the entire PlcSoftware container (or on the specific PlcBlockUserGroup that owns the candidates) before calling Export. This produces the consistency graph the Openness serializer requires.
Step-by-Step Procedure
- Open the TIA Portal project containing the blocks to export. Confirm that no exclusive access lock is held by another Portal instance.
- In the project tree, right-click the PLC device > Program blocks node and select Compile > Software (rebuild all). Wait for the compiler to finish; the Output window should show
"Compile completed successfully"with zero errors. - Open TIA Portal Openness Scripter from the Windows Start menu. The scripter is delivered with TIA Portal at
%ProgramFiles%\Siemens\Automation\Portal V<XX>\Openness\Scripter\Siemens.Engineering.ScriptRunner.exe. - Load or paste the export script. The minimum working skeleton is shown below.
- Execute the script. Verify that all candidate XML files are present in the target directory.
Minimum Working Script (C# Style, Openness Scripter)
// Connect to running TIA Portal
Portal portal = Portal.Create();
Project project = portal.Projects.Open(new FileInfo(@"C:\Projects\MyPlant.ap17"));
// Navigate to the PLC device
Device plcDevice = project.Devices.First(d => d.Name == "PLC_1");
PlcSoftware plc = plcDevice.DeviceItems
.First(item => item.Name == "PLC_1" && item is PlcSoftware)
.GetService<PlcSoftware>();
// Step 1: Force a full compile of the software container
plc.GetService<PlcSoftwareService>().Compile();
// Step 2: Enumerate program blocks and export to XML
PlcBlockUserGroup programBlocks = plc.BlockGroup;
foreach (PlcBlock block in programBlocks.Blocks)
{
string targetPath = $@"C:\Export\{block.Name}.xml";
block.Export(new FileInfo(targetPath), ExportOptions.WithDefaults);
}
project.Close();
portal.Dispose();
The Compile() call above is the critical step. Without it, the iteration over programBlocks.Blocks may yield blocks whose internal state lags behind the user's last edit, and the Export invocation raises the inconsistency error on the first such block.
Granular Compile (Targeted Software Unit)
For projects with multiple software units (multi-CPU or master-copy configurations), compile the specific PlcBlockUserGroup that owns the candidates to avoid cascading compile time across the entire device.
PlcBlockUserGroup targetGroup = plc.BlockGroup.Groups
.FirstOrDefault(g => g.Name == "MainProgram");
if (targetGroup != null)
{
targetGroup.GetService<PlcBlockUserGroupSystemService>().Compile();
}
Alternative Export Paths
If the Openness export must be deferred (e.g., the project cannot be compiled because of unrelated syntax errors), or if the goal is a round-trippable text artifact rather than the Openness XML schema, use the integrated Generate source from block feature.
- In the project tree, right-click any
DB,FB, orFC. - Select Generate source from block.
- Choose a target directory; the engine writes a plain-text SCL/TXT file per block.
- Re-import into another project via right-click > Import source to block.
This path produces a plain-text export that is more portable across TIA Portal versions than the Openness XML schema, and it does not require Openness licensing. The trade-off is loss of metadata: alarms, message configurations, attributes, and HMI tag bindings are not preserved in the plain-text source.
Verifying Consistency Before Script Run
To eliminate the inconsistency class of errors before launching the script, perform the following checks in the TIA Portal UI.
| Check | Where | Expected Result |
|---|---|---|
| Project compiles cleanly | Project tree > right-click PLC > Compile > Software | Output window: "0 errors, 0 warnings" (warnings allowed if unrelated) |
| UDTs have compiled snapshot | PLC data types node > modified badge | No yellow "modified" badge on any UDT used by export candidates |
| No exclusive access | Title bar of TIA Portal window | No "in use by <user>" annotation |
| Software unit selected | Project tree > Software units | Exactly one software unit marked active; Openness exports only the active unit |
| Openness reference assembly loaded | Script runner log | Reference resolves to Siemens.Engineering.dll matching the TIA Portal version |
Scripting With the OpennessScripter Tool
The OpennessScripter bundled with TIA Portal is a lightweight C# script host that loads Siemens.Engineering.dll from the Portal installation directory. Documentation is available as OpennessScripter detailed documentation (PDF) attached to the Siemens Industry Online Support entry.
Key behaviors documented in the manual:
- The scripter establishes an implicit connection to the running Portal instance; explicit
Portal.Create()is permitted but the existing instance is reused. - Output from
Console.WriteLineappears in the scripter's Output pane. - Long-running operations should be wrapped with progress reporting via
IProgress<int>to avoid the scripter's idle timeout. - File-system writes require absolute paths; relative paths resolve against the scripter's working directory, not the project's location.
An open-source reference implementation is available at cezar1/TiaExportBlocks. The reference implementation explicitly invokes the project compile before walking the block tree, mirroring the resolution procedure above.
Export Filter Patterns and Wildcards
Openness does not expose a wildcard parameter directly to Export. To export only the data blocks, filter the enumeration explicitly.
// Export only DBs whose names start with "Recipe_"
foreach (PlcBlock block in plc.BlockGroup.Blocks
.Where(b => b.Name.StartsWith("Recipe_") && b is DataBlock))
{
block.Export(new FileInfo($@"C:\Export\DB\{block.Name}.xml"),
ExportOptions.WithDefaults);
}
This pattern also reduces the chance of triggering the inconsistency error, because each filtered iteration can be wrapped in a try/catch that logs the offending block name without aborting the entire script.
try
{
block.Export(target, ExportOptions.WithDefaults);
}
catch (EngineeringException ex)
{
Console.WriteLine($"Skip {block.Name}: {ex.Message}");
}
Cross-Version Compatibility
XML files generated by Openness V17 cannot be re-imported into V15.1 without explicit conversion. The recommended migration path is the plain-text Generate source / Import source workflow described above. When importing the XML back into the same Portal version, the target project must also be in a compiled state, otherwise the import engine reports the inverse error: "Target project contains inconsistent blocks".
| Source Version | Target Version | Recommended Path |
|---|---|---|
| V17 | V17 (same project) | XML round-trip via Openness |
| V17 | V18 / V19 / V20 / V21 | Plain-text source export / import; manual version upgrade in target |
| V17 | V16 or earlier | Project upgrade in source first, then plain-text migration |
| V20 | V20 | XML round-trip per V20 export documentation |
Common Pitfalls
-
Compiling only the changed block. The Compile block right-click menu item compiles the individual block but does not propagate the consistency snapshot to dependent blocks or UDTs. Use Compile > Software (rebuild all) or the
Compile()API call on the parent container. - Multiple Portal instances. If two Portal windows are open against the same project, the second scripter call may attach to the wrong instance. Close all but one Portal window before running an export script.
-
Read-only project file. Openness cannot write the recompile artifacts to a read-only project directory. Ensure the
.ap17file and its.<ProjectName>.filescompanion folder are writable. -
Library references. Blocks that reference global libraries must have the library master copies resolved before export. The export engine raises
"Inconsistent block or UDT is used"if a referenced library type cannot be located. - Hardware configuration edits. A change to the device configuration (added module, removed submodule) invalidates the IO address map and triggers the same inconsistency class of errors for blocks that reference IO tags.
Verification
After the script completes, validate the export with the following checks.
- List the export directory and confirm that the file count matches the expected number of
ProgramBlockscandidates. - Open one exported XML file and verify the presence of the
<SW.Blocks.FB>or<SW.Blocks.DB>root element with validSchemaVersionmatching the TIA Portal version. - Import the XML back into a scratch project using
block.Importor right-click > Import blocks from XML. The import must complete without re-triggering the inconsistency error. - Compare the imported block's interface signature against the original using the project comparison tool.
Frequently Asked Questions
What does the error "Inconsistent block or UDT is used" mean in TIA Openness?
It means the export engine found a block whose internal state does not match a successfully compiled snapshot. The most common cause is that the project (or the specific program block group) was edited after the last compile pass. Run Compile > Software (rebuild all) in the TIA Portal UI, or invoke PlcSoftwareService.Compile() in your Openness script, before calling Export.
Can Openness export only data blocks (DBs) without FBs and FCs?
Yes. Filter the programBlocks.Blocks enumeration by is DataBlock and apply an optional name filter (e.g., StartsWith("Recipe_")). Openness does not provide a wildcard parameter to Export, so the filter must be applied in script before the export call.
How do I export blocks to XML without using Openness at all?
Right-click any block in the TIA Portal project tree and select Generate source from block. The output is a plain-text file per block that can be re-imported via Import source to block. This path bypasses the Openness XML schema and is more portable across TIA Portal versions.
Does compiling inside an Openness script lock the project for other users?
Yes. The TIA Portal project enforces exclusive access while a compile is in progress. Schedule Openness compile-and-export routines for maintenance windows, or use a dedicated CI agent that opens the project in offline mode (project.Save() is not required if no edits are made).
Which Siemens manual documents the export API and consistency requirements?
The Exporting blocks page in the TIA Portal Openness V20 documentation describes the XML export contract, and the V21 export/import overview covers version compatibility. The OpennessScripter PDF manual documents the bundled scripter tool.