1. Overview
Batch-oriented reporting is a regulatory expectation in pharmaceutical, food & beverage, and specialty chemical plants. Unlike time-windowed reports where the operator picks BeginTime and EndTime arbitrarily, a batch report is anchored to a single production unit: the batch. Every value, every trend curve, and every alarm message rendered in the PDF must trace back to the same BatchID that the system generated when the batch started and closed when the batch ended.
This article covers the end-to-end configuration of three report layouts in SIMATIC WinCC V7.3 (SP3 minimum, SP4 recommended for PDF print stability):
- Process value batch report (snapshot + statistical summary per batch)
- Trend batch report (WinCC Online Trend Control bound to the batch window)
- Alarm batch report (WinCC Alarm Control filtered by the batch window)
All three layouts are rendered as PDF files on the engineering station at batch end, while an identical hardcopy is simultaneously routed to the line printer.
2. Prerequisites
| Component | Minimum Version | Notes |
|---|---|---|
| SIMATIC WinCC | V7.3 SP3 Update 1 | SP4 (HF1) preferred for PDF print stability and OCX fix in CCTrcv/COM errors. |
| WinCC Archive Server | Included with V7.3 | Tag Logging fast / slow, Alarm Logging. |
| WinCC User Archives | Option “WinCC/User Archives” | License required on the server. |
| Report Designer | Included with V7.3 | Layouts are edited in WinCC Explorer > Report Designer. |
| VB Script engine | Installed with WinCC | Used to read User Archive rows and populate internal tags. |
| Printer driver | “Microsoft Print to PDF” or a hardware PDF printer | Configure as Windows printer WinCC_PDF. |
| Operator authorization | WinCC User Administrator | Authorize batch end + report print. |
Reference: Siemens FAQ 2463816 – Reducing C code in scripts for accessing User Archives. The VBScript patterns in this article are derived from that FAQ and adapted for WinCC V7.3.
3. Architecture & Data Flow
The batch report engine has three live data sources plus one configuration source:
The control plane is a single VBScript fired by the Batch End event. It queries the User Archive for the chosen BatchID, copies the StartTime and EndTime into internal tags, and triggers the three Report Designer PrintJobs.
4. Storing Batch Context in User Archives
Create a User Archive named UA_BatchMaster with the schema below. One row per batch. The BatchEnd action in the PLC is responsible for the final UPDATE that closes the row with EndTime and BatchStatus = "Closed".
| Column | Data Type | Length | Example | Purpose |
|---|---|---|---|---|
| BatchID | Text | 16 | B-2024-04571 | Unique key; primary identifier in reports. |
| ProductCode | Text | 16 | P-RIVOT-50 | SKU / material code. |
| BatchName | Text | 32 | Rivotril 50 mg Lot 4 | Human-readable name. |
| OperatorID | Text | 16 | OP-204 | Logged-in operator at batch start. |
| StartTime | DateTime | 8 | 2024-04-12 06:14:02 | Batch start; drives trend/alarm range. |
| EndTime | DateTime | 8 | 2024-04-12 11:48:33 | Batch end; drives trend/alarm range. |
| BatchStatus | Text | 12 | Closed | Open / Closed / Aborted. |
| TargetYield | Float | 4 | 49.5 | Printed in the header for QA review. |
| ActualYield | Float | 4 | 49.71 | Updated by PLC at batch end. |
DateAdd math in Section 9 assumes this epoch, not the Windows epoch. Convert explicitly when interoperating with other systems.5. Declaring the Batch Selection Tags
Internal tags live in the WinCC Tag Management and act as the dynamic parameter interface between the VBScript controller and the layouts. Create the following structure under Internal Tags > BatchReport:
| Tag | Type | Use |
|---|---|---|
| BatchReport.SelectedBatchID | Text (16) | Batch ID selected by the operator. |
| BatchReport.StartTime | Date/Time | Copied from UA row; drives trend/alarm range. |
| BatchReport.EndTime | Date/Time | Copied from UA row; drives trend/alarm range. |
| BatchReport.BatchDuration_s | Signed 32-bit |
EndTime − StartTime in seconds. |
| BatchReport.ProductCode | Text (16) | Header field on all three reports. |
| BatchReport.OperatorID | Text (16) | Header field on all three reports. |
| BatchReport.ActualYield | Float | Header field. |
| BatchReport.PrintTrigger | Binary tag | Rising-edge tag that VBS watches to start a print. |
| BatchReport.PrintStatus | Text (32) | “Idle”, “Printing”, “OK”, “Error:...”. |
Define the linear limits only if you need to enforce ranges in the face field. Date/Time tags default to 0 (1970) when uninitialized, which WinCC treats as a valid display but not a valid archive filter; the script in Section 9 must therefore write the tags before the PrintJob is fired.
6. Building the Process Value Report Layout
Open Report Designer > Page Layouts and create @Report_PV_Batch.rpl. Use the static page header for batch identification and the table body for process value snapshots:
- Insert a Static Text field with the project name. Tie a Dynamic Text field next to it to
BatchReport.ProductCodeusing the formula' & BatchReport.ProductCode & '. - Add a row of header tags:
BatchID,OperatorID,StartTime,EndTime,Duration. Use the Excel-style@BatchReport.StartTimesyntax for direct tag output. - Insert a Dynamic Table with one column per process value:
ReactorTemperature,AgitatorRPM,pH,Conductivity. Each cell uses the formula= BatchReport.PV_<TagName>. - For statistical summary use the Report Designer built-in functions:
= Min("TagLoggingFast:ReactorTemperature", BatchReport.StartTime, BatchReport.EndTime)
= Max("TagLoggingFast:ReactorTemperature", BatchReport.StartTime, BatchReport.EndTime)
= Average("TagLoggingFast:ReactorTemperature", BatchReport.StartTime, BatchReport.EndTime) - Add a formula column for yield deviation:
= BatchReport.ActualYield - BatchReport.TargetYield. - Set the page footer to
= "Page " & PageNumber & " of " & TotalPages.
BatchReport.StartTime renders as MM/DD/YYYY HH:MM:SS by default. To match a pharma SOP style, force YYYY-MM-DD HH:MM:SS via = Format$(BatchReport.StartTime, "yyyy-mm-dd hh:nn:ss").7. Building the Trend Report Layout
The trend report embeds the WinCC Online Trend Control so the curves are filtered by the batch window, not by a hardcoded calendar day.
- In a new layout
@Report_Trend_Batch.rpl, insert the OCXCCAxOnlineTrendControl.Picturefrom the object palette. - Open its Configuration Dialog; add curves for
ReactorTemperature,AgitatorRPM,pH, andConductivity. Each curve uses the WinCC Tag Logging archive that already collects the values. - Switch to the Properties tab and convert the following properties to dynamic parameters, each pointing at the corresponding internal tag:
•BeginTime→BatchReport.StartTime
•EndTime→BatchReport.EndTime
•TimeAxisRange→ calculated onceEndTime - StartTime - Set the Y-axis to Auto so an uninitialized layout does not crop small excursions. Lock it to a fixed range once you have the validated SOP window.
- Add a static header above the OCX showing
BatchIDandProductCode, identical to the PV layout, so the printed trend is self-identifying. - Insert a legend under the OCX using the
CCAxOnlineTrendControl’s built-in legend object.
Because BeginTime and EndTime are dynamic, the same layout renders correctly for any BatchID. Do not hardcode times into the layout — the layout is a template, the script is the parameter source.
8. Building the Alarm Report Layout
The alarm report mirrors the trend report pattern but uses the WinCC Alarm Control OCX:
- Create
@Report_Alarm_Batch.rpl. - Insert
CCAxAlarmControl.Picture. - In the Properties dialog, set:
•TimeFilter.StartTime→ dynamic →BatchReport.StartTime
•TimeFilter.EndTime→ dynamic →BatchReport.EndTime - Add visible columns: Date, Time, Status, Priority, Message Number, Message Text, Point of Error, Acknowledgement. Hide server/operator column clutter via
ColumnVisibleproperties if the SOP calls for it. - Set
SortColumntoTimeascending andRowCountto0(all rows). - At the bottom of the layout, add a count field using the formula
= CountMessages(BatchReport.StartTime, BatchReport.EndTime)
so the QA reviewer immediately sees “23 alarms during B-2024-04571”.
RowCountMax to a safe upper bound (e.g. 5000) and add a footer note: “Report truncated; full message list available in Alarm Logging export.”
9. VBScript: Reading User Archive by Batch ID
Place this routine in the global script library under Project Functions > Reports. It is called by the print button and by the Batch End event.
' --- Reports_GetBatch.bas ---
Option Explicit
Function Reports_PopulateBatchTags(ByVal sBatchID)
Dim oUaCon, oUaRst, oFields, sSql
Dim sProd, sOp, dStart, dEnd, dDur
Dim HMIRuntime
Set HMIRuntime = CreateObject("HMIRuntime.HMIRuntime")
Set oUaCon = CreateObject("UserArchive.CDBCONN")
oUaCon.UserArchive = "UA_BatchMaster"
' SQL against the User Archive; BatchID is text so quote it.
sSql = "SELECT BatchID, ProductCode, OperatorID, StartTime, EndTime, ActualYield " & _
"FROM UA_BatchMaster WHERE BatchID = '" & _
Replace(sBatchID, "'", "''") & "' AND BatchStatus = 'Closed'"
Set oUaRst = oUaCon.Read(sSql)
If oUaRst Is Nothing Then
Reports_PopulateBatchTags = False
Exit Function
End If
If oUaRst.RecordCount = 0 Then
HMIRuntime.Trace "Batch " & sBatchID & " not found or not Closed."
Reports_PopulateBatchTags = False
Exit Function
End If
oUaRst.MoveFirst
sProd = oUaRst.Fields("ProductCode").Value
sOp = oUaRst.Fields("OperatorID").Value
dStart = oUaRst.Fields("StartTime").Value
dEnd = oUaRst.Fields("EndTime").Value
HMIRuntime.Tags("BatchReport.SelectedBatchID").Write sBatchID
HMIRuntime.Tags("BatchReport.ProductCode").Write sProd
HMIRuntime.Tags("BatchReport.OperatorID").Write sOp
HMIRuntime.Tags("BatchReport.StartTime").Write dStart
HMIRuntime.Tags("BatchReport.EndTime").Write dEnd
dDur = DateDiff("s", CDate(dStart), CDate(dEnd))
HMIRuntime.Tags("BatchReport.BatchDuration_s").Write dDur
' Yield may be NULL while still in progress; guard it.
If Not IsNull(oUaRst.Fields("ActualYield").Value) Then
HMIRuntime.Tags("BatchReport.ActualYield").Write _
CDbl(oUaRst.Fields("ActualYield").Value)
End If
oUaRst.Close
Reports_PopulateBatchTags = True
End Function
The pattern is reusable: every parameter the layouts need is published through a tag. The script is the single point that converts raw UA rows into layout-ready values. For further reading on the UserArchive.CDBCONN object and SQL injection hygiene, see the Siemens FAQ referenced in Section 2.
10. PrintJob Configuration for PDF Output
WinCC PrintJobs are configured under Report Designer > Print Jobs. Create one PrintJob per layout:
| PrintJob name | Layout | Printer | Output path | File format |
|---|---|---|---|---|
| PJ_PV_Batch | @Report_PV_Batch.rpl | WinCC_PDF | C:\WinCC_Reports\<BatchID>\ | PDF (via Microsoft Print to PDF) |
| PJ_Trend_Batch | @Report_Trend_Batch.rpl | WinCC_PDF | C:\WinCC_Reports\<BatchID>\ | |
| PJ_Alarm_Batch | @Report_Alarm_Batch.rpl | WinCC_PDF + LinePrinter | C:\WinCC_Reports\<BatchID>\ + LPT1 | PDF + Hardcopy |
Configure the WinCC_PDF Windows printer with the following properties:
- Port:
FILE:, output directory redirected via PrintJob at runtime. - Default paper size: A4 portrait (use A3 for plants where SOPs require landscape trend capture).
- Disable “Allow scaling” so 1:1 page sizes are preserved; scale via the layout, not the driver.
To print both a PDF and a hardcopy, create two PrintJobs pointing at the same layout with different printers and call them in sequence from VBScript.
11. Triggering Reports on Batch End
Wire a button on the operator screen (or schedule a periodic VBS job that polls BatchReport.PrintTrigger) to:
' --- Reports_PrintByBatch.bas ---
Option Explicit
Sub Reports_PrintByBatchID_Clicked(ByVal sBatchID)
Dim HMIRuntime
Set HMIRuntime = CreateObject("HMIRuntime.HMIRuntime")
HMIRuntime.Tags("BatchReport.PrintStatus").Write "Printing"
If Not Reports_PopulateBatchTags(sBatchID) Then
HMIRuntime.Tags("BatchReport.PrintStatus").Write _
"Error: Batch not found"
Exit Sub
End If
' Force the layout to re-render the dynamic parameter binding.
HMIRuntime.Tags("BatchReport.StartTime").Write _
HMIRuntime.Tags("BatchReport.StartTime").Read
On Error Resume Next
HMIRuntime.PrintReport "PJ_PV_Batch"
If Err.Number <> 0 Then
HMIRuntime.Tags("BatchReport.PrintStatus").Write _
"Error: PJ_PV_Batch " & Err.Description
Exit Sub
End If
HMIRuntime.PrintReport "PJ_Trend_Batch"
HMIRuntime.PrintReport "PJ_Alarm_Batch"
On Error Goto 0
HMIRuntime.Tags("BatchReport.PrintStatus").Write "OK"
End Sub
Bind the button to this routine. Set the operator authorization level on the button to Batch_Report_Print in the User Administrator. The routine is reentrant, so it can be triggered from an external scheduling tool as well as from the HMI.
12. Verification & Commissioning Checklist
- Close a test batch in the PLC. Confirm that the Batch End action writes a new row into
UA_BatchMasterwithBatchStatus = 'Closed'. - On the operator screen, enter the test BatchID and click the print button.
- Watch
BatchReport.PrintStatus: it must transitionPrinting→OKwithin 5–20 s for short batches. - Open the three PDFs in
C:\WinCC_Reports\<BatchID>\. Each must contain the same BatchID in its header. - Visually verify the trend curve covers exactly the batch window — the left edge should snap to
StartTime, the right edge toEndTime. - Verify the alarm list does not include any message timestamped outside the batch window. A single stray message indicates the Alarm Control OCX is using a static filter instead of the dynamic property.
- Sign and date the hardcopy per the plant’s SOP. The PDF must be moved to the validated archive directory by the end-of-shift procedure.
- Repeat the full procedure with a deliberately long batch (> 24 h) to confirm the RowCountMax truncation rule on the alarm report.
13. Troubleshooting Matrix
| Symptom | Likely Cause | Fix |
|---|---|---|
| PDF file is empty or only contains the static header. | PrintJob fired before internal tags were written. | Add the “force rewrite” line in Section 11 before calling PrintReport. |
| Trend curves always show last 10 min instead of batch window. |
BeginTime/EndTime are static in the OCX properties. |
Reopen the OCX configuration dialog and convert BeginTime and EndTime to dynamic parameters pointing at BatchReport.StartTime and BatchReport.EndTime. |
| Alarm report shows messages from yesterday’s batch. | Alarm Control OCX is using a default filter of “last 8 hours” instead of dynamic filter. | Clear TimeFilter.UseDefault and bind TimeFilter.StartTime / EndTime dynamically. |
PrintStatus stuck at Error: Batch not found. |
Operator entered a typo, or the batch has not been closed yet. | Verify the row in WinCC Explorer > User Archives; check that BatchStatus = 'Closed'. |
| Microsoft Print to PDF prompts for filename interactively. | Printer driver not configured to use the default filename from the print job. | In Printer Properties → Advanced → Printing Defaults, uncheck “Always show dialog”. Configure output path via the PrintJob’s file output field. |
| Tag Logging average returns "N/A" in process value report. | The StartTime/EndTime arguments were passed as untyped variants. |
Wrap them in CDate(...) in the layout formula. |
| VBScript error “UserArchive.CDBCONN: No active connection”. | User Archive server has not started, or the runtime is on a client without the User Archives option licensed. | Confirm SIMATIC WinCC User Archives license on the runtime station. Check WinCC Explorer > Computer > User Archives. |
Print button works once, then PrintStatus stays at Printing. |
PrintJob spooler is jammed by a stuck EMF file. | Clear C:\Windows\System32\spool\PRINTERS\ and restart the WinCC PrintJob service. |
14. Archival & Reprint Workflow
Once PDFs are generated, the SOP usually mandates a defined folder structure and a hash check. Recommended pattern:
- Keep
C:\WinCC_Reports\<BatchID>\as the staging area only. - After
PrintStatus = OK, an OS-level scheduled task moves the three PDFs into\\NAS\BatchReports\<YYYY>\<MM>\<BatchID>\and computes SHA-256 hashes. - Reprints are served from the NAS path. The print button should never directly reprint a closed batch; require operator re-entry of the BatchID so that every reprint is logged in the WinCC audit trail.
This keeps the runtime “original” separate from the “archive copy” and gives QA a single source of truth.
How do I print a WinCC V7.3 batch report in PDF format by BatchID instead of by time range?
Store the BatchID, StartTime, and EndTime in a WinCC User Archive row at batch start. Use a VBScript (with the UserArchive.CDBCONN object) to read the row by BatchID, copy the times into internal tags, and trigger three Report Designer PrintJobs whose layouts use dynamic BeginTime/EndTime properties. See Sections 4, 9, and 11.
Can I bind the trend window in CCAxOnlineTrendControl to a variable batch time?
Yes. In the OCX configuration dialog, convert BeginTime and EndTime to dynamic parameters. Point them at BatchReport.StartTime and BatchReport.EndTime. The same layout renders correctly for any batch. See Section 7.
Which User Archive data type should I use for the batch StartTime column?
Use the DateTime column type with length 8. Internally it is a signed 32-bit seconds-since-1990 value. Wrap any cross-system exchange (e.g. to a SQL Server) in a DateAdd or explicit DateSerial(1990,1,1) offset to avoid epoch confusion.
Why does the alarm report include messages from outside the batch window?
The Alarm Control OCX defaults to a rolling “last N hours” filter. Clear TimeFilter.UseDefault in the OCX properties and bind TimeFilter.StartTime and TimeFilter.EndTime dynamically to BatchReport.StartTime / EndTime. See Section 8.
Can I print both a PDF and a hardcopy in one click?
Yes. Create two PrintJobs pointing at the same layout — one to WinCC_PDF (Microsoft Print to PDF), one to the line printer. Call them in sequence from VBScript using HMIRuntime.PrintReport "PJ_PV_Batch". See Sections 10 and 11.
Where is the official Siemens reference for User Archive scripting in WinCC?
Siemens FAQ 2463816 covers reducing C code in scripts for accessing User Archives and shows the canonical CDBCONN SQL pattern used in Section 9. The full WinCC V7.3 documentation set (Report Designer manual, Scripting manual, Options manual) is available on the Siemens Industry Online Support portal.