
1. 为什么工业监控离不开报表1.1 从一次“要报表”的现场经历说起我在不少工厂现场被问过同一个问题“你们WinCC能不能生成报表”问这话的可能是车间主任也可能是设备管理员甚至是财务的人。你要是直接说“能”对面多半马上补一句“就是那种我点一个按钮它自己把昨天产量、开机时间、报警次数统统给我列成一张表的。”我最早接触WinCC报表需求是在一条包装线项目上。当时客户要求每天夜班结束前班长能看到当班产量、设备运行时长、几条主要报警的发生次数最好还能打印出来签字归档。我刚看了下任务第一反应是WinCC里的报表功能没那么显眼正儿八经的报表输出能力不算强它是监控系统不是BI平台。但工业现场恰恰最缺的就是这件事——数据一直都在画面里跳可真要落到纸面上、变成一张能拿去开会的表就得把数据“捞”出来重新组织。这篇东西不是照着帮助文档抄出来的是我反复做、反复被现场问题“打脸”之后沉淀下来的做法。从变量归配置开始到三种主流实现方式再给一个能直接落地的定时自动报表案例最后把常见的坑列一份速查清单。适合谁看正在用WinCC做项目、被工厂提过报表需求的工程师刚接手老项目、发现历史数据压根没存下来的维护同行以及准备做MES对接、需要把WinCC数据往外送的集成人员。新手看完至少知道从哪里下手老手可以对照看看自己有没有踩过类似坑。1.2 报表到底“报”什么现场的报表需求远不止一张表搞清楚了需求再动手能省一半的时间。我在现场碰到的报表需求归纳下来无外乎这几类生产统计报表产量累计、班产量、日产量、合格率、原料消耗。这是最普遍的通常由班长或车间主任看。设备运行报表开机时间、停机时间、运行状态时长分布、故障停机次数。设备科和维修工程师最关心。报警报表报警发生时间、确认时间、恢复时间、报警次数统计。这是安全与质量追溯的刚需。能耗报表水、电、气、蒸汽的累积量与分时用量。现在工厂对能耗考核越来越细这个需求增长速度很快。交接班报表把当班期间的运行概况汇总成一张表供下一班快速了解状态。这几类报表的特点很明显都是“事后查看”型的数据输出不是实时监控画面。WinCC作为SCADA软件它的日常工作是实时反映过程状态而报表是把一段时间内积累的数据重新切片、汇总、呈现。所以你看做报表这件事核心不在于WinCC本身而在于你有没有把该记的数据记下来。这也是我想在第二章节先聊数据归档的原因——报表好不好做在数据配置那一刻就决定了。2. 先做数据底子变量归档配置才是报表的地基2.1 归档配置的三个基础动作很多工程师以为报表难在脚本和代码其实难在数据源。WinCC里的变量分为内部变量和外部变量外部变量连接PLC等控制器。如果这个变量没有开启归档那当前值永远只能“看一眼”历史数据什么都没有。好比监控摄像头没有接硬盘录像机画面实时能看到可出了事你想回放对不起没录。所以做报表前第一个动作就是检查变量有没有归档。打开WinCC项目浏览器里的“变量管理”选中某个外部变量右键打开属性在“归档”选项卡里勾选“记录”并设置归档周期和归档类型。这一步很多新手容易漏。第二件事是最小化数据噪声。如果你准备用一分钟的归档周期那变量采集周期就不需要每次都存可以设定一个较长的归档周期。我在一个项目里遇到过这样的配置客户把采集周期设为100毫秒归档周期也默认成了100毫秒结果一台设备一天就能产生几十万行数据系统越来越卡报表查询也慢得像蜗牛。后来把归档周期改成1分钟数据量骤降到原来的1%都不到报表功能才真正“活”了过来。第三件事是明确归档类型。WinCC的归档类型有“平均值”“瞬时值”“最大值”“最小值”“求和”等选项。做日报表的时候产量累计值用“瞬时值”来读最终值但如果是能耗分时统计用“求和”或“平均值”更合理。举个例子你用功率变量做归档想要电耗数据就该选“求和”因为这本质上是时间积分。如果不做这个选择后面报表里看到的数值可能只是采样瞬间的瞬时值和电表实际读数对不上。2.2 采集周期与归档周期怎么定这里说一个我常用的参考思路归档周期到底设多大取决于你想做什么报表。上一条包装线项目班长要看的是“每天总产量”“每小时产量”这种需求归档周期设1分钟完全够用。但如果现场有快速瞬变的过程量比如压力波动、温度波动做趋势分析时可能要求秒级甚至更快那归档周期就得相应缩短。这里牵涉到数据精度与存储容量的平衡没有绝对正确的值只有适合现场需求的值。补充一个细节归档压缩算法不要乱用。WinCC归档时会为每一个周期内的数据记录压缩值比如平均值、最小值、最大值、求和等。如果归档类型选成“瞬时值”它只记录每个归档周期开始瞬间的值某些变化快的信号可能会丢失关键峰值。所以如果需要做故障追责类分析建议同时勾选“平均值”和“最大值最小值”这对后面的趋势与报表都有好处。还有个容易踩的坑压缩后的归档表里数据的更新时间不是“真实事件时间”而是归档周期对应的间隔时间。比如一分钟归档几分钟前的故障尖峰报表上看到的时间可能是一个分钟内整点位置并非精确到秒。如果工厂要求精确到秒做追责就得在设计报表时明确告诉客户这个精度差异不然验收时会被打回来。2.3 数据类型和单位报表里最容易翻车的环节变量归档时WinCC会按变量的数据类型存储。INT、REAL、BOOL、WORD每个类型在数据库里占用空间不一样取值方式也不一样。报表脚本里如果用了错误的类型转换轻则取不到正确的数重则脚本报错。常见错误是BOOL型变量被当成REAL型读取结果报表上出现一堆1或者0以外的奇怪数。单位问题就更常见了。传感器采集到的原始值可能是0到1000的百分比物理量程却是0到100度。如果你在WinCC变量组态里已经做了线性缩放那归档里存的是工程单位换算后的数值报表直接往外用就行。但有一些老项目是在画面脚本里做缩放而归档存的是原始值这种项目你直接取归档数值做报表数据就会差一个斜率系数。碰到这类情况我一般会先确认PLC侧还是WinCC侧做了量程转换再决定报表里要不要二次换算。还要提醒一件事数据库里的归档表不能随意清理。WinCC后台是SQL Server很多人图省事直接用SQL工具删历史数据结果导致WinCC运行系统启动异常或报表模块报错。历史数据的清理应该用WinCC自带的存储管理工具按照周期策略处理千万别手截DELETE语句。3. 三种主流报表实现方式按现场条件选3.1 方式AWinCC自带的控制与导出功能WinCC的画面编辑器里提供了“在线表格控件”和“趋势控件”把它们拖到画面里绑定归档变量运行后就能显示历史数据。这个方式快、零代码适合临时看一下某时间段的数据也适合当成操作员站上的普通查询窗口。自带的导出功能可以把表格内容存成CSV或Excel格式很多现场就把这个当成简易报表。但这个方式的短板非常明显样式固化几乎没法按客户期望的格式输出比如合并单元格、列宽、表头、统计行这些它统统做不了。而且它是“手动操作型”报表没有人点击按钮它不会自己生成。所以这种方式我通常只用来做“在线历史查询”功能而不是真正的生产报表。3.2 方式BVBS脚本 Excel自动化这是我在绝大多数项目里的主力方案。原理不复杂WinCC的全局脚本或者画面脚本支持VBS可以通过脚本创建Excel.Application对象然后在Excel里写入数据、设置格式、做公式统计、保存成文件甚至通过邮件发送。这样做的好处是报表的格式完全自定义。你想怎么做表头、怎么设边框、怎么调字号Excel能做的WinCC脚本里都能做。而且可以做成完全自动化的定时触发不需要任何人工干预。对于交接班报表、日报表这类需求第二天早晨8点自动生成一张格式固定的表放到指定共享目录这个方案非常合适。实现方式上有个细节数据读取一般有两种路径。第一种是直接在WinCC运行时内部通过脚本读取变量当前值、读取归档查询对象即WinCC自带的“归档数据查询”API这种方式和项目耦合度高必须在WinCC运行环境中跑第二种是通过WinCC OLEDB Provider或者直接连SQL Server查归档表把查询结果导入Excel这种方式更稳定查询历史数据也更容易。第二种方式我实际用得更多因为它可以把历史数据查询的复杂度放到SQL语句里脚本只负责“取结果、写表格”。比如想统计某天每个小时的产量直接对归档表做GROUP BY就可以脚本逻辑简单得多。后面第四节的实战案例就是按这个思路写的。3.3 方式C数据库 专业报表工具或开源BI如果报表需求已经上升到“统计分析和多维度展示”比如同时要看三个车间、十几条产线的产量对比或者要和MES、ERP系统做数据对接那WinCC脚本和Excel组合就显得吃力了。这时候推荐直接访问WinCC归档数据库用专业报表工具来做数据可视化与汇总。常见做法是把WinCC后台SQL Server里的归档数据通过视图或定时同步外推到独立报表数据库再用帆软报表、Power BI或者开源图表库做展示。工业和互联网圈的报表工具非常多找一个支持数据源连接、能做参数查询、能定时刷新的即可。这个方案的好处是性能好、可扩展、能做复杂的统计分析代价是需要单独部署一套报表服务和数据同步机制开发和维护成本更高。另外一个不能忽略的点直接用第三方工具连WinCC归档库是有一定风险的因为WinCC的归档库表结构属于系统内部实现官方不保证兼容性。更稳妥的方式是使用WinCC提供的OLEDB Provider连接字符串形如ProviderWinCCOLEDBProvider.1;...或者通过WinCC的“数据导出/外部数据接口”把数据同步到外部库再做分析。安全第一别把生产系统的数据库搞出问题。3.4 三种方式对比实现方式开发难度报表格式自动化能力适用场景在线控件导出低固定手动临时查数、趋势浏览VBSExcel中高度自定义支持定时触发日报/月报/交接班报表数据库报表工具高灵活可做BI支持定时与交互多维度统计、MES/ERP对接我在实际选型时的经验法则是需求简单、要得快选方式A格式要求明确、要自动生成选方式B数据量大、统计维度多、要对接上层系统选方式C。很多项目往往是B和C混着用日常生产报表用B月度经营分析用C。4. 实战自动生成“昨日生产日报表”并导出Excel4.1 需求定义把模糊的“要报表”变成清晰功能表假设这样一个场景客户提出“每天早上一上班我要看到昨天每个班次的产量、设备运行时间和报警次数最好自动生成Excel表格放到共享文件夹里”。我拿到这类需求后一般先写成下面几条具体指标再动工统计周期昨日00:00:00到23:59:59。统计对象3台设备的产量累计变量、运行状态变量、一个报警汇总变量。输出格式Excel表格第一行是标题第二行是日期第三行开始按设备列行最后一行有合计。触发方式每天01:00自动运行生成文件名为“生产日报_YYYYMMDD.xlsx”。存放位置服务器D盘指定共享目录。把需求落到这个颗粒度之后后面开发和验收都会顺畅很多。很多报表项目拖垮在模糊需求上就是因为客户一开始只说“要个表”等到你交了货他又说格式不对、缺了哪个字段反复改。所以做报表第一个技巧就是“先定义再开发”。4.2 用VBS读取归档数据并写入Excel这一节是核心。我给出一个思路完整、可直接改写的VBS脚本框架。先说下数据获取的逻辑由于WinCC归档数据表名和项目相关具体表名需要通过查询确认常见的历史归档表名形如PV_1、PV_2等对应你在变量归档中分配的表ID。更稳妥的做法是在WinCC自带的“OLAP”或者数据库连接测试界面里确认表名也可以在WinCC项目数据库中查看。生产部署前一定要把表名核对清楚别直接照搬网上的脚本。准备一份查询昨日产量累计值的SQL思路SELECT TagName, Value, ValueTime FROM PV_1 WHERE TagName Line1_TotalCount AND ValueTime BETWEEN 2024-01-01 00:00:00 AND 2024-01-01 23:59:59 ORDER BY ValueTime有了查询结果之后VBS脚本要做的事情就是连接数据库、执行查询、把结果写入Excel。下面是一段我在项目里实际使用过的脚本框架手动调整过变量名和文件路径Option Explicit Dim conn, rs, xlApp, xlBook, xlSheet Dim strConn, strSQL, strExcelPath Dim iRow, strDate 昨天日期字符 strDate DateAdd(d, -1, Date()) strDate Year(strDate) - Right(0 Month(strDate), 2) - Right(0 Day(strDate), 2) 连接WinCC归档数据库这里以SQL Server方式为例 strConn ProviderSQLOLEDB;Data Sourcelocalhost;Initial CatalogWinCCProjectDB;User IDsa;Password******; Set conn CreateObject(ADODB.Connection) conn.Open strConn 查询昨日归档数据注意表名需据项目核实 strSQL SELECT TagName, Value, ValueTime FROM PV_1 _ WHERE ValueTime strDate 00:00:00 _ AND ValueTime strDate 23:59:59 _ ORDER BY ValueTime Set rs CreateObject(ADODB.Recordset) rs.Open strSQL, conn, 1, 1 创建Excel对象 Set xlApp CreateObject(Excel.Application) xlApp.Visible False Set xlBook xlApp.Workbooks.Add Set xlSheet xlBook.Worksheets(1) 写表头 xlSheet.Cells(1,1) 设备名称 xlSheet.Cells(1,2) 时间 xlSheet.Cells(1,3) 产量 写数据 iRow 2 Do While Not rs.EOF xlSheet.Cells(iRow,1) rs.Fields(TagName).Value xlSheet.Cells(iRow,2) rs.Fields(ValueTime).Value xlSheet.Cells(iRow,3) rs.Fields(Value).Value iRow iRow 1 rs.MoveNext Loop 保存文件 strExcelPath D:\Report\生产日报_ Replace(strDate, -, ) .xlsx xlBook.SaveAs strExcelPath, 51 51表示xlsx格式 清理对象 rs.Close conn.Close Set rs Nothing Set conn Nothing xlBook.Close False xlApp.Quit Set xlSheet Nothing Set xlBook Nothing Set xlApp Nothing MsgBox 报表已生成 strExcelPath这个脚本实际执行前要特别留意几件事Excel对象如果创建失败八成是服务器上没有安装Excel或者DCOM权限没配好文件保存路径如果目录不存在SaveAs会报错查询结果为空也要先判断一下别让Excel生成一张只有表头没数据的空表。4.3 定时自动触发让报表不依赖人工点击脚本写好了怎么让它每天自动跑WinCC全局脚本里有定时触发器。打开全局脚本编辑器的“触发器管理”新建一个触发器触发方式选“定时器”设置每天01:00触发一次再把上述脚本挂到这个触发器下面即可。说起来简单实际现场有好多隐含条件。WinCC服务器本身必须开机而且运行系统得处于激活状态脚本才能按触发条件执行。如果服务器设置了自动睡眠或者有人手动关闭了运行系统定时脚本是跑不起来的。所以在实施时我会在服务器上写一个计划任务作为“双保险”每天早上8点检查一下报表文件是否生成没生成就发一个告警消息到微信群或者短信平台——工业项目里“没数据”和“数据错了”一样要命宁可让机器多说一句话也别让车间主任来问你。还有一个容易被忽略的问题运行系统的脚本执行需要登录用户权限。如果WinCC运行系统以服务方式运行脚本里创建Excel等COM对象时使用的是服务账户的权限通常没有Excel许可就会失败。我的做法是把WinCC和Excel都放在同一个具备本地桌面权限的登录会话里运行这也是工业项目里很多自动化报表的基本前提。4.4 给报表加一个“手动查询”入口定时自动报表解决的是“定期要数”的问题可现场经常有人问“能不能把上个月的报表也导出来看看”。我建议除了自动任务再做一个画面按钮绑定一段手动触发脚本让操作员可以选择起始时间和结束时间生成自定义时间段的报表。实现上可以在WinCC画面里放几个“输入输出域”绑定到内部变量比如StartTime、EndTime操作员填好时间段后点击按钮按钮的VBS事件里读取这两个内部变量的值替换SQL语句里的时间条件再执行和自动报表类似的导出逻辑。这个做法的好处是复用同一段核心代码减少重复开发。编码时记住一个原则把查询和导出做成一个子过程自动任务和手动按钮都调用它。这样以后要改报表格式只改一处不用同时改两边。5. 报表实战中绕不开的故障与排查速查表5.1 报表全都是0或者一片空白这个问题我碰到过太多次了。第一先查归档配置第二个查通讯状态第三个查脚本的时间条件。归档没开启是最容易发生的。有些变量你看画面里值有变化以为存下来了其实变量属性里“记录”根本没打勾。排查方法很简单在WinCC运行系统的“变量归档”模块里打开归档数据视图查一下目标时间段有没有数据。如果没有说明数据源就有问题后面脚本写得再好也是白搭。还有一种情况是通讯问题。WinCC和PLC之间连接异常时变量值不变或者变成0归档下来的自然全是0。这时WinCC的诊断里会报通讯握手失败或连接中断需要先恢复通讯连接再谈报表。我遇到过一次现场把PLC网线误拔导致当日报表全部为0后来在报表逻辑里加了一个“通讯状态判断”如果变量质量代码为0就把对应数据标记为异常免得报表看着正常却是错数。5.2 查询时间范围正确但Excel里数据缺失或偏移做一个项目时遇到过明明选了昨天的时间段导出的数据却少了最后几分钟或者出现了一些“看似整点整分”却不是真实事件时间的数据。原因多半出在时间格式和数据库查询条件上。SQL查询时间范围时最好带上毫秒或者使用数据库的ISODATE格式避免边界条件漏数据。比如19:00:00这个时刻很多系统存储的是19:00:00.000如果你只写到“19:00:00”在某些OLEDB访问场景下没问题但在有些连接字符串下就会被截断或者格式不识别。我在时间字符串拼接时统一使用“yyyy-mm-dd hh:mm:ss.000”标准格式省掉很多麻烦。还有一个和时区相关的小坑WinCC服务器的本地时间和PLC的系统时间不一定一致。如果PLC和上位机之间时间不同步归档数据里记录的是WinCC服务器接收时打上的时间戳而不是PLC侧真正发生事件的时间。所以现场实施时第一件事就是把上位机、PLC、HMI的时间源统一否则报表上和报警记录里的时间会对不上客户第一时间就会质疑报表的正确性。5.3 WinCC“握手错误”与报表数据缺失的关系热搜词里频繁出现“WinCC 握手错误”这部分值得单独说一下。“握手错误”一般出现于WinCC通信连接建立失败的场景。例如使用S7协议族连接时WinCC作为客户端与PLC建立TCP连接如果PLC的IP地址配置错误、子网掩码不对、访问点没指对、或者PLC侧没有开放对应连接资源通信握手就会失败。现场表现往往是变量状态变灰、值不更新、诊断里报连接故障。这和报表有什么关系关系很大。报表的数据源说到底就是这些变量。通信都握不上手归档必然缺了一段数据哪怕后期脚本再聪明也补不回来。所以我在项目调试阶段就会要求客户先把所有通信连接的状态做成一个画面汇总绿、黄、红三色显示每天检查一次。一旦报表发现数据空白先看这个汇总页凡是红黄的连接那段数据缺失都是可以解释的。排查握手上问题的思路我一般按照网络通不通PING→ 访问点对不对设置PG/PC接口→ PLC连接资源够不够S7 CPU属性里连接数→ WinCC变量连接配置有没有错逻辑设备名、插槽号、机架号这条流程走。最常见的原因是访问点或者插槽号搞错细心检查一遍基本都能定位。5.4 报表导出Excel慢、服务器卡顿定时报表脚本跑起来后CPU占用不高但Excel导出经常要卡几十秒甚至几分钟尤其在数据库表数据量很大的时候。原因基本出在查询和写入的方式上。Excel写入的瓶颈通常是逐行Cells赋值。如果你查询出几千行数据用循环一行一行的写速度会非常慢。优化办法是把查询结果一次性读入数组然后用Excel的Range对象一次性赋值速度能提升一个数量级。我在数据量大的情况下会把脚本改成Dim arrData arrData rs.GetRows() xlSheet.Range(xlSheet.Cells(2,1), xlSheet.Cells(2 UBound(arrData,2), 3)).Value Application.Transpose(arrData)另外数据库查询要尽量在SQL里完成汇总比如用SUM、AVG、COUNT、GROUP BY别把几万条原始记录全拉到Excel里再算。报表要的是“结论”而非“过程数据”在数据库侧算好再导出速度快得多也更容易保证统计口径一致。5.5 其他几个高频现场问题现象可能原因处理方法打开WinCC工程无显示项目缓存异常、授权文件缺失、分辨率或显卡兼容问题先检查项目复制路径和授权尝试重置视图缓存脚本定时没执行运行系统没激活、触发器没绑定、服务登录会话无权限检查运行系统状态、触发器和用互登录会话Excel文件被锁定上一天报表文件没关、杀毒软件占用脚本里先关闭同路径文件检查杀毒白名单报表中文字符乱码Excel导入或写入字符集不匹配常见于CSV统一使用UTF-8或GBKExcel中用文本导入指定编码归档数据量膨胀过快归档周期太短、保留策略没配调整归档周期设置压缩与清理策略6. 一点真实的使用体会做WinCC报表这些年我最大的感受是报表本身不是一个独立功能它是数据链条的最后一环。前面的变量定义、归档周期、通讯质量、时间同步哪一个环节松懈了报表都会给你颜色看。很多工程师一上来就研究脚本怎么写、Excel格式怎么调却忽略了数据源的有无与准确度结果折腾半天做出来的报表根本没人敢用。如果让我给刚入手的同事一个排序建议我会说先花三天把归档配好再花一天写脚本最后留半天测故障场景。不要把时间全花在争奇斗艳的表格样式上工厂里真正有用的报表永远是“数据可靠、逻辑清晰、按时送达”这一条。最后分享一个小技巧在报表文件名里加入“年月日班次”字段生成后不要覆盖旧文件保留至少一个月的历史版本。这样万一哪天对账的时候发现数据有异常还能回头查究竟是报表脚本有问题还是某个时间段的归档数据本身就缺了。这个习惯救过我很多次也希望它能在你的项目里少几次无谓的扯皮。