Restoring UDT Symbols in Uploaded STEP 7 Programs (S7-300/400)

David Krause15 min read
S7-300SiemensTroubleshooting
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

Restoring UDT-Defined Symbols in an Uploaded STEP 7 Program (S7-300/400)

This reference documents the root cause, the engineering constraints, the recovery procedures, and the long-term best practices for working with UDTs in SIMATIC STEP 7 V5.x (SIMATIC Manager). It applies to S7-300, S7-400, and C7 controllers running firmware that supports the standard STEP 7 V5.x block compilation model.

Scope: This article targets the classic STEP 7 environment (STEP 7 V5.5 / V5.6 with optional S7-GRAPH, S7-SCL, S7-CFC). It does NOT cover TIA Portal's PLCSIM-UDT model, S7-1200, or S7-1500 optimized data blocks. The mechanism described is a quirk of the S7-300/400 block container and is independent of CPU firmware revision.

1. Problem Description

The reported failure mode is reproducible and consistent:

  1. A STEP 7 source project is authored with one or more UDTs (e.g. UDT_MOTOR, UDT_VALVE, UDT_AI_SCALE).
  2. Multiple instance DBs are created from those UDTs (e.g. DB100 MOTOR_DB_1, DB101 MOTOR_DB_2).
  3. Function Blocks are written whose STAT section contains UDT_xxx elements (multi-instance model), or whose interface directly references UDT-based structures.
  4. The compiled S7 program is downloaded to the CPU. The runtime process executes normally.
  5. The complete program is uploaded to the PG via SIMATIC Manager (PLC > Upload Station to PG).
  6. The resulting offline project contains blocks with correct numerical structures but every UDT-inherited symbol name displays as ???, ???, or simply a raw address, even though the byte/word offsets match the original UDT layout.

Copying the original Symbol Table back into the uploaded project restores the global I/O, FB, DB, and UDT symbols. It does not restore the member symbols inside a DB that was built from a UDT. The UDT itself can be reinserted into the S7 program folder, and the DB's Declaration View still shows the UDT reference on the header line, but the member column is empty.

2. Root Cause Analysis

Understanding why the symbols vanish requires looking at how STEP 7 separates project data from block data.

2.1 What is downloaded to the CPU

When you call PLC > Download, only the compiled blocks are written to the CPU's load memory. Specifically:

  • OBs, FBs, FCs, DBs, SDBs, SFBs, SFCs are transferred as compiled code and data.
  • UDTs are not transferred as standalone objects. The UDT definition is expanded into the compiled FB/DB at compile time. The CPU has no concept of a named UDT — it only knows byte offsets.
  • The Symbol Table is never transferred to the CPU. Symbolic names live only in the offline project on the PG.
  • Comments, network titles, and variable comments are stripped from the blocks on download.

This is documented in the Siemens FAQ 16893267 ("Why are comments and symbols missing after uploading?") and the related FAQ 22781586 ("How do you export/import STEP 7 symbols via Excel?").

2.2 What an Upload Produces

The Upload Station to PG command reads the compiled blocks back. STEP 7 re-parses each block and reconstructs a best-effort declaration view. For blocks that were built from a UDT, STEP 7 needs three pieces of information to recreate symbolic member names:

  1. The UDT definition (which it does not have, because the CPU never stored it).
  2. The fact that the DB originally referenced that UDT — encoded in the block header, but not always reliably after upload.
  3. The original address binding between UDT member name and byte offset.

If any of these pieces is missing, the member symbols become ??? (three question marks). The byte layout is still correct because STEP 7 can compute it from the block length and the implicit structure of the original UDT, but the textual mapping is lost.

2.3 Why Copying the UDT Back Does Not Work

Inserting a copy of the original UDT_xxx into the uploaded project's Blocks folder does add the UDT to the offline project, but the uploaded DB was generated as a free DB with absolute offsets, not as a UDT-referenced DB. STEP 7 has no automatic reverse-engineering pass that re-establishes the UDT binding. The "Check Block Consistency" function — which is the normal mechanism for recompiling FBs to refresh their instances — is grayed out in this scenario because STEP 7 has no uncompiled source for the uploaded block to check against.

Additionally, when an FB uses UDTs in its STAT section (multi-instance model), the multi-instance DB inherits the UDT structure, and this inheritance is encoded in the FB's compiled interface. Without the original FB source, the uploaded FB cannot regenerate the multi-instance structure either.

3. Confirming the Diagnosis

Before applying recovery steps, confirm that the symptom is in fact the UDT-symbol loss issue and not a different problem (corrupt project, mismatched CPU firmware, or wrong block consistency check).

