Overview
WinCC Professional (TIA Portal, RT Professional runtime) does not expose the SetDataRecordPLC function that exists in WinCC Comfort/Advanced. Engineers migrating a Comfort Panel HMI application to a PC-based WinCC Professional runtime, or those consolidating multiple Advanced panels onto a single SCADA station, must re-implement the "load a specific data record into the connected PLC tags" action using either the Recipe Control Tags (ID + Job) or the C-script User Archive (UA) standard functions.
This reference shows how to drive the recipe system from a custom selection interface using two integer PLC tags (RecipeNumber and DataRecordNumber) and the WinCC Professional recipe control tag mechanism, including commissioning checks and a fault matrix.
Prerequisites
- TIA Portal V16 or later with WinCC Professional installed.
- Configured HMI device of type "WinCC Professional" (PC-based or RT Professional).
- Configured Recipes in the project tree (project HMI device → "Recipes").
- Connection to the PLC with at least two writable integer tags exposed to the HMI (e.g.,
RecipeNumberInt andDataRecordNumberInt). - For the C-script path: a C script editor window in a screen or a global script. (C scripting is supported in WinCC Professional; VBScript is supported but does not expose the ua* functions the same way.)
Recipe System Differences: Advanced vs Professional
WinCC Comfort/Advanced stores recipes in a flat, panel-local data structure and exposes them through area pointers (RecipeNumber, DataRecord, DataRecordName, UserData) plus the high-level function SetDataRecordPLC. WinCC Professional uses a fundamentally different model:
| Aspect | WinCC Comfort/Advanced | WinCC Professional (RT) |
|---|---|---|
| Recipe storage | Panel-internal, binary RDB | Server-side database (SQL Server / SQLite) accessed via ua* API |
| Element→PLC mapping | Configured per element under "Properties → Process" | Configured under recipe element; Tags column points to PLC tags or HMI tags |
| Trigger to load to PLC | Area pointer job + SetDataRecordPLC function |
Recipe control tags (ID, Job, Status, Error) OR C/VBS script using ua* functions |
| Historical name | Recipes | User Archives (legacy WinCC Classic); same ua* API |
| User selection UI | Recipe View control | Recipe View control or custom UI driven by control tags |
Because the area pointer "job" concept is gone, the equivalent of an Advanced button calling SetDataRecordPLC becomes a two-step in WinCC Professional: (1) write the desired recipe number into the recipe's control tag for "ID", then (2) pulse a job code into the recipe's "Job" control tag to trigger the transfer.
Method 1 — Recipe Control Tags (Recommended)
Every recipe in a WinCC Professional HMI device has four automatically-created control tags that you can read and write from the PLC or from scripts. These are configured in the recipe's properties, not in the PLC.
Step 1 — Inspect the auto-generated control tags
- Open the project tree, expand your HMI device, then Recipes.
- Select a recipe (e.g.,
Recipe_1). - In the Inspector window choose Properties → Control tags.
- Note the four tag names. By default they are:
-
<RecipeName>_ID— DWORD, recipe number -
<RecipeName>_Job— DWORD, command code -
<RecipeName>_Status— DWORD, runtime state -
<RecipeName>_Error— DWORD, error code
-
Step 2 — Configure recipe elements and their process tags
- Select the Recipe elements tab in the lower area of the Recipes editor.
- For each element, set Name, Data type, and most importantly the Tag column — the HMI or PLC tag whose value is read/written when the record is loaded or saved. This corresponds to the Process tag in Advanced.
- Add one element row per value that must transfer to the PLC.
Reference: Creating Recipe Elements and Data Records (RT Professional).
Step 3 — Create the runtime data records
- Switch to the Data records tab of the recipe.
- Click Add to create a new data record row. Enter the Display name (operator-visible) and the internal record number.
- Populate the cells of the data record with the values that should be written to the process tags when the record is loaded.
Step 4 — Build the custom selection UI
On the screen where the operator selects a recipe/data record:
- Add two I/O fields bound to your two PLC tags (
RecipeNumberandDataRecordNumber) — these are the tags already present in your PLC logic. - Add a Button labelled "Load". Configure a Click event using the Set tag function or a small C/VBS script that performs the three writes below.
Step 5 — Drive the recipe with control tags
The sequence executed when the operator clicks "Load" is:
- Write the desired recipe number into
<RecipeName>_ID. - Write the desired data record number into
<RecipeName>_ID(recipe number is the high word in some firmware; in current versions a single DWORD carries the record number — see job table below). - Write a job code (e.g.,
6= "Load data record to PLC") into<RecipeName>_Job. - Poll
<RecipeName>_Status; the runtime clears the job bit when complete. - Evaluate
<RecipeName>_Errorfor fault codes.
Control tag job codes (RT Professional)
| Job code | Action |
|---|---|
| 1 | Save data record from PLC |
| 2 | Load data record from PLC to tags (preview) |
| 3 | Delete data record |
| 4 | Rename data record |
| 5 | Create new (empty) data record |
| 6 | Load data record to PLC (this is the Advanced SetDataRecordPLC equivalent) |
| 7 | Save data record as new |
Step 6 — C-script example (button click)
// Trigger "Load data record to PLC" via the control tag job interface
// Recipe: "Recipe_1"
// Control tags: "Recipe_1_ID", "Recipe_1_Job"
DWORD dwRecipe = GetTagWord("HMI_RecipeNumber"); // from PLC selection
DWORD dwRecord = GetTagWord("HMI_DataRecordNumber");
// Some firmware versions pack record number in the high word of _ID.
// If your project uses the high-word convention:
// DWORD dwID = (dwRecipe << 16) | (dwRecord & 0xFFFF);
// Otherwise _ID holds only the recipe number:
DWORD dwID = dwRecord;
SetTagDWORD("Recipe_1_ID", dwID);
SetTagDWORD("Recipe_1_Job", 6); // 6 = "Load data record to PLC"
For a PLC-driven solution, write the same two HMI control tags from a job bit in the PLC: set Recipe_1_ID first, then raise a pulse that writes 6 to Recipe_1_Job for one cycle, then clear it.
Method 2 — C-Script User Archive (UA) Functions
When a single selection interface must drive multiple recipes, or when the recipe name must be passed dynamically (e.g., selected from a string tag), the cleaner path is the C-script User Archive API. These are the same functions used in legacy WinCC Classic against the "User Archive".
UA function reference (RT Professional)
| Function | Purpose |
|---|---|
uaConnect |
Open/attach to a user archive (recipe backend) |
uaDisconnect |
Close the archive |
uaQueryArchive |
Read archive metadata (fields, types, record count) |
uaGetRecord |
Read a single data record into memory |
uaSetRecord |
Write a data record back to the archive |
uaGetFieldValue |
Read a single field value from the loaded record |
uaSetFieldValue |
Write a single field value into the loaded record |
uaArchiveSaveToFile |
Persist to disk (V19+) |
uaArchiveImport / uaArchiveExport |
CSV import/export (V19+) |
Step-by-step UA path
- Open the screen that contains the selection UI.
- Open the C editor for the "Load" button Click event.
- Insert the script shown below.
- Compile the script (the editor reports syntax errors inline).
C-script example — load a record to PLC tags
// Load a recipe's data record into process tags using the UA API
// Recipe: "Recipe_1"; record number comes from PLC tag HMI_DataRecordNumber
#include "apdefap.h"
void OnClickLoad(char* lpszPictureName, char* lpszObjectName)
{
long lRecord = GetTagWord("HMI_DataRecordNumber"); // 1-based
long lJob = 6; // not used by UA path, but kept for parity
BOOL bOK = FALSE;
// 1. Connect to the archive backing "Recipe_1"
long lArchID = uaConnect("Recipe_1");
if (lArchID == 0) {
SetTagWord("HMI_LoadError", 1001); // connection failed
return;
}
// 2. Read the requested record into the runtime cache
if (uaGetRecord(lArchID, lRecord) == TRUE) {
// 3. Push each archive field into the matching process tag
// Field order in uaGetFieldValue is 1-based and matches the
// recipe element order configured in the editor.
SetTagFloat("PLC_Tag_Setpoint", uaGetFieldValueFloat(lArchID, 1));
SetTagWord ("PLC_Tag_Mode", uaGetFieldValueLong (lArchID, 2));
SetTagFloat("PLC_Tag_Tolerance", uaGetFieldValueFloat(lArchID, 3));
bOK = TRUE;
}
// 4. Disconnect
uaDisconnect(lArchID);
// 5. Report
SetTagWord("HMI_LoadError", bOK ? 0 : 1002); // 1002 = record not found
SetTagBit ("HMI_LoadDone", bOK);
}
uaGetFieldValue was the archive field name string, not a numeric index. Check the TIA Information System entry Visualize Processes → Working with recipes → RT Professional → User Archive functions for the exact prototype in your installed version.
PLC-Side Coordination
For either method, the PLC must hand-shake cleanly with the HMI to avoid double triggers and to surface errors to the operator. A standard pattern is:
| PLC tag | Direction | Meaning |
|---|---|---|
RecipeNumber |
PLC → HMI | Recipe index (1..N) chosen by operator |
DataRecordNumber |
PLC → HMI | Data record index (1..M) chosen by operator |
LoadRequest |
PLC → HMI | Pulse; arms the HMI to perform the load |
LoadActive |
HMI → PLC | TRUE while the transfer is running |
LoadDone |
HMI → PLC | TRUE for one cycle on success |
LoadError |
HMI → PLC | Error code from <Recipe>_Error (Method 1) or ua* result (Method 2) |
Use the PLC LoadActive signal as an interlock: the operator selection should be disabled while a load is in progress. This prevents the operator from changing RecipeNumber between the ID and Job writes.
Verification and Commissioning
-
Tag visibility test. In RT Professional runtime, open the Tag simulator or use a temporary I/O field to confirm the four recipe control tags (
_ID,_Job,_Status,_Error) are online and writable. -
Single-record load test. Manually write recipe number = 1, record number = 1, then write job = 6. Verify in the PLC that each mapped process tag updates to the configured data record value within one scan cycle of
LoadDone. -
Error path test. Set record number to a value beyond the configured records and trigger job = 6. Confirm
LoadErrorreturns a non-zero code (typically0x8004xxxx-range codes for record-not-found, or a documented numeric code per your Information System). -
UI lock test. With
LoadActiveTRUE, attempt to changeRecipeNumberfrom the operator screen. The selection should be rejected or visually disabled. -
Restart persistence. Restart the RT Professional runtime. Recipe data records must reload from the configured database. Method 1 automatically re-reads; Method 2 (ua*) requires the script to
uaConnecton each invocation, which is the safe default.
Troubleshooting Matrix
| Symptom | Likely cause | Fix |
|---|---|---|
| Button click has no effect on PLC tags | Control tag _Job not being written, or written and cleared in the same cycle |
Hold the job value for at least 200 ms; check that the tag connection is configured with the right acquisition cycle |
| Partial update — some tags change, others don't | Recipe element has no Tag column entry | Open the recipe element, fill in the process tag for every row |
LoadError = 0x80040001 (record not found) |
DataRecordNumber is 0-based in your PLC but 1-based in RT Professional |
Add +1 on the PLC side or use the data record display number
|
| ua* script returns connection error | Recipe/archive name string doesn't match the editor's recipe name | Use exactly the recipe name from the project tree, case-sensitive |
| Data record loads old values after project recompile | Database not re-imported; RT runtime caches | Use Recipes → right-click → Export/Import data records after every engineering change, or enable auto-export in the recipe properties |
| Tags remain zero after job = 6 | Connection interrupt between HMI and PLC | Check the HMI connection in Devices & Networks; verify tag consistency in the PLC's Connection properties |
| Script compiles but does nothing in runtime | C script not registered as the event handler | Re-open the button's Events tab, ensure "OnClick" points at the C function you wrote |
Comparison of the Two Methods
| Criterion | Control tags (ID/Job) | ua* C-script |
|---|---|---|
| Engineering effort | Low — configure once, drive from PLC | Medium — write & maintain C code |
| Performance | Optimized runtime path, single transfer per job | Per-field read/write; slower for large recipes |
| Dynamic recipe/record name | No — recipe is fixed at compile time | Yes — name is a string parameter |
| PLC-driven trigger | Native fit (control tags are HMI tags) | Requires a script triggered by a tag change event |
| Error reporting | Built-in via _Error tag |
Manual — return values must be interpreted |
| Best for | 1-to-N fixed recipes, exact Advanced replacement | Generic recipe engine, dynamic selection lists |
References Inside the Documentation Set
Open the TIA Portal Information System and navigate:
- Visualize Processes → Working with recipes → RT Professional — for editor and control tag specifics.
- Visualize Processes → Working with recipes → RT Professional → Data transfer to PLC → Control tags — the definitive source for the job code table above.
- Visualize Processes → Working with recipes → RT Professional → User Archive functions — full ua* function reference.
For recipes on Comfort/Advanced panels (used here only for comparison), see Using the advanced recipe view (Basic Panels, Panels, Comfort Panels, RT Advanced).
What is the WinCC Professional equivalent of SetDataRecordPLC?
There is no direct equivalent function. Use the recipe's control tag interface: write the data record number into <RecipeName>_ID and then write the job code 6 (Load data record to PLC) into <RecipeName>_Job. The runtime transfers the data record values into the process tags configured on each recipe element.
Where are the recipe control tags configured in TIA Portal?
Select your HMI device in the project tree, then Recipes → select the recipe → Properties → Control tags. The four tags (_ID, _Job, _Status, _Error) are created automatically; you can rename them but not remove them.
Are recipe numbers and data record numbers zero-based or one-based in RT Professional?
Both are 1-based in the runtime interface. If your PLC logic uses 0-based indexing, add 1 before writing the value to <RecipeName>_ID to avoid the "record not found" error code (typically 0x80040001).
Can I select a recipe by name from a string tag in WinCC Professional?
Yes, but only through the C-script User Archive (ua*) API — for example uaConnect, uaGetRecord, and uaGetFieldValue. The control tag interface (Method 1) requires a fixed recipe name selected at compile time.
Why are the ua* functions called "User Archive" if I configured a Recipe?
In WinCC Classic (pre-TIA) the underlying mechanism was called the User Archive. The TIA Portal renamed the editor to "Recipes" but kept the same C API for compatibility, so all ua* functions still work against a recipe configured under Recipes in the project tree.