Adding Logo and Borders to Excel Reports in WinCC Flexible 2008 SP2 Runtime
WinCC Flexible 2008 SP2 Runtime does not expose a built-in, dialog-driven way to embed a corporate logo or to apply cell borders inside the formatted output of an Excel report. The standard report object writes tag values, alarm archives, and process values into a defined layout, but the visual treatment of the report — header graphics, lines, frames, and corporate identity elements — must be carried in by the template. The supported and field-proven approach is to author a fully formatted Excel template (.xlt or .xls) that already contains the company logo, header text, cell borders, fonts, and number formats, and to use a VBScript function in the WinCC Flexible project to copy this template, populate it from runtime tags, and save the result under a runtime-generated filename. This article documents that workflow end-to-end with code, parameter tables, and the diagnostic checks that commissioning engineers typically need.
CreateObject("Excel.Application") is supported. WinCE-based Panel RTs do not host Excel and cannot use this approach. For current-generation TIA Portal projects use the WinCC Unified Excel Reporting add-in workflow instead.1. Architecture: How Excel Reporting Works in WinCC Flexible 2008
WinCC Flexible 2008 SP2 ships two native report objects that can target Excel as a print/export target:
- Report (alarm / process value log) — drawn from the configured alarm archive or process value archive and rendered through a layout. Excel export is available when the layout is configured with a spreadsheet target.
- Recipe report — produces a single-line-per-ingredient tabular view of a recipe set; it is the closest native analog of a "batch sheet" and is the layout the source conversation modified.
Both objects are bound to a layout file stored on the runtime filesystem. Layout files in WinCC Flexible are proprietary and do not give access to the chart-frame, picture-insertion, or border properties the customer requested. The widely deployed and Siemens-supported workaround is to drive Excel directly from a VBScript triggered by a button, a scheduled task, or a value-change on a tag. The script becomes the layout.
The runtime model is therefore:
When the script fires, the template is opened, the placeholder cells are written with live tag values, and a new workbook is written to the report destination. The original template is never modified, so every batch report inherits the customer's branding and frame automatically.
2. Prerequisites
- Microsoft Excel installed on the RT PC. A 32-bit Excel installation is recommended when the WinCC Flexible RT is 32-bit; mixing 32/64-bit Office with 32/64-bit RT will not work because VBScript binds to the first matching registered class id.
- WinCC Flexible 2008 SP2 (or SP3/SP4) engineering software with a project compiled for the PC RT target.
- VBScript editor access on the RT, enabled in Project > Settings > Runtime Settings > Services. The default is enabled; verify before commissioning.
- Write permission for the runtime user account on the directory that will hold the template and the generated reports. On a multi-user RT, the path should be on a local fixed disk or a UNC path the RT service can reach; mapped network drives lose their mapping when the RT runs as a service.
- Template authoring workstation with Excel 2003/2007/2010. The template should be saved as Excel 97-2003 Workbook (.xls) if any RT PC still has Office 2003, or as Excel Template (.xlt) when forcing the file to be treated as a template on open.
3. Step 1 — Author the Excel Template with Logo and Borders
Open a new workbook in Excel and lay out the report as it should look at runtime. The convention is to designate specific cells as data cells and to leave every other cell fully formatted. The script only writes to the data cells.
3.1 Cell layout convention
| Range | Type | Content (template) | Written by script? |
|---|---|---|---|
| A1:F1 | Merged header | Company name + tagline, Calibri 16pt bold | No |
| A2:F2 | Image anchor | Company logo (.png/.bmp/.jpg) inserted via Insert > Picture | No |
| A4:F4 | Section header | "Batch Production Report", bordered | No |
| A5 | Label | "Batch ID" | No |
| B5 | Data cell | (empty, format: text) | Yes — SmartTags("Batch_ID")
|
| A6 | Label | "Operator" | No |
| B6 | Data cell | (empty, format: text) | Yes — SmartTags("Operator")
|
| A7 | Label | "Start time" | No |
| B7 | Data cell | (empty, format: yyyy-mm-dd hh:nn:ss) | Yes — SmartTags("Batch_Start")
|
| A8 | Label | "End time" | No |
| B8 | Data cell | (empty, format: yyyy-mm-dd hh:nn:ss) | Yes — SmartTags("Batch_End")
|
| A10:F25 | Measurement table | Header row + empty rows, full borders | Yes — loop writes row by row |
3.2 Applying cell borders
Select the report range (e.g. A4:F25) and apply borders from the ribbon. The Microsoft Excel support article on cell borders documents the user-interface path and the underlying constants used by the Excel object model. The same constants are reused by the script in step 4.
| VBScript constant | Decimal | Border edge |
|---|---|---|
xlDiagonalDown |
5 | Diagonal from top-left to bottom-right |
xlDiagonalUp |
6 | Diagonal from bottom-left to top-right |
xlEdgeBottom |
9 | Bottom edge of the range |
xlEdgeLeft |
7 | Left edge of the range |
xlEdgeRight |
10 | Right edge of the range |
xlEdgeTop |
8 | Top edge of the range |
xlInsideHorizontal |
12 | Horizontal lines between rows |
xlInsideVertical |
11 | Vertical lines between columns |
Recommended pattern for a corporate frame is to set xlEdgeTop, xlEdgeBottom, xlEdgeLeft, xlEdgeRight to Thin / Continuous / Automatic, and the inside lines to Hairline / Continuous / Automatic. This combination is readable on print and survives a highlighter pass from a quality auditor.
3.3 Inserting the company logo
Place the cursor in cell A2 (or any cell that will hold the image) and use Insert > Pictures > This Device. Anchor the picture To Cell, untick Move with cells only if you want the image pinned to its row during sorting — for a report it should be anchored to the cell. Acceptable formats are PNG, JPG, BMP, GIF, and TIFF; PNG at 150-300 DPI gives the best print quality without bloating the file. A logo of 200×60 pixels at 96 DPI fits a typical header band and keeps the workbook under 100 kB.
3.4 Save the template
Save the workbook as report_template.xlt into the runtime-visible path, typically:
- Local RT folder:
C:\Program Files\Siemens\Automation\WinCC Flexible 2008 RT\Reports\report_template.xlt - Or an operator-facing path:
D:\Reports\report_template.xlt
Use Save As > Excel Template (.xlt) to flag the file as a template. Excel will then open it as a copy in memory, leaving the original untouched. If you save as .xls instead, the script must explicitly use SaveAs to write a new file, which is the approach the source conversation adopted.
4. Step 2 — Configure the Runtime Storage Path
The runtime needs read access to the template and write access to the report destination. In the engineering project, declare both paths as paths so they can be edited at the panel without re-compiling:
- Open Project > Paths.
- Add
REPORT_TEMPLATEpointing to the.xltlocation. - Add
REPORT_DESTINATIONpointing to the output directory (e.g.D:\Reports\Archive\).
These are not filesystem variables — they are project constants surfaced under Runtime > Project Settings > Paths on the target. Keep them lowercase on the filesystem; Excel does not care, but case-sensitive backup tools do.
5. Step 3 — Write the VBScript Function
The function below opens the template, writes the tag values into the placeholder cells, applies a thicker border around the measurement block, embeds a logo if the template does not already have one, and saves the result. It is the same skeleton that ships in customer projects derived from the source conversation, extended with explicit object cleanup, error handling, and configurable paths.
'--------------------------------------------------------------
' WinCC Flexible 2008 SP2 RT — Excel Report Generator
' Trigger: scheduled task, button press, or value-change on
' tag "Generate_Report_Trigger"
'--------------------------------------------------------------
Option Explicit
Const xlContinuous = 1
Const xlAutomatic = -4105
Const xlThin = 2
Const xlMedium = -4138
Const xlEdgeTop = 8
Const xlEdgeBottom = 9
Const xlEdgeLeft = 7
Const xlEdgeRight = 10
Const xlInsideHorizontal= 12
Const xlInsideVertical = 11
Const msoTrue = -1
Const msoFalse = 0
Sub Generate_Batch_Report()
Dim objExcel, objWkb, objWks, objFSO, objFolder
Dim sTemplate, sDestDir, sBatchID, sOutFile, sErr
Dim iRow, iCol
On Error GoTo EH
'--- 1. Resolve paths from project constants ---
sTemplate = SmartTags("REPORT_TEMPLATE")
sDestDir = SmartTags("REPORT_DESTINATION")
sBatchID = SmartTags("Batch_ID")
'--- 2. Validate inputs ---
If Len(sTemplate) = 0 Or Len(sDestDir) = 0 Or Len(sBatchID) = 0 Then
SmartTags("Report_Status") = "E: missing path or batch id"
Exit Sub
End If
'--- 3. Ensure destination directory exists ---
Set objFSO = CreateObject("Scripting.FileSystemObject")
If Not objFSO.FolderExists(sDestDir) Then objFSO.CreateFolder sDestDir
'--- 4. Launch Excel invisibly ---
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = False
objExcel.DisplayAlerts = False
objExcel.ScreenUpdating = False
'--- 5. Open the template (logo + borders pre-applied) ---
Set objWkb = objExcel.Workbooks.Open(sTemplate, , True) ' ReadOnly=True keeps template intact
Set objWks = objWkb.Sheets(1)
'--- 6. Optional: dynamically insert a logo if template lacks one ---
If objWks.Shapes.Count = 0 Then
objWks.Shapes.AddPicture _
Replace(sTemplate, "report_template.xlt", "company_logo.png"), _
msoTrue, msoTrue, 10, 10, 200, 60
End If
'--- 7. Write tag values to placeholder cells ---
With objWks
.Range("B5").Value = sBatchID
.Range("B6").Value = SmartTags("Operator")
.Range("B7").Value = SmartTags("Batch_Start")
.Range("B8").Value = SmartTags("Batch_End")
' Measurement block A10:F25 — write 16 rows from array tag
For iRow = 0 To 15
.Cells(11 + iRow, 1).Value = iRow + 1
.Cells(11 + iRow, 2).Value = SmartTags("Meas_Name_" & (iRow + 1))
.Cells(11 + iRow, 3).Value = SmartTags("Meas_Value_" & (iRow + 1))
.Cells(11 + iRow, 4).Value = SmartTags("Meas_Unit_" & (iRow + 1))
.Cells(11 + iRow, 5).Value = SmartTags("LSL_" & (iRow + 1))
.Cells(11 + iRow, 6).Value = SmartTags("USL_" & (iRow + 1))
Next iRow
End With
'--- 8. Re-assert borders on the measurement block in case
' the template author left them off ---
With objWks.Range("A10:F26").Borders
.Item(xlEdgeTop).LineStyle = xlContinuous : .Item(xlEdgeTop).Weight = xlMedium
.Item(xlEdgeBottom).LineStyle=xlContinuous : .Item(xlEdgeBottom).Weight=xlMedium
.Item(xlEdgeLeft).LineStyle = xlContinuous : .Item(xlEdgeLeft).Weight = xlMedium
.Item(xlEdgeRight).LineStyle= xlContinuous : .Item(xlEdgeRight).Weight= xlMedium
.Item(xlInsideHorizontal).LineStyle = xlContinuous
.Item(xlInsideVertical).LineStyle = xlContinuous
End With
'--- 9. Save under runtime-generated filename ---
sOutFile = sDestDir & "Report_" & sBatchID & "_" & _
FormatDateTime(Now, 2) & "_" & _
FormatDateTime(Now, 4) & ".xls"
sOutFile = Replace(sOutFile, "/", "-") ' Excel does not like / in sheet names
objWkb.SaveAs sOutFile, -4143 ' xlWorkbookNormal
SmartTags("Report_Status") = "OK: " & sOutFile
SmartTags("Report_FilePath") = sOutFile
'--- 10. Clean up ---
objWkb.Close False
objExcel.Quit
Set objWks = Nothing : Set objWkb = Nothing : Set objExcel = Nothing
Set objFSO = Nothing
Exit Sub
EH:
sErr = "E" & Err.Number & " " & Err.Description
SmartTags("Report_Status") = sErr
If Not objWkb Is Nothing Then objWkb.Close False
If Not objExcel Is Nothing Then objExcel.Quit
Set objWks = Nothing : Set objWkb = Nothing : Set objExcel = Nothing
Set objFSO = Nothing
End Sub
5.1 Code notes
-
Workbooks.Open(sTemplate, , True)opens the file in read-only mode so the original template is not modified. The subsequentSaveAswrites a new workbook to the destination. -
objExcel.DisplayAlerts = Falsesuppresses the "Keep current format?" prompt that Excel shows when saving an .xls from a newer Excel version. Set this toTrueduring commissioning to see the dialogs and identify the format being written. - Border constants are defined at the top of the module.
xlContinuous = 1is the only line style used for solid corporate frames; the Microsoft Excel cell borders reference documents the full set. - The
FormatDateTime(Now, 2)returnsyyyy/mm/ddon most locales; replace the date formatter with a fixed format string if your plant enforces a particular naming convention.
6. Step 4 — Bind the Script to a Trigger
There are three trigger patterns in WinCC Flexible 2008 that engineers typically choose between:
| Trigger | Where configured | Use case | Limitation |
|---|---|---|---|
| Scheduled task (cyclic / once) | Project > Schedules | End-of-shift report, daily summary | Drift between trigger time and PC clock |
| Tag change | Tag properties > Events | End of batch (Batch_ID transitions to a new value) | Edge detection required |
| Button click | Button properties > Events > Press | Operator-driven ad-hoc report | Operator must be on the right screen |
For batch reporting the recommended binding is tag change on a Boolean or integer trigger tag. Configure the tag with an event that calls Generate_Batch_Report on a rising edge only. A common implementation writes a one-shot pulse from the PLC (0 → 1 → 0) and uses the rising edge to fire the report. This avoids duplicate reports when the runtime reads the same value twice.
7. Border and Logo Reference Tables
The following tables consolidate the Excel object-model constants the script uses. They are the same constants a user would set in the Excel UI; the script reaches them programmatically.
7.1 LineStyle constants
| Constant | Value | Appearance |
|---|---|---|
xlContinuous |
1 | Solid line |
xlDash |
-4115 | Dashed |
xlDashDot |
4 | Dash-dot |
xlDashDotDot |
5 | Dash-dot-dot |
xlDot |
-4118 | Dotted |
xlDouble |
-4119 | Double line |
xlLineStyleNone |
-4142 | No line |
7.2 Weight constants
| Constant | Value | Use |
|---|---|---|
xlHairline |
1 | Inside grid lines |
xlThin |
2 | Standard frame |
xlMedium |
-4138 | Section frame, headline band |
xlThick |
4 | Outer frame on a corporate template |
7.3 Shapes.AddPicture parameters
| Parameter | Type | Meaning |
|---|---|---|
Filename |
String | Absolute path to the image file |
LinkToFile |
Boolean |
msoTrue = linked, msoFalse = embedded (use msoFalse for portable reports) |
SaveWithDocument |
Boolean |
msoTrue = save image inside the workbook |
Left, Top |
Single | Position in points (1 point = 1/72 inch) |
Width, Height |
Single | Display size in points |
LinkToFile = msoFalse in a report that may be moved to a different folder or sent to a customer. A linked picture shows a red X the moment the original image is no longer reachable from the report's path.8. Error Handling and Diagnostics
The most common failure modes seen in field deployments are listed below with their hex/decimal error codes and the corrective action.
| VBScript error | Hex / dec | Typical cause | Fix |
|---|---|---|---|
| ActiveX component can't create object | 0x800A01AD / -2146827859 | Excel not installed, or wrong bitness (64-bit RT with 32-bit Office) | Install matching Office bitness; verify with CreateObject("Excel.Application") in a small test |
| Method 'Open' of object 'Workbooks' failed | 0x800A03EC / -2146827252 | Template path not reachable by the RT service | Use an absolute local path; UNC paths must be reachable from the service account |
| Method 'SaveAs' of object '_Workbook' failed | 0x800A03EC / -2146827252 | Destination directory read-only, or filename contains illegal characters | Strip / : * ? " < > | from filenames; verify write permission |
| File format is not valid | 0x800A03EC / -2146827252 | Template is .xlsx and Office 2003 is on the RT | Re-save template as .xls (Excel 97-2003) |
| Subscript out of range | 0x800A0009 / 9 |
Sheets(1) called on a workbook with no sheets (template corrupted) |
Open template manually, save again, re-deploy |
| Permission denied | 0x800A0046 / 70 | Template opened by another user (read-only on the network) | Place template on the local RT disk; never on a shared editor's workstation |
Two operational rules eliminate most of the entries above:
- Always store the template on a local fixed disk of the RT, never on a network share. The RT service may not have a mapped drive letter.
- Always set the template as read-only at the filesystem level so a misbehaving script cannot corrupt it. The script opens it with
ReadOnly:=Truefor the same reason.
9. Verification and Commissioning
A sign-off script for the QA team should include the following checks. Run them once during Site Acceptance Test (SAT) and again on any Excel/Office update.
-
Template path resolution — From the RT, open a command prompt under the same service account and confirm
dir "%REPORT_TEMPLATE%"listsreport_template.xlt. - First-run end-to-end — Trigger the report manually from the HMI button. Confirm the new file appears in the destination, contains the logo in the header, and shows borders on the measurement block.
- 100-run stress — Loop the trigger 100 times with synthetic data. Verify (a) all 100 files are written, (b) file sizes are within 10% of each other, (c) the template file is unchanged (compare SHA-256).
-
Edge cases — Trigger a report with an empty
Operatortag. Trigger one with aBatch_IDcontaining a slash. Verify that the script does not crash and that the output filename has illegal characters replaced. - Print preview — Open one of the generated files, send to print preview, and verify the logo and borders render on a real printer or to PDF.
- Multi-user — If the RT supports concurrent operators, trigger two reports within one second. Verify both are written and that Excel does not raise a "file in use" error. If it does, the script must serialize the calls with a single global mutex tag.
10. Performance and Runtime Footprint
Each report open Excel.Application starts a new EXCEL.EXE process. The WinCC Flexible RT is forgiving of this for low-frequency reports (end of batch, end of shift), but it is not appropriate for tag-change-rate triggers on fast processes. Approximate numbers from the field:
| Action | Typical duration (PC, x86, HDD) |
|---|---|
| Excel.Application cold start | 1.2 – 2.0 s |
| Open 50 kB template | 0.3 – 0.5 s |
| Write 16 rows + format | 0.1 – 0.2 s |
| SaveAs .xls | 0.4 – 0.6 s |
| Quit and cleanup | 0.2 – 0.4 s |
| Total per report | 2.2 – 3.7 s |
For reports triggered more often than once per minute, consider keeping a single Excel.Application instance alive and reusing it via a long-lived script object. WinCC Flexible 2008 SP2 does not expose an in-process Excel server, so this is a workaround that is brittle across RT restarts and is not recommended in production for the typical batch-reporting workload.
EXCEL.EXE can remain in memory. Add a watchdog that kills EXCEL.EXE at the start of each Generate_Batch_Report call if it has been idle for more than N minutes. Set objExcel = Nothing alone is not sufficient on a hard RT abort.11. Migration Path to WinCC Unified
Customers continuing to use WinCC Flexible 2008 SP2 should be aware that the platform is in the legacy / extended support phase and that the Excel-COM approach above is replaced in current TIA Portal projects by the WinCC Unified Reporting add-in for Excel. The new workflow:
- Install the WinCC Unified Reporting add-in in Excel on the engineering station.
- Open the add-in and connect it to the Unified runtime; tag values are exposed as a connected data model.
- Author the report as a regular Excel file — the Reporting add-in in Excel page documents the enablement steps in the Trust Center.
- Publish the report template to the runtime; reports are generated server-side, not via per-report Excel launches.
The data-cell philosophy (write tags into fixed cells of a styled template) is identical between the two platforms, which makes the migration mechanical: the template can be reused, only the binding mechanism changes.
12. Reference Material
- Microsoft Support — Apply or remove cell borders on a worksheet (line-style, weight, and edge constants)
- TIA Portal docs — Adding the Reporting add-in in Excel (RT Unified) (target architecture for migration)
FAQ
Why does the company logo disappear or show a red X in the generated report?
The logo is linked to the original image file (LinkToFile = msoTrue), and the generated file was moved to a path that can no longer reach the image. Re-author the template with LinkToFile = msoFalse and SaveWithDocument = msoTrue so the image is embedded inside the workbook and travels with the file.
The script returns "ActiveX component can't create object" (0x800A01AD). What bitness do I need?
Install the same bitness of Microsoft Office as the WinCC Flexible 2008 RT. A 32-bit RT requires 32-bit Office. Mixed bitness (64-bit Office, 32-bit RT) fails to register the class id and the CreateObject call returns error -2146827859.
Can I apply borders to a range without a template, directly from the script?
Yes. Use the Range.Borders collection with the constants xlEdgeTop, xlEdgeBottom, xlEdgeLeft, xlEdgeRight, xlInsideHorizontal, and xlInsideVertical, and set LineStyle = xlContinuous and Weight = xlThin or xlMedium. The reference table in section 7.1 lists every line style and the Microsoft Excel borders documentation covers the UI equivalents.
How do I prevent the template from being overwritten by a misbehaving script?
Open the template with Workbooks.Open(sTemplate, , True) so Excel opens it read-only, and set the filesystem permission on the .xlt to read-only for the RT service account. The script writes a new file via SaveAs, leaving the original template byte-identical (verifiable with SHA-256).
How many reports per minute can the WinCC Flexible 2008 SP2 RT generate this way?
Field measurements show 2.2 to 3.7 seconds per report including Excel cold start. The practical ceiling is roughly 15-20 reports per minute on a typical industrial PC. For higher rates, use a pooled Excel.Application instance (not recommended for long-running RT) or migrate to the WinCC Unified server-side reporting pipeline.