ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

WinCC报表控件实战:从选型到VBS导出与排查指南

WinCC报表控件实战:从选型到VBS导出与排查指南 简介WinCC报表控件是西门子公司为WinCC V7.x与博途WinCC环境打造的专业报表生成工具面向自动化工程师、PLC调试人员及工业数据管理人员用于快速创建实时/历史数据可视化报表无需编写复杂脚本即可生成曲线图、饼图、仪表盘等图表适用于生产监控、性能分析与异常诊断等场景。压缩包共15个文件包含可执行程序、DLL运行库、PDF使用手册、MP4入门录屏、XML/INI配置以及界面PNG素材等整体约10.94MB程序主体与配套说明完整齐备。已有6747人学习下载。借助这套资料用户可获得可直接运行的报表程序、依赖库、手册和录屏按步骤完成安装配置。结合示例可掌握动态数据绑定、定时触发、报警集成与权限管理等进阶用法并快速搭建符合自身需求的报表模板大幅缩短开发周期尤其适合需要提升报表制作效率、降低脚本开发成本的工控从业者。1. WinCC报表控件班报不是画面上多一张表而是数据能不能按时出去凌晨交班前半小时操作员打开 WinCC 报表控件把当班产量、温度、设备运行时间拉出来做成一张班报发给下一个班贴在交接班记录本上。这个画面里看起来不起眼的表格真正跑起来之后往往比很多控制逻辑更折磨人不是显示不出来就是时间对不上再要么导出的 Excel 打不开。这里要聊的 WinCC 报表控件不是某一种固定控件而是围绕 WinCC 数据展示、导出、打印的一整套落地路径。适合正在做产线数据交接、设备 OEE 统计、能耗报表或者被甲方一句“加个报表功能”砸中的组态工程师。读完你能分清方案、跑通脚本并提前知道坑在哪儿。2. 先分清报表控件的三条路线选型看的是数据量、格式要求和维护成本很多项目做到一半才来问“WinCC 报表怎么做”本质上是因为“报表”这个词在 WinCC 里被三种完全不同的做法共用。选错路线后面所有工作都在给选型还债。我对项目的第一步永远是先问三个问题数据会不会被二次加工打印格式是固定还是经常变数据量是几百条还是几十万条这三个问题的答案决定了你该用哪条路。2.1 自带报表工具、VBSExcel、数据库集中报表边界在哪里第一条路线是 WinCC 自带的报表能力日常最常见的就是运行画面里的在线表格控件Online Table Control。它直接读变量归档在画面上按时间范围显示数据配合画面打印输出纸质报表。这条路适合班报、日报、报警记录这类格式固定、数据量中等、不需要二次计算的场景。优点是随 WinCC 自带不依赖 Office稳定缺点是样式调整能力弱表格稍微复杂一点合并单元格、跨页表头、自定义公式就非常吃力而且打印效果基本就是屏幕截图级别。第二条路线是 VBS 脚本加 Excel 对象。WinCC 的全局脚本和画面按钮事件里都可以写 VBS用 CreateObject 创建 Excel 应用把变量值写入单元格再按日期生成文件。这是国内现场用得最多的“野路子”因为 Excel 人人会用交接方便格式想怎么调就怎么调。代价是它依赖 Office 环境Excel 进程残留、版本兼容、中文编码都是坑后面专门讲。第三条路线是把数据落到外部数据库再用专业报表工具做。适合几十台站、数据要跨系统共享、要做趋势分析和多维度统计的场景。这条路最重需要额外部署数据库服务和报表服务一般项目用不上但如果你已经建了数据中心报表控件和脚本反而成了过渡方案。三条路线的取舍我常用下面这张表来定不纠结。方向适用场景优势主要代价自带表格控件单机画面查看、固定格式打印稳定、不依赖 Office、和归档直接打通样式能力弱、大数据量卡顿、分页控制差VBS Excel交接班报表、二次加工、格式灵活可完全自定义、Excel 可再用、上手快依赖 Office、进程残留、编码坑多数据库 外部报表多站集中、历史分析、跨系统承载量大、共享方便、图表丰富部署重、需要额外开发维护2.2 报表的数据地基变量归档先跑起来控件才有东西可画不管选哪条路线报表控件本质上只负责“读”不负责“存”。它读的是 WinCC 的变量归档Tag Logging数据。很多新手在画面上拖一个报表控件选了一个变量发现表格是空的第一反应是控件坏了实际上变量根本没有加入归档组。归档没写入报表就是无源之水这是报表问题里最大的一类根因。在变量管理里每个测点可以设置是否归档、归档类型和归档周期。班报、日报一般用平均值归档就够了不需要秒钟级的数据故障分析才需要快速归档。我一般会在项目初期就把归档项和周期定下来因为报表控件的粒度上限就是归档的粒度——控件查不到比归档周期更细的数据这是硬边界。另外归档段的存储空间和滚动策略也要提前看归档写满或者磁盘满报表会自动缺数据而且这种缺不是报错是静默的最坑。注意报表控件显示的是归档数据不是实时数据。如果你在画面里选了一个从未归档的变量控件会一直空白。3. 用 WinCC 自带报表工具搭一张班报布局、数据源和打印三步走确定了用自带报表控件之后真正搭一张能用的班报核心就三件事把报表画面搭出来、把数据源和时间范围对好、把打印输出调顺。这三步做完一张中规中矩的班报就能交差。下面按我惯用的顺序走一遍。3.1 新建报表画面从控件库拖出在线表格控件并固定表头常见做法是在图形编辑器里新建一张专门放报表的画面和主操作画面分开。不要把报表直接堆在主画面上因为报表控件加载时比较重放在主画面会影响整个画面的打开速度。新建画面后从控件栏里找到在线表格控件不同版本里名字可能叫 Online Table Control 或 WinCC Online Table Control拖到画面中间拉出一个足够大的显示区域。接着处理表头。在线表格控件本身有“标题行”属性可以在属性配置里填表头文字比如“XX 线 1 号班次产量报表”以及报表的生成时间、班次号。固定表头的好处是打印的时候每页都能带上标题比在画面上用静态文本拼表头可靠得多。然后调整列。控件默认会显示“变量名、值、时间”这些列在属性里可以配置显示哪些列、列的顺序、列宽以及时间格式。我习惯把时间格式显式配置为“YYYY-MM-DD HH:MM:SS”不要用默认格式否则后面打印和导出时容易变成一串数字。这一步看着琐碎但值得一次调对。3.2 绑定变量归档与时间范围让报表跟着交班时间走控件拖好后进入数据源配置。大部分版本的在线表格控件都支持选择“变量归档”作为数据源然后在归档变量列表里把要显示的测点勾选进来。这里注意勾选的是归档变量不是画面变量。两者名字可能一样但归档变量多了一层“已归档”的属性如果列表里找不到说明这个变量没建归档。时间范围是报表的灵魂。班报要显示“上一个班次的数据”而不是固定写死一个时间段所以我会创建两个内部变量比如 StartTime 和 EndTime在控件的开始时间和结束时间属性里分别关联它们。然后由班次切换脚本在交班时把 StartTime 更新为上一个班的开始点、EndTime 更新为当前时间点。这样操作员任何时候打开报表看到都是最近一个班次的完整数据不需要手动改时间。控件属性里还有一个刷新周期。报表画面不会自己实时刷新需要给控件一个合理的刷新周期比如 300 秒一次或者在画面加一个“刷新”按钮让操作员手动拉取最新数据。手动刷新比自动刷新更可控因为自动刷新如果赶上控件正在渲染大数据量画面会明显卡顿。我的习惯是自动刷新放后台按钮刷新做前台。3.3 打印输出横向布局、按页打印表头和边距处理数据在屏幕上能看了接下来是打印。常见做法是在报表画面上放一个“打印报表”按钮按钮事件里调用画面打印函数不同版本函数名略有差异通常是 PrintPicture 一类。打印前先在打印设置里把纸张方向改成横向因为多列数据在纵向 A4 上一定放不下竖着打印出来的报表字小到没法看。页边距也要单独调。报表打印不同于普通画面打印表格边缘容易被裁掉所以页边距按纸张实际宽度设小一些比如左右 10mm 左右同时把控件放在画面中央偏左的区域给右边缘留出打印机的物理不可打印区。还有一点如果班报数据行数超过一页自带控件打印时不会像 Excel 那样自动重复表头这是它的先天局限。遇到多页报表我通常直接把数据源切到 Excel 导出方案不自找麻烦。4. 用 VBS 把 WinCC 数据导成 Excel轻量报表方案的完整脚本自带控件适合“看一眼、打一页”但只要涉及交班记录归档、班组长二次编辑、Excel 模板汇总VBS 加 Excel 就是绕不开的方案。它的核心思路很简单VBS 脚本读 WinCC 变量写入 Excel 单元格按时间戳存成文件。下面这段脚本是我在项目里最常用的最小骨架你可以直接照着改变量清单和路径。4.1 最小可用脚本读变量、写表头、循环填数、存盘Dim objExcel, objBook, objSheet, i, row Dim arrTags(4), tagName, tagValue 需要输出的变量清单按报表列顺序排列 arrTags(0) Line1_Speed arrTags(1) Line1_Temp arrTags(2) Line2_Speed arrTags(3) Line2_Pressure arrTags(4) Line3_Output Set objExcel CreateObject(Excel.Application) objExcel.Visible False objExcel.DisplayAlerts False Set objBook objExcel.Workbooks.Add() Set objSheet objBook.Worksheets(1) 固定表头第一行留给标题第二行开始写数据 objSheet.Cells(1, 1).Value 变量名 objSheet.Cells(1, 2).Value 数值 objSheet.Cells(1, 3).Value 记录时间 objSheet.Cells(1, 1).Font.Bold True objSheet.Cells(1, 2).Font.Bold True objSheet.Cells(1, 3).Font.Bold True row 2 For i 0 To 4 tagName arrTags(i) HMIRuntime.Tags(xx).Read 读的是当前值 tagValue HMIRuntime.Tags(tagName).Read objSheet.Cells(row, 1).Value tagName objSheet.Cells(row, 2).Value CDbl(tagValue) objSheet.Cells(row, 3).Value Now() row row 1 Next 生成带日期的文件名保存到共享报表目录 Dim strFile strFile D:\Reports\Shift_ Year(Now()) _ Right(0 Month(Now()), 2) _ Right(0 Day(Now()), 2) .xls objBook.SaveAs strFile, 56 objBook.Close False objExcel.Quit Set objSheet Nothing Set objBook Nothing Set objExcel Nothing这段脚本的逻辑分四段准备变量清单、创建 Excel 对象、循环写数据、保存关闭。arrTags 数组就是要输出的变量清单以后加测点只需要改这一处用数组而不是逐个写死是为了让循环结构固定报表扩展时不容易漏行。参数说明部分有三处需要重点解释。第一HMIRuntime.Tags(tagName).Read读的是当前实时值如果要做历史班报就要把这一步替换成查询归档数据或者让控件先把数据显示出来再导出不要指望这段简单脚本直接拉历史库。第二CDbl(tagValue)很关键Read 返回的值有时候是字符串直接写入 Excel 会导致单元格变成文本格式后面没法求和所以先转成数值。第三SaveAs strFile, 56里的 56 表示 xls 格式如果想存 xlsx可以改成 51但要注意现场 Office 版本是否支持老版本 Office 打不开高版本格式。4.2 定时触发与班次文件命名把脚本从按钮搬到自动任务脚本写完只是第一步。实际项目中没人愿意每天手动按按钮导出所以要把脚本挂到 WinCC 的全局脚本里用触发器自动运行。常见做法是在全局脚本的“动作”里新建一个 VBS 动作把上面这段代码拷进去然后给这个动作设置周期触发器比如每分钟执行一次在动作开头判断当前时间是否落在交接班窗口。判断窗口的写法很简单用 Hour(Now()) 配合班次定义。比如白班是 8 点到 20 点夜班是 20 点到次日 8 点那么在每天 7:50 和 19:50 生成上一班的报表文件Dim nowHour nowHour Hour(Now()) If (nowHour 7 And Minute(Now()) 50) Or _ (nowHour 19 And Minute(Now()) 50) Then 到达交班窗口执行导出动作 Call ExportShiftReport() End If文件命名上我强烈建议文件名里带班次信息只带日期会覆盖上一个班次的报表。把班次拼进文件名比如Shift_Night_20260512.xls和Shift_Day_20260512.xls这样每天的报表能完整留档月底汇总时也方便按文件名排序。4.3 VBS方案的边界哪些报表别硬写脚本VBS 加 Excel 看起来很万能但它有明确边界。数据量一旦上来这条路就走不通了。比如要做 50 个变量、一个月的数据量导出VBS 循环逐行写 Excel脚本可能要跑几分钟期间 WinCC 画面卡顿操作员会以为系统死机了。再比如多台 WinCC 站同时生成报表每站都去操作同一个 Excel 文件文件锁冲突会频繁出现。我一般这样判断报表文件小于几百行、格式要灵活、用户要在 Excel 里继续编辑用 VBS报表数据量大、要长期存储、要跨系统共享应该考虑数据库加报表工具不要把 Excel 当数据库用。还有一种折中做法是让 VBS 只负责导出 CSV 文件CSV 轻量、不依赖 Excel COM 对象、写入速度快后续用 Excel 打开另存为正式格式即可。如果现场只是要“能导出来看”CSV 比 xls 省心得多。5. WinCC 报表控件的常见坑与排查从空白数据到格式错位报表相关的问题有个特点不报硬错误全是软故障。画面上不红不弹窗但数据就是不对。下面这五类坑是我在不同项目里反复撞过的按现象、原因、解决的顺序写清楚排查时可以直接对照。5.1 报表一片空先查归档接口而不是控件现象报表画面能打开时间范围也设置了但表格里一条数据都没有刷新也没用。原因最常见的是变量根本没加入归档组。控件从归档里查询数据如果变量管理里没有勾选归档或者归档组的存储周期没有启动控件什么都查不到。其次是时间范围写反了开始时间大于结束时间查询结果为空。还有一种是归档服务没运行WinCC 的变量归档服务和画面运行是独立的画面正常不代表归档在写入。解决先不要动控件打开变量管理确认报表用到的变量都在归档组里并且归档状态是“运行”。然后打开在线表格控件的数据源配置重新选择归档变量看列表里能不能找到目标变量。最后用时间范围属性做一个简单测试把开始时间设为当前时间减 5 分钟结束时间设为当前时间如果这样还是没有数据问题就在归档侧和控件无关。5.2 时间变成日期序号区域设置和单元格格式的双重陷阱现象报表里的时间列显示成 45123.78432 这样的数字或者显示成“2026-05-12”但排序完全乱掉年份和月份错位。原因Excel 内部的时间本质上是序列值当 WinCC 返回的时间被识别成字符串后又按文本处理单元格格式不对就会露出原始序列值。另一个常见原因是一台机器的 Windows 区域设置是中文另一台是英文WinCC 按系统区域解析时间字符串导出的内容就会在不同机器上表现不一致。解决在写入时间时不要直接用Now()塞进单元格而是先用FormatDateTime(Now(), 0)转成固定格式字符串再把该列的单元格格式显式设置为“日期”而不是“常规”。同时所有操作 WinCC 和 Excel 的机器保持区域设置一致避免日期解析在不同客户端上出现小时偏差。报表如果涉及跨时区要提前想清楚用的是现场时间还是服务器时间不要混用。5.3 导出报“文件被占用”EXCEL.EXE 残留进程的清理顺序现象脚本第一次运行正常第二次运行提示“文件被占用”或“无法访问”有时候 Excel 文件在资源管理器里显示为 0KB。原因脚本异常退出时Excel 的 COM 对象没有正常释放EXCEL.EXE 进程残留在后台锁住了刚才打开的文件。WinCC 的 VBS 脚本环境里如果脚本中途报错跳过了 Quit进程就永远留在那里。共享目录下的报表文件一旦被残留进程锁住其他站点的脚本也会跟着失败。解决不要一上来就杀所有 Excel 进程那会把操作员正在编辑的表格也关掉。正确顺序是在脚本开头设置On Error Resume Next正常执行到最后Quit并置空对象如果确实碰到文件被占用先确认为残留进程再单独结束对应进程或者用taskkill /f /im excel.exe清掉全部残留然后重新导出。更稳的做法是把报表生成目录固定定期清理历史文件减少同名文件冲突的概率。5.4 控件打开卡死时间范围太大别让控件一上来就全表渲染现象报表画面打开速度非常慢鼠标在控件区域一直转圈有时候直接白屏要等一两分钟才恢复。原因在线表格控件默认会自动加载数据源里设置的完整时间范围。如果把开始时间设成很远的日期比如“本月 1 日”控件会一次性把这段时间内的所有归档记录读进内存并逐行渲染。变量多、时间跨度大时渲染几百行到几千行性能急剧下降。解决把控件默认时间范围改成“最近一个班次”或“最近 1 小时”大范围查询交给按钮触发而不是打开画面就查。控件属性里如果有“最大显示行数”限制把它设成一个合理上限比如 500 行超过部分提示用户缩小时间范围。另外一个做法是把报表控件放到独立子画面操作员需要时才打开不要堆在主操作画面里。5.5 中文乱码和列宽错位模板与字体设置的三个检查点现象导出到 Excel 后中文变量名变成乱码列宽挤成一团有的列被截断打印出来的报表标题重叠。原因脚本创建的是空白工作簿默认字体不支持中文或者写数据时没有设置列宽Excel 使用默认宽度导致中文字符显示不全。另外如果变量名里带特殊符号VBS 写入时被当作公式解析也会出现显示异常。解决三个检查点依次过一遍。第一在脚本里把单元格区域的字体统一设置为“宋体”或“微软雅黑”字符集选默认即可。第二写入值之前把列宽显式设置一下比如objSheet.Columns(1).ColumnWidth 20不要依赖自动宽度自动宽度在有合并单元格或表头复杂时经常会失灵。第三变量名写入前做一次安全处理把开头的等号、引号、斜杠替换掉避免被 Excel 当成公式执行。6. 把 WinCC 报表控件再往前推一步模板复用与数据交接报表控件单独能跑通不难真正拉开差距的是后续的维护成本和数据可信度。这里分享两个进阶做法以及我判断一个报表方案值不值得继续投入的标准。6.1 用统一 Excel 模板管住全厂报表样式把第 4 章的脚本从“新建工作簿”改成“打开模板文件”是让报表规范化最有效的一步。提前做一个ShiftReport.xltx模板表头、列宽、边框、公式、打印区域全部在模板里设好脚本只负责往指定单元格填数据然后另存为带日期的正式文件。这样改一处模板全厂的报表样式同步变不用再去脚本里改列宽和字体。模板文件不要放在共享目录让所有人编辑权限放开后总有人往里面加签名、加备注最后格式就乱了。6.2 报表数据交接时的核对技巧交接班最怕的不是报表生成失败而是数据对不上。我在项目里给自己定了一条规矩任何自动生成的报表都要在文件里留下数据来源和时间戳信息。具体做法是在模板固定位置写上报表生成时间、生成脚本版本号、数据对应的班次时间范围。拿到报表的人第一时间能看出这份数据是哪个时间段的和交接班记录本一对就知道有没有缺口。验证报表是否准确的技巧也很简单抽三到五个关键变量打开 WinCC 在线监视画面对比当前值和报表里最后一个点的数值误差应该在合理范围内。历史数据则用 WinCC 自带的在线表格控件查询同一时间段和 Excel 导出的结果核对如果两边不一致优先怀疑归档写入有断档而不是脚本算错。6.3 一个判断标准和一个个人习惯要不要在报表控件这条路上继续加投入我的判断标准看两点数据量是否还在几百行的量级格式要求是否能用一张模板固定下来。满足这两点WinCC 自带控件加 VBS 导出完全够用一旦超出迁移到数据库报表是更省时间的决定别在脚本里用循环硬扛大数据量。个人习惯上我每写一个报表脚本都会在脚本最前面留下注释这个报表给谁用、变量清单从哪里维护、缺哪个变量会有什么表现。半年后脚本出错看注释五分钟就能定位不用把整段代码重读一遍。报表这类功能往往是在项目收尾时才被重视前期欠下的归档配置和时间格式债务到交工时都会加倍还回来。希望我的这些记录能帮你在做 WinCC 报表时少走一段我走过的弯路希望帮到你。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进