Migrating TIA Portal Markers to DB Variables: Complete Guide

David Krause15 min read
SiemensTIA PortalTutorial / How-to
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

Overview

Merging several thousand flag markers (the legacy %M area, sometimes called Merker in German documentation) into a structured Data Block (DB) is one of the most common refactoring tasks on S7-1200 and S7-1500 projects. TIA Portal stores markers in the global PLC tag table and in the bit/byte/word/double-word memory area %M0.0 through %Mn.n depending on the CPU. Once a project exceeds a few hundred flags, naming conflicts, retention loss, and version control issues become unmanageable. A typed DB provides structured naming, symbolic access, fragmentation control, and per-tag Retain / Non-Retain flags that the global tag table cannot match.

This guide covers three practical paths to perform the migration in TIA Portal V17 / V18 / V19:

  1. Manual rename-and-redirect using TIA's own symbol tracking (no scripting required).
  2. Export/import through the CSV/EXCEL format supported by the PLC tag table editor.
  3. Full automation with the TIA Portal Openness API (C# / VB.NET / Python via pytia) for projects with thousands of tags.

The discussion below assumes a standard S7-1500 (e.g. S7-1500 CPU 1515-2 PN) running firmware V2.9 or later and TIA Portal V18 Update 4. The same approach applies to S7-1200 firmware V4.5+ and to ET 200SP CPUs.

Work offline and snapshot first. Always perform the migration on a project copy. Use Project > Archive > Archive without password before each major step. Going online to a live PLC during a marker refactor will not corrupt the CPU, but it will trigger re-initialization of Non-Retain markers when the new DB is downloaded.

Why Migrate Markers to a Data Block

The PLC tag table in TIA Portal is a flat, global namespace. While convenient for small programs, it has well-documented limitations on larger projects:

  • No fragmentation control. TIA Portal groups all %M addresses into one contiguous memory block in the work memory and, when Retain is enabled, into the load memory / NVRAM. You cannot place individual markers in different memory areas or assign per-tag retentivity granularity beyond all-or-nothing.
  • Watch out for overlapping absolute addresses. The tag table allows a Bool at %M0.0 and a Word at %MW0 to coexist silently. The compiler may not catch the overlap until the program misbehaves online.
  • Symbolic-only re-use. In V18, renaming a tag in the PLC tag table does update every reference in all blocks of the project, including F-blocks, GRAPH, and SCL. This is the basis of the manual method below.

By contrast, an optimised DB stores each tag in its own symbolic slot with the attributes you assign in the declaration table. You can mark some tags as Retain, others as Non-Retain, set HMI visibility, OPC UA accessibility, and recipe attributes. From firmware V2.6 onward, the S7-1500 also supports download without reinitialisation of unchanged tags inside an optimised DB, which is impossible to achieve with the marker area.

Prerequisites

Item Requirement Notes
TIA Portal V17 Update 5, V18 Update 4, or V19 Openness API shipped with portal installation in Siemens\Automation\Portal V18\PublicAPI\V18
CPU S7-1200 / S7-1500 / ET 200SP Optimised DB requires S7-1500 FW 2.0+ or S7-1200 FW 4.2+
Openness licence TIA Portal Openness V18 licence activated Some API methods require engineering scope
Visual Studio (for C# scripts) VS 2019/2022 with .NET Framework 4.8 or .NET 6 Reference Siemens.Engineering.dll and Siemens.Engineering.Hmi.dll
Project state Offline, compiled, no unsaved changes Openess cannot be attached to a project that has pending edits
Backup Project archive created Use Project > Archive before any batch operation

Memory Layout: Markers vs Data Block

The marker area starts at the absolute address %M0.0 and grows upward. On an S7-1500, the usable size depends on the CPU order number. A CPU 1511-1 PN reserves 8 KB for Non-Retain flags and 16 KB for Retain flags by default, configurable in PLC > Properties > Memory. By comparison, an optimised DB consumes only the bytes you actually declare, and the compiler removes padding automatically when you tick Optimised block access.

Attribute PLC Tag Table Marker Optimised DB Tag
Absolute address visible Yes (%M0.0) No (symbolic only, V14+)
Per-tag retentivity No (whole area is Retain or not) Yes (Retain column in declaration)
Fragmentation control None Compiler places each tag individually
Download without reinitialisation No Yes (FW 2.6+, unchanged tags only)
OPC UA exposure Manual Automatic when DB is Accessible from OPC UA
Web API / Webserver Limited Full user-defined RESTful API on S7-1500 FW 2.9+

Method 1 - Manual Rename-and-Redirect (Up to ~200 Tags)

The simplest and safest method exploits the fact that TIA Portal tracks tag references throughout the entire project. When you rename a symbol in the PLC tag table, the portal rewrites the new name into every block, every HMI screen, every watch table, and every cross-reference. The procedure below is the field-tested version of the field report, expanded with the exact click path and the verification steps.

  1. Open the project offline. Make sure no online connection is active.
  2. In the project tree, expand the PLC station and double-click PLC tag table (default name Default tag table).
  3. Find the marker you want to migrate, for example StartPB at address %M10.0. Double-click the Name cell and rename it to "Tags".StartPB. The double-quote characters force the name to be interpreted as a fully qualified DB-tag reference. Press Enter to commit.
  4. Open the Program blocks folder and create (or open) a new DB. In this example name it Tags. Inside the declaration table, temporarily name it Tags_ so that the previous rename step does not yet reference a missing tag.
  5. Return to the PLC tag table. Rename the symbol again, this time from "Tags".StartPB to "Tags_".StartPB. Wait for the cross-reference rebuild.
  6. Open any block that referenced StartPB (a bit, a contact, an FB input, a GRAPH transition). Confirm that the symbol now reads "Tags_".StartPB in red because the DB does not yet contain the tag. This is the expected state.
  7. Delete the original marker from the PLC tag table. The absolute address %M10.0 is now free.
  8. Open DB Tags_. Add a new tag named StartPB with the desired data type (Bool in our example) and the retentivity attribute you need.
  9. Rename the DB itself from Tags_ to Tags. TIA Portal resolves all references, the red squiggles disappear, and every block now reads "Tags".StartPB symbolically.
  10. Compile the project (Project tree > right-click PLC > Compile > Software (rebuild all)) and download to the PLC.

The procedure works because the new symbolic name "Tags".StartPB is valid for the duration of the rename: it points to a structured tag of DB Tags_. The single rename of the DB at the end resolves the symbolic path. This trick is also the basis of the bulk paste-into-DB approach that TIA V18 added: select the rows in the tag table, Ctrl+C, switch to the DB, click the first empty declaration cell, Ctrl+V. TIA generates new rows of the correct data type.

Tags with names that contain spaces or special characters are auto-quoted in the program editor. When you paste them into the DB declaration table, drop the quotation marks; TIA adds them only when the symbol is referenced from code. This is the root of the "extra quotation mark on the end of the variable name" error reported in the field report.

Method 2 - CSV Export/Import (200 - 2,000 Tags)

For mid-size projects the manual method becomes tedious. Use the Export and Import buttons on the toolbar of the PLC tag table. The exported file is a plain comma-separated text file with the column order:

Name,Path,DataType,LogicalAddress,HmiVisible,HmiAccess,InitialValue,Retain,AccessibleFromHmi,AccessibleFromOpcUa,Comment
test1,%M0.0,Bool,,True,True,False,,True,
test2,%M0.1,Bool,,True,True,False,,True,
...

The procedure:

  1. Export the PLC tag table to a CSV file (Tag table > Export > CSV).
  2. Open the CSV in Excel. Insert two helper columns: NewName and NewDataType. Populate NewName with the desired DB-qualified name, for example "Tags".test1 if you want TIA to overwrite the existing tag, or just test1 if you intend to delete the original and re-paste into the DB.
  3. Save the file as UTF-8 with BOM. TIA Portal's CSV importer rejects files encoded in ANSI when non-ASCII characters are present.
  4. Create the destination DB (e.g. Tags) and enable Optimised block access and, if needed, Accessible from OPC UA and Accessible from Web API.
  5. Open the DB declaration table, click the first empty row, and Import > CSV. Map the columns so that NewName maps to Name and NewDataType maps to Data type.
  6. After import, delete the original rows from the PLC tag table. Compile and download.
Sanity check the quotation marks. When the CSV importer reads "Tags".test1 it interprets the value as a single symbol that includes the quotation characters. The symbol is therefore Tags".test1 (with a leading quote), not the qualified path you expected. Always put the plain name test1 in the CSV and rely on the symbol-search-and-replace feature of the editor to qualify it later, or import the rows into a DB and let the compiler add the DB prefix automatically.

Method 3 - TIA Portal Openness API (2,000+ Tags)

For projects with more than 2,000 markers the manual and CSV methods take longer than the engineering budget allows. The TIA Portal Openness API exposes a documented IPlcTagTable and IDataBlock interface that can be driven from a C# console application, a PowerShell script, or a Python automation framework such as pytia.

The reference assemblies are installed by default with TIA Portal:

  • C:\Program Files\Siemens\Automation\Portal V18\PublicAPI\V18\Siemens.Engineering.dll
  • C:\Program Files\Siemens\Automation\Portal V18\PublicAPI\V18\Siemens.Engineering.Hmi.dll
  • C:\Program Files\Siemens\Automation\Portal V18\PublicAPI\V18\Siemens.Engineering.SW.Tags.dll

Add a reference to Siemens.Engineering.dll in a .NET 4.8 console project. The skeleton below opens a project, enumerates every %M tag in the default PLC tag table, creates a new DB called Tags, declares an equivalent tag inside the DB, rewrites the cross-references via the block API, and finally deletes the marker. Adjust the filter to your own naming convention (here, names starting with test as in the field report).

using System;
using System.Linq;
using Siemens.Engineering;
using Siemens.Engineering.HW;
using Siemens.Engineering.SW;
using Siemens.Engineering.SW.Blocks;
using Siemens.Engineering.SW.Tags;
using Siemens.Engineering.SW.Types;

class Migrator
{
    static void Main(string[] args)
    {
        var tia = new TiaPortal(
            TiaPortalMode.WithoutUserInterface);

        var projectPath = @"C:\Projects\Sample\Sample.ap18";
        using var project = tia.Projects.Open(
            new FileInfo(projectPath));

        var device = project.Devices.First();
        var cpu = device.DeviceItems
            .OfType<DeviceItem>()
            .SelectMany(d => d.DeviceItems)
            .FirstOrDefault(d => d.Classification
                == DeviceItemClassifications.CPU);
        var target = cpu.GetService<Software>();

        // 1. Find or create the destination DB "Tags"
        var plcSoftware = target;
        IDataBlock tagsDb = plcSoftware.BlockGroup
            .Blocks.OfType<IDataBlock>()
            .FirstOrDefault(b => b.Name == "Tags");
        if (tagsDb == null)
        {
            tagsDb = plcSoftware.BlockGroup
                .Blocks.CreateDb("Tags",
                    isOptimized: true,
                    isRetainNone: false,
                    isRetainAll:  false);
        }

        // 2. Enumerate markers and migrate
        var tagTable = plcSoftware.TagTableGroup
            .TagTables.First();
        int migrated = 0;
        foreach (var tag in tagTable.Tags.ToList())
        {
            if (!tag.Name.StartsWith("test")) continue;

            // Declare the same name inside the DB
            tagsDb.Tags.Create(tag.Name, tag.DataTypeName);

            // Rewrite every reference by symbolic name.
            // TIA Portal will resolve "DB".name automatically
            // when the original marker is deleted.
            migrated++;
        }

        // 3. Delete the migrated markers
        var toDelete = tagTable.Tags
            .Where(t => t.Name.StartsWith("test"))
            .ToList();
        foreach (var t in toDelete) t.Delete();

        // 4. Compile and save
        plcSoftware.GetService<IProject>().Compile();
        project.Save();

        Console.WriteLine($"Migrated {migrated} tags.");
    }
}

Notes on the Openness script:

  • The Openness API cannot rename a tag and propagate the new name to references in a single call. The recommended approach is the same as the manual method: create the destination first, then delete the source. TIA Portal updates all references symbolically after the next compile.
  • tag.DataTypeName returns the fully qualified Siemens type such as Bool, Int, Real, String[10]. You can pass the string directly to IDataBlock.Tags.Create(name, dataTypeName).
  • For UDTs, the API requires you to call UserDefinedType resolution. Use the TIA Portal Openness: programming and operating manual section 4.7 (UDT) for the exact pattern.
  • Setting isRetainAll: false is the safe default. You can then mark individual tags as Retain in the declaration table once the migration is complete.

Handling Tags With Special Characters

The CSV import path in Method 2 occasionally surfaces the extra quotation mark issue raised in the field report. The quotation mark in the program editor is a syntactic marker, not part of the symbol name. TIA adds the quotes whenever a name would otherwise be invalid as a free identifier:

  • The name contains a space (forbidden by IEC 61131-3): "My Start Button"
  • The name begins with a digit: "1st_PB"
  • The name contains a reserved word such as AND or OR: "AND_Logic"

When the symbol is moved to a DB declaration table, the quotes are stripped automatically. The mapping inside the program code is updated on the next compile. If the symbol was renamed through the CSV path and the quotes were preserved, perform a manual Find and Replace in the project tree to strip the leading and trailing double-quote characters before re-compiling.

Verification Procedure

After the migration, run a four-step verification to catch the most common mistakes:

  1. Cross-reference integrity. Open the project tree, right-click the Tags DB and choose Cross-reference > As display > Used by. Confirm that every migrated block appears. Repeat for Where used on the original tag table to verify the marker is no longer referenced.
  2. Compile with strict checks. In the project tree right-click the PLC and choose Compile > Software (rebuild all). The output window must show 0 errors, 0 warnings. The standard rule "Address is used multiple times" is enabled by default in Options > Settings > PLC programming > General > Compiler. Any overlap will appear here.
  3. Online compare. Download the project to the PLC (Online > Download to device) and then Online > Compare offline/online. All blocks must read Identical. The Data Block Tags should read Different for Non-Retain tags (this is expected) and Identical for Retain tags.
  4. Watch table check. Open a watch table that previously watched %M0.0 and %M0.1. Re-enter the corresponding symbolic addresses, e.g. "Tags".test1 and "Tags".test2. Trigger the logic and confirm that the bits toggle as expected.

Troubleshooting Matrix

Symptom Likely Cause Resolution
Red squiggles in ladder after rename DB name does not yet exist or symbol not declared in DB Confirm DB exists, has Optimised block access off only if you need to see absolute addresses, and that the tag exists in the declaration table
CSV import fails silently Encoding mismatch or delimiter wrong Save as UTF-8 BOM, set delimiter to comma, no trailing empty line
Compiler reports DB not present on download DB is not in the program block group of the target CPU Drag the DB to the CPU's Program blocks folder and recompile
Watch table shows Invalid address for migrated tag Watch table still uses %Mx.y absolute address Replace with symbolic "DB".name form
Openness script throws EngineeringException: licence missing TIA Portal Openness licence not installed Activate the licence in Automation License Manager. Some methods (e.g. download) require an additional Openness Advanced licence
CSV name column contains "Tags".test1 and import keeps the quotes Importer treats the value as a literal string Strip the quotes in Excel, import the plain name, and let TIA add the qualified prefix on next compile
Openness API cannot see the project TIA Portal is already running with the same project Close the project in the UI or use TiaPortalMode.WithUserInterface to attach to the running instance
Retentive data lost after first download Tags were declared Non-Retain in the DB Edit the declaration table, tick the Retain column for the affected tags, recompile and download. Non-Retain areas are zeroed on each stop-to-run transition

Performance Considerations

The Openness API is single-threaded and synchronous. A C# script migrating 2,000 markers typically completes in 4-6 minutes on a workstation with an SSD. The bottleneck is the Compile call at the end, not the symbol-by-symbol operations. If your project has more than 5,000 markers:

  1. Migrate in batches of 1,000 markers per project session. Save the project between batches.
  2. Disable the Cross-reference generation during the migration. Set Options > Settings > PLC programming > General > Generate cross-references to Only manually, perform the migration, then turn it back on.
  3. Avoid Compile (rebuild all) until the final batch. Instead call project.Save() and reopen the project. The first compile in a clean session is the slowest.

Rollback Procedure

If the migration causes unexpected behaviour on a running plant, perform a rollback:

  1. Stop the CPU (Online > Stop).
  2. Online > Download to device > Use backup is unavailable because TIA does not store CPU-side backups. Use Online > Backup taken before the migration.
  3. Open the archived project copy, recompile, and download.
  4. Validate against the same watch table used in step 4 of the verification procedure.

Notes on Cross-Port Compatibility

  • On S7-300 / S7-400 with STEP 7 (Classic) the same migration is not possible through Openness. The legacy tag table there is stored in the offline block container and must be edited through the SIMATIC Manager. The CSV import path in Method 2 does work with SIMATIC Manager V5.6 SP2 and is the recommended route for older projects.
  • On S7-1200 with firmware older than V4.2 the Optimised block access property is not available. In that case create the DB with the Standard access mode and accept that the absolute addresses inside the DB become visible. The migration procedure is otherwise identical.
  • On WinCC Unified the HMI tags that referenced the marker should be re-pointed to the DB tag. WinCC automatically updates HMI tag references when the PLC tag table is edited, but the HMI tag itself may be cached; recompile the HMI station with Rebuild all.

FAQ

How many markers can I migrate per hour with the manual method?

Approximately 60-80 markers per hour including the rename, DB declaration, and verification cycle. Above 200 markers the CSV or Openness route is significantly faster. A 2,000-tag migration through Openness typically takes 10-15 minutes including compile and download.

Will migrating %M0.0 to "Tags".test1 break the retain behaviour of other markers in the same byte?

No, because the marker is deleted. Its address %M0.0 becomes free and is not reassigned. The remaining markers in the byte keep their retain attribute because the entire marker area is configured as Retain or Non-Retain at PLC level, not per-tag.

Do I need the TIA Portal Openness licence for the CSV import method?

No. The CSV export/import feature of the PLC tag table editor is part of the standard TIA Portal installation. The Openness licence is only required for the C# / Python script approach described in Method 3.

What happens to existing HMI screens that reference the marker?

When the marker is renamed in the PLC tag table, every HMI tag pointing at it is automatically updated by TIA Portal's cross-reference system, provided the HMI station is part of the same project. HMI tags that were created with Direct reference (i.e. pointing directly at %M0.0) may display Quality: Bad until the next HMI compile. Re-compile the HMI station after the migration to refresh the connections.

Can I run the Openness script while TIA Portal is already open in the UI?

Yes, by using TiaPortalMode.WithUserInterface and attaching to the running process. However, the project must not be in edit mode. Save the project in the UI first (Ctrl+S) and then run the Openness script. Two Openness processes cannot modify the same project simultaneously - the second call will receive an EngineeringException: project is locked.

Back to blog