Overview: The Recipe View Variable Problem
A SIMATIC TP1500 Comfort HMI (6AV2 124-1QC02-0AX0 or current equivalent) running WinCC Comfort on TIA Portal V16, V17, or V18 cannot directly bind a STRING tag to the active-data-record selector in the recipe view. The control expects an internal ordinal — 0, 1, 2, ... — that matches the order in which recipe data records were created in the recipe editor. Operators, however, normally think in product codes ("VQ0", "VQ12", "code emballage a1") that are not pure integers. The configuration option exposed in the recipe view properties is the "Tag (Recipe Number)" (a.k.a. recipe index), and that tag must be a numeric HMI tag — not a STRING.
The Siemens support article Configuration options of the advanced recipe view documents this binding: the tag selected in "Configuration of the recipe view → Tag" is the recipe's data record number, and the value the HMI writes into that tag selects which data record the view shows.
Prerequisites
- TIA Portal V16, V17, or V18 with WinCC Comfort/Advanced installed.
- A SIMATIC TP1500 Comfort (6AV2 124-1QC02-0AX0 family) with firmware matching the TIA Portal version.
- An S7-1500 CPU (e.g., CPU 1515-2 PN 6ES7 515-2AM02-0AB0) configured in the same project with an HMI connection.
- Recipes defined in HMI tags under "Recipes" with consistent data record numbering.
- For the VBScript workaround: the VBScript runtime option enabled on the HMI (Runtime Settings → Services → VBScript = "On") per the TIA Portal Help "WinCC Engineering — Runtime VBScript".
WinCC Comfort Recipe Architecture and Configuration Reference
A "Recipe" in WinCC Comfort is a collection of "Recipe Elements" (one per HMI tag participating in the recipe), grouped into "Recipe Data Records". The data records appear in the recipe view in a fixed order — the order in which they were added or sorted in the editor. The HMI exposes the index of the currently selected data record to the PLC through a tag; the same tag is what the HMI's recipe view reads back to highlight the active record.
The recipe view configuration dialog exposes the following properties. Only the first is used to drive the selection; the others are display-only mirrors.
| Property | Type | Direction | Purpose |
|---|---|---|---|
| Tag (Recipe Number) | INT (signed 16) | Bidirectional | Selector. HMI writes the active ordinal here; the view reads from it to highlight a record. |
| Tag (Recipe Name) | STRING | HMI → PLC | Display-only. Mirrors the active recipe name back to the PLC; cannot be used to select. |
| Tag (Data Record Name) | STRING | HMI → PLC | Display-only. Mirrors the active data record name; cannot be used to select. |
| Tag (Variable Offsets) | INT | Bidirectional | Optional pointer offset for tag multiplexing; not used to select data records. |
Configuring the INT Tag Binding
- In the TIA project tree, expand "HMI Tags" under the TP1500 Comfort and create a new tag named
RecipeIndexof typeInt. - Connect the tag to a PLC tag in the S7-1500, e.g.,
DB_Recipes.SelectionIndex(Int). - In the recipe editor, confirm that data records are sorted in the order operators expect (record 0 = first product, record 1 = next, ...).
- On the screen that hosts the recipe view, open the "Configuration" dialog of the recipe view control.
- Under "Tag (Recipe Number)", select the
RecipeIndexHMI tag. Under "Tag (Recipe Name)", optionally select a STRING tag you intend to update for display. - In the PLC, write the desired ordinal (0, 1, 2, ...) into
DB_Recipes.SelectionIndex; the recipe view switches to the matching data record. The HMI also writes the active ordinal back into the same tag when the operator changes the selection.
Why a STRING Code Will Not Bind
The recipe view's selection property is a 16-bit signed integer internally. There is no property in the dialog that accepts a STRING as the selector. If a STRING tag is wired, the HMI runtime either flags a configuration error in the ES log or coerces the value through the recipe's data record name match — but that path is not stable across firmware versions and is not documented as supported in the Comfort manual. Operator codes such as VQ0, VQ12, or code emballage a1 carry non-numeric prefixes and cannot be converted at runtime by the HMI's built-in recipe logic.
The expected pattern in Siemens recipes is therefore:
- Each product variant = one integer index, mapped 1:1 in the PLC.
- The PLC (or an HMI script) translates operator-facing codes to indices.
Cross-Platform Recipe Conventions
The same conceptual pattern appears in vendor-neutral recipe libraries: the selector is always a numeric handle or a fully qualified name resolved server-side. WinCC Comfort's INT requirement is the same convention, just stricter on what may be wired to the HMI tag.
| Platform | Selector | Documentation |
|---|---|---|
| Siemens WinCC Comfort | INT ordinal via "Tag (Recipe Number)" | Siemens KB 109798671 |
| Beckhoff TwinCAT 3 | Numeric handle on RecipeManCommands.LoadRecipe
|
TwinCAT 3 PLC Intro |
| Bosch Rexroth IndraWorks | Recipe record name resolved by the editor | Rexroth Docs |
| Schneider EcoStruxure Machine Expert | Recipe name on oLoadRecipe
|
Schneider Product Help |
All four platforms require the application to manage the mapping from operator code to recipe handle. The Comfort panel differs in that the binding is to an INT tag, not to a name string on a method call.
Workaround 1: VBScript String-to-Integer Bridge
Because the recipe view will not read a STRING, a small VBScript routine on the HMI converts the operator-entered code into the integer index the view expects, then pushes the integer into RecipeIndex. The recipe view's tag polling picks up the new index on the next cycle and displays the right data record.
The script is attached to the "Load recipe" button as a click event:
' Script: btnLoadRecipe_OnClick
' Purpose: convert operator code (STRING) -> recipe index (INT)
' and write it to the recipe view's selection tag.
Sub OnClick(ByVal item)
Dim sCode, iIndex, iMax
' Operator code entered on the screen (HMI STRING tag)
sCode = SmartTags("code_emballage") ' e.g., "VQ0", "VQ12"
iMax = SmartTags("recipe_count") ' PLC provides total data record count
' Strip the "VQ" prefix; numeric suffix becomes the 0-based index
If Len(sCode) >= 2 Then
If Left(sCode, 2) = "VQ" Then
iIndex = CInt(Mid(sCode, 3)) - 1
Else
' Fallback: try to parse the trailing digits
iIndex = CInt(sCode) - 1
End If
Else
iIndex = 0
End If
' Bound-check against the recipe list size
If iIndex < 0 Then iIndex = 0
If iIndex > iMax-1 Then iIndex = iMax - 1
' Write the resolved index into the tag the recipe view polls
SmartTags("RecipeIndex") = iIndex
' Optional: echo the resolved name to an output field
SmartTags("loaded_recipe_label") = sCode
End Sub
The recipe_count tag is supplied by the PLC and is updated whenever the recipe list is rebuilt — typically a constant for a fixed product family. Keeping the bound check in the script prevents an out-of-range recipe from being selected if the operator mistypes.
Workaround 2: DB + ARRAY Lookup in the PLC
For sites where VBScript is disabled or where a strictly PLC-driven logic is preferred, a DB/array lookup keeps the translation in the S7-1500. Each product code is stored once as a STRING, paired with its 0-based integer index. The HMI only needs the STRING; the PLC computes the INT and writes it to RecipeIndex.
DATA_BLOCK "DB_RecipeLookup"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
STRUCT
Entry : ARRAY[0..199] OF STRUCT
Code : STRING[16]; // operator-facing code, e.g., 'VQ0'
Index : INT; // resolved ordinal for the recipe view
END_STRUCT;
Count : INT; // number of valid entries
END_STRUCT;
END_DATA_BLOCK
A small function block iterates the array on each request from the HMI. The HMI triggers the lookup with a 1-bit Request pulse and reads back the resolved index in the same DB.
// SCL - "FB_RecipeLookup"
// Triggered on rising edge of bRequest; fills iIndex with the
// first matching entry in DB_RecipeLookup.
IF bRequest AND NOT bRequestOld THEN
iIndex := -1;
FOR n := 0 TO "DB_RecipeLookup".Count - 1 DO
IF "DB_RecipeLookup".Entry[n].Code = sCode THEN
iIndex := "DB_RecipeLookup".Entry[n].Index;
EXIT;
END_IF;
END_FOR;
bFound := (iIndex >= 0);
END_IF;
bRequestOld := bRequest;
The HMI tag RecipeIndex is then driven by the PLC, not by the HMI. This pattern is closer to a translation table and survives the rare case where product codes are not strictly numeric.
Workaround 3: One Recipe File per Operator Code
When operator codes are stable and few (e.g., < 30 variants), many field engineers create one recipe file per code and switch files at runtime. WinCC Comfort's recipe view exposes "Active recipe" and "Active data record" as separate properties; the recipe file can be exchanged by a control command (e.g., LoadDataRecordFromFile or a manual change from the recipe view's toolbar) without rebuilding the index.
The drawback is that data record indices still need to be stable, so this approach is most useful when the entire recipe set is rebuilt per order. For line setups with a fixed product family, Workaround 1 or 2 is usually lighter to maintain.
Step-by-Step Implementation
- In Runtime Settings of the TP1500 Comfort, confirm "VBScript" is enabled under Services. Reload the runtime if it was off.
- Create the HMI STRING tag
code_emballageand an INT tagRecipeIndex. Both are reachable from the script. - Add a button on the recipe screen. In the button's Events → Click, add a VBScript action and paste the code from "Workaround 1".
- On the recipe view, set "Tag (Recipe Number)" to
RecipeIndex. - Build and download the project to the panel.
- In the HMI, type
VQ0into the input field bound tocode_emballage, press the button, and confirm the recipe view switches to the first data record. Repeat forVQ1,VQ2, ... and confirm the active record index in the HMI diagnostics matches what the script wrote.
Verification, Common Errors, and Field Cautions
After deploying, use the following checks:
- In the HMI's "Project diagnostics" (Control Panel → OP → Diagnostics → Project), confirm no recipe view binding error is reported.
- In the S7-1500's watch table, monitor
DB_Recipes.SelectionIndex; it should track the index the script writes and the value the recipe view writes back when the operator uses the view's own selector. - In the recipe editor, click "View" → "Order of data records" to confirm the index-to-name mapping matches the operator's mental model. The list shown there is the same order the recipe view uses.
- Trigger a power-cycle of the HMI and confirm the recipe view re-acquires the last selected data record (this is a property of the recipe view's "Save persistent" setting, not of the script).
| Symptom | Likely cause | Fix |
|---|---|---|
| Recipe view does not change when the script writes RecipeIndex | View not bound to the tag, or VBScript runtime disabled | Verify binding in the view's configuration; enable VBScript in Runtime Settings |
| Recipe view shows the wrong data record | Editor data records were reordered | Rebuild the DB lookup; never reorder records in production |
| Error "Tag type invalid" on download | A STRING tag is wired to "Tag (Recipe Number)" | Replace with an INT tag |
| Operator's typed code is not applied | Button click event not firing on the HMI | Confirm event in the project's button configuration; check that the screen is the active screen |
| Recipe view flashes between two records | Both PLC and operator write the index at the same time | Add an ownership bit (PLC vs Operator) and gate one of the writers |
Additional field cautions:
- Index drift after edits. Adding, removing, or reordering data records in the recipe editor will shift the ordinals. Document the mapping in the project (a comment in the PLC DB is enough) and review it on every recipe editor change.
- VBScript on Comfort panels. TP1500 Comfort supports VBScript, but smaller Comfort panels (KP400, KTP400) do not. The PLC-side lookup (Workaround 2) is the safer choice for mixed fleets.
- String length. WinCC Comfort STRING tags are 80 characters by default; operator codes longer than 16 characters should be modeled as a separate display string and not stuffed into the lookup.
- Firmware version. Recipe view properties documented for V16 are unchanged in V17 and V18 of TIA Portal, but a V14 project migrated to V17 may show the new property names with the old behavior — re-test the binding after migration.
- Recipe names with non-ASCII characters. "code emballage a1" is fine; non-ASCII labels are fine in display but should not be used as selection keys.
-
Concurrent selection from PLC and HMI. If the PLC writes
RecipeIndexwhile the operator is in the recipe view, the view will follow the PLC. To avoid operator confusion, gate PLC writes through a "PLC/Operator" ownership bit.
FAQ
Can I bind a STRING tag directly to the recipe view on a TP1500 Comfort?
No. The recipe view's selection property is an INT ordinal; only the "Tag (Recipe Number)" binding is honored, and it must be a numeric HMI tag. Use a script, a DB lookup, or a 1:1 integer-to-code mapping in the PLC.
Which TIA Portal versions support this recipe view configuration?
TIA Portal V16, V17, and V18 with WinCC Comfort/Advanced support the documented recipe view properties. V15.1 also supports them, but with some property names renamed in later releases; re-test after a project migration.
Do I need to enable VBScript on the panel for the string-to-int workaround?
Yes. In the TP1500 Comfort's Runtime Settings, switch "VBScript" under Services to "On". Without this, click events cannot execute the conversion script, and the recipe view will never see the resolved integer.
How do I keep recipe indices stable when I edit the recipe list?
Do not rely on the editor's auto-numbering. Either keep a separate DB mapping code → index, or document the ordinals in the recipe's data record name and never reorder records without updating the mapping.
Can the recipe view pick a record by name instead of by index?
WinCC Comfort does not expose a "select by name" property in the recipe view. The HMI runtime resolves the active name to an internal ordinal; that ordinal is what the "Tag (Recipe Number)" carries. Translating names to indices before they reach that tag is the supported pattern.