3.1 Quick Diagnostic Checklist

Check Expected If UDT Symbol Loss Wrong-If-Other-Cause
DB byte layout vs. original Identical Layout differs → corrupt upload or wrong CPU
DB Declaration view header line May show STRUCT with no member names Shows nothing → DB did not exist on CPU
Symbol Table after copying Global symbols restored; UDT members still ??? Whole table missing → wrong source project
Check Block Consistency button Grayed out Active → FB was uploaded with source, try recompile
UDT object in Blocks folder Present after copy but DB still empty Missing → confirm correct UDT copy
FB multi-instance STAT names All ??? Some present → partial upload

3.2 The Hard Truth

4. Recovery Procedures

Use the procedure that matches the resources you have available.

4.1 Path A — Original Project Is Available (Recommended)

This is the cleanest recovery and the one Siemens Support will direct you to.

  1. Create a new working copy of the source project (do not modify the original).
  2. Establish an online connection to the CPU containing the current runtime data.
  3. In the offline copy, open the Blocks folder and delete every DB whose current values you need to preserve (motor DBs, valve DBs, parameter DBs).
  4. Right-click the online → Copy to Offline (or drag-and-drop) for each runtime DB. STEP 7 will write the online DB into the offline project, replacing the source DB. The DB now contains the latest process values.
  5. Do not overwrite FBs this way unless you intend to discard source comments. FBs should remain as the compiled source; only the DBs need the runtime refresh.
  6. Re-download the merged project to the CPU to put the source FB declarations back into the load memory (the CPU's FBs were identical anyway, so this is effectively a no-op for code, but it re-aligns the offline project as the source of truth).

This is the same workflow as the Siemens FAQ 24352635 on online/offline DB synchronization. Because the source FBs, UDTs, and the original DB declarations are still present, all symbolic names are preserved.

4.2 Path B — Source Project Lost, UDT Definitions Available as STL Source

If you exported the UDTs and DBs to STL source files (SCL or STL is the same model) before the loss, recovery is still possible.

  1. Compile the source files back into the S7 program: Options > STL Source Files > Generate.
  2. STEP 7 will recreate the UDT objects, the FBs with their STAT UDT members, and the DBs with the UDT structure.
  3. For runtime values, repeat the online → offline DB copy from Path A.

4.3 Path C — Source Project Lost, No STL Backup

This is the worst case. The UDT-derived symbolic names are unrecoverable. Mitigations:

  • Re-author the UDTs from the byte layout. Open each affected DB, switch to Declaration View, and rebuild the UDT structures in the UDT editor of SIMATIC Manager. The byte offsets in the DB reveal the UDT layout: counters are typically 2 bytes, timers 2 bytes, real values 4 bytes, bool 1 bit. Match the inferred layout to a reconstructed UDT, save, and re-link the DB header to the UDT (right-click DB > Source > Generate Source, edit, and recompile).
  • Use absolute addressing in any cross-references (CFC, SCL, HMI tag list) until the UDTs are rebuilt.
  • Document the loss in the project and add this incident to the maintenance log so it does not repeat.

5. Why Check Block Consistency Stays Grayed Out

The Check Block Consistency command (Edit > Check Block Consistency, or the toolbar button) only operates on blocks that have a source available in the project. A block uploaded from the CPU has no associated source — only the compiled code in the offline Blocks folder. To re-enable consistency checking, you must regenerate the source:

  1. Open the affected FB/DB.
  2. Right-click > Generate Source > select STL, SCL, or LAD/FBD source as appropriate.
  3. Save the source file in the Sources folder of the S7 program.
  4. Right-click the source > Check Consistency — the button is now active because the offline block has a source it can be checked against.
  5. After a successful check, Compile the source (File > Compile) to refresh the runtime blocks.

The same applies to Check and Update Accesses (right-click block > Check and Update Accesses). Without a source, STEP 7 has no AST to walk and no symbol table to update from.

6. Block Size and Performance Impact of UDTs

An often-overlooked consequence of using UDTs in S7-300/400 is that the compiled block size grows significantly compared to using flat structures. Field experience and Siemens Application Examples indicate the multiplier is typically 2× to 3×:

Structure Style Relative MC7 Code Size Comments
Direct member declaration in FB STAT 1.0× (baseline) Smallest compiled footprint
Single UDT used once in FB STAT ~1.4× UDT reference adds small overhead
Same UDT instantiated 2× in FB STAT ~1.7× Structure inlined per instance
Same UDT instantiated 5× in FB STAT ~2.2× Each instance duplicates the UDT body
Heavy UDT use (5× UDTs of 30+ members) 3.0× or more Can exhaust work memory on S7-314/315

For S7-314IFM, S7-314, and older S7-315 CPUs with tight work-memory limits (48–128 KB), the UDT size multiplier can prevent a project from fitting. Check the Module Information > Memory tab in SIMATIC Manager after every significant FB change. Typical work-memory budget for a small machine:

  • Code (OB/FB/FC): < 30% of work memory
  • Data (DB): < 40% of work memory
  • System data (SDB): < 10%
  • Free for online changes: ≥ 20%

7. Re-establishing UDT References After a Partial Upload

If you have the original UDTs and want to relink them to the uploaded DBs, perform the following in SIMATIC Manager:

  1. Open the uploaded DB in the Declaration View.
  2. Note the UDT name in the block header (it may still be present, e.g. UDT_MOTOR).
  3. Open the original UDT in the UDT editor and copy the full declaration text (including STRUCT and END_STRUCT).
  4. In the uploaded DB, select all rows in the Declaration View, delete them.
  5. Right-click the first empty row > Insert > Line and paste the UDT body, or use the menu Insert > UDT to reference the UDT by name. STEP 7 will expand the UDT members symbolically.
  6. Save and compile the DB.
  7. Re-link the DB to the original instance name in the Symbol Table.

This is essentially what Generate Source > Recompile does automatically when the source file is intact. The manual procedure is for when the source file is lost but the UDT itself is preserved.

8. HMI and SCADA Symbol Import

A common downstream consumer of UDT symbols is the HMI/SCADA tag list. When the STEP 7 symbol table is correctly preserved, an HMI such as a Pro-face GP series can import the symbols directly.

For Pro-face GP Pro EX (or the legacy GP-Pro EX) connecting to a Siemens S7-300/400 over Ethernet or MPI, the symbol import path is:

  1. In GP Pro EX, open the project for the target HMI.
  2. From the menu bar, choose Common SettingsSymbol Variable.
  3. In the Edit Symbol Variables page, click UtilityImportSTEP7 Project File.
  4. Browse to the STEP 7 source project (.s7p) or the exported .xls symbol list.
  5. GP Pro EX expands UDT member names into individual HMI tags with the dot-notation path (e.g. DB100.MOTOR_DB_1.Speed_SP).

The official procedure is documented in the Pro-face GP Pro EX Reference Manual — Import STEP 7 Project File (section 8.14.5.1 Common Settings > Symbol Variables > Import). When the STEP 7 project has lost its UDT symbols, the HMI import will create a tag list with bare addresses (e.g. DB100.DBD0, DB100.DBD4) but no member names. This is the HMI-side mirror of the PLC-side problem and is itself a strong indicator that the STEP 7 source needs to be restored first.

Other HMI platforms follow the same pattern:

  • WinCC flexible / TIA Portal HMI: Direct STEP 7 integration preserves the symbols if the source project is intact.
  • WinCC (Classic): Uses the STEP 7 symbol server; same prerequisite.
  • Third-party SCADA (Ignition, iFIX, Citect): Typically imports via .xls export from STEP 7 (Options > Symbol Table > Export) or via OPC-DA/UA browsing of the PLC tag space.

9. Best Practices for UDT Management in S7-300/400 Projects

Preventions are far cheaper than the recovery described above.

9.1 Always Keep the Source Project Archival

  • Use a version-control system (SVN, Git with STEP 7 add-ins, or Siemens SIMATIC Logon + Version Trail if available) to archive every released version of the source project.
  • Store at minimum: the .s7p source, the Sources folder content, and an exported .xls symbol table.
  • Tag each archive with the CPU serial number, the CPU firmware version, and the project version string.

9.2 Always Export Symbols Before Upload

Before any Upload Station to PG action:

  1. Open the source project (if available) and export the Symbol Table: Options > Symbol Table > Export. Save the resulting .xls or .asc file.
  2. Export all UDTs, FBs, and DBs to STL/SCL source: Options > [Block Type] > Generate Source. Save the sources.
  3. Perform the upload.
  4. Import the symbols and re-compile the sources as described in Section 4.

9.3 Use STL/SCL Source Files for All UDT-Dependent Blocks

Source files are the only durable representation of UDT structure in an offline project. They survive block corruption, project copy errors, and CPU firmware updates. If the original project must be reconstructed from a backup, the source files can be recompiled to rebuild the entire UDT/FB/DB hierarchy.

9.4 Minimize UDT Multi-Instance Use on Memory-Constrained CPUs

For S7-31x CPUs with small work memory, prefer the following alternatives when the UDT memory cost is too high:

  • Use a single instance DB per FB instead of multi-instance, so the UDT structure is not inlined multiple times in the FB's code.
  • Split very large UDTs into several smaller UDTs to localize the memory cost.
  • Use the ANY pointer model for ad-hoc structures that don't need symbolic access from HMI.

9.5 Define Symbols in the Symbol Table for Every DB

A frequent contributor to the reported failure is missing Symbol Table entries for the UDT-derived DBs. After upload, STEP 7 falls back to the bare DB number (e.g. DB100) and provides no path back to the UDT member names. Always create an explicit symbol for every DB and FB in the offline project, even if the symbol is just the descriptive name:

// Symbol Table (Symbolic.sdf)
DB100   MOTOR_DB_1     DB100
DB101   MOTOR_DB_2     DB101
FB200   MOTOR_CTRL     FB200
UDT1    MOTOR_UDT      UDT 1

9.6 Configure S7-Graph and CFC Symbol Export

If the project uses S7-GRAPH sequencers or CFC charts, the S7-GRAPH FB and CFC chart are also affected by UDT symbol loss. Enable the Generate Symbol Table option in the S7-GRAPH and CFC editors so that the sequencer/chart symbols are written to the Symbol Table for re-import after upload.

10. Verification After Recovery

After applying any of the recovery procedures, perform the following verification:

  1. Symbolic view check. Open each recovered DB, switch to Declaration View and Data View. Member names should be present (not ???) and the data values should match the runtime process.
  2. Cross-reference. Use Options > Reference Data > Display and verify that every symbolic access from the FBs resolves to the correct address. Any unresolved reference will appear with a ??? marker.
  3. Check Block Consistency. With the source files regenerated, Edit > Check Block Consistency should now run successfully and return zero errors.
  4. Compile all sources. Options > STL Source Files > Check All > Compile All. Any remaining ??? in the generated blocks indicates a missing or renamed UDT member.
  5. Online compare. PLC > Compare Offline/Online should show no differences in the FBs (code) and the DBs (data) other than the expected values.
  6. Download and warm restart. Perform a controlled download and a CPU warm restart. Verify process behavior matches the pre-recovery state.

11. Frequently Asked Questions

Why are UDT-defined symbols missing after uploading a STEP 7 program from an S7-300/400 CPU?

The CPU stores only compiled block data, not UDT definitions or symbol tables. The upload reverses the compilation but cannot recover the UDT member-to-symbol mapping without the original UDT source. Copying the UDT back into the offline project does not relink an already-expanded DB.

Does copying the Symbol Table from the original project restore UDT member names inside a DB?

No. The Symbol Table holds only global symbols for blocks, I/O, and timers/counters. UDT member names are stored inside the UDT declaration itself and inside the FB/DB compiled interface. They require the original UDT definition and a successful recompile of the consuming blocks to be regenerated.

Why is the "Check Block Consistency" button grayed out in the uploaded program?

The button is only active when at least one block has a corresponding source file in the offline project's Sources folder. Uploaded blocks have no source, so STEP 7 has nothing to check. Generate a source for the affected block (right-click > Generate Source) and the button becomes active.

How can I preserve UDT symbols permanently so this does not recur?

Always export the UDT, FB, FC, and DB declarations as STL or SCL source files in the S7 program's Sources folder. Archive the entire source project with version control, and export the Symbol Table to .xls/.asc before every upload. Source files can be recompiled to fully reconstruct the UDT hierarchy in case of project loss.

Does UDT usage in S7-300/400 FBs significantly increase block size?

Yes. Each UDT instance in an FB's STAT section inlines the UDT body, producing a 2× to 3× increase in compiled MC7 code size compared to direct member declaration. On memory-constrained S7-31x CPUs (48–128 KB work memory), heavy UDT use can cause the project to exceed the available code or data memory.

What is the correct way to refresh DB values from the running CPU without losing source FBs?

In SIMATIC Manager, open the offline source project, connect online, and for each runtime DB that needs updating, right-click the online block and choose "Copy to Offline" (or drag-and-drop). Do not overwrite FBs this way; their source declarations must remain intact. This is the procedure described in Siemens FAQ 24352635.

How does the UDT symbol loss affect HMI tag imports?

HMI platforms such as Pro-face GP Pro EX, WinCC flexible, and WinCC Classic rely on the STEP 7 symbol server or the exported Symbol Table. When UDT member symbols are lost, the HMI import produces a tag list with bare addresses (DB100.DBD0) and no symbolic names, severely impacting alarm configuration, trending, and operator-facing descriptions. Restoring the STEP 7 source project restores the HMI-side symbols on the next import.

Back to blog