1. 别急着拖控件,WinCC报表的几条路线你得先选明白
1.1 一个夜班报表引发的“血案”
做WinCC项目的工程师基本都经历过这个场景:设备调试完了、联机也正常了,甲方突然提需求——“我们要个夜班报表,晚上12点到早上8点的温度、压力、流量平均值,还要能自动打印”。
很多人的第一反应是:WinCC不是自带报表控件吗?拖个控件上去不就行了?真这么干的人,十有八九会在调试末期被报表磨掉一层皮。原因很简单:WinCC的“报表控件”从来不是一个万能组件,它是由在线表格控件、在线趋势控件、归档数据库查询、脚本导出等多条技术路线组成的组合拳,不同需求得走不同路。
我做了十几个WinCC项目,从化工到水处理都碰过,现在总结下来就一句话:选型比配置重要。选对了路线,报表功能半天搞定;选错了,后面全是补丁。
1.2 三条路线,分别解决什么问题
先说结论,WinCC项目里的报表需求基本可以分成三大类,对应三种不同做法:
| 需求类型 | 典型场景 | 推荐方案 | 复杂程度 |
|---|---|---|---|
| 现场快速查看历史数据 | 设备运行状态回看、单个变量查值 | WinCC在线表格控件 | 低 |
| 趋势分析、曲线对比 | 工艺参数波动分析、多变量对比 | WinCC在线趋势控件 + 脚本 | 中 |
| 正式生产报表、交接班报表 | 需要按班次统计、导出Excel、定时打印 | SQL查询 + VBS脚本导出 | 高 |
这里面的逻辑很直白:表格控件和趋势控件是用来“看”的,真正的报表是用来“交”的。如果只是操作员在画面上翻一翻历史数据,用在线表格控件就够了;但如果要给车间主任、生产调度发一份格式固定的Excel报表,你就必须走数据库查询加脚本导出的路线。
1.3 为什么很多人一上来就卡在“控件用不了”
我在现场被问得最多的问题是:为什么表格控件拖上去,里面什么都没有?
十有八九是因为变量没有归档。WinCC报表控件不读实时值,它读的是历史归档数据。你必须在WinCC变量管理里面把需要做报表的变量勾选上“记录”属性,给这些变量分配归档周期,数据才会进入历史数据库。控件本身只负责把历史库里的数据捞出来显示,你不存数据,它当然什么都显示不出来。
所以,做报表的第一步其实是做归档规划:哪些变量需要记录、记录频率是多少、保留多久、是否需要压缩。这一步不做,后面所有报表都是空中楼阁。
2. 在线表格控件:从拖控件到真正出数据,中间差了这几步
2.1 一个能查出历史值的表格控件是怎么配出来的
以WinCC V7.x为例(TIA Portal里的WinCC Professional逻辑类似),操作路径大概是这样的:
- 在图形设计器里打开目标画面,从对象选项板的“控件”分类里找到“WinCC Online Table Control”,拖到画面上。
- 右键控件,在组态对话框里的“列”属性中添加需要的字段,比如时间列和过程值列。
- 把变量管理里面已经开启归档的变量分配到对应列上。
- 设置查询的时间范围。可以设为相对时间(比如最近1小时),也可以绑定画面上的日期时间输入框,做成可选的。
- 运行画面,表格里就能看到历史数据了。
这里有个容易被忽略的细节:在线表格控件的“列”不一定都显示变量值。你完全可以配一列“注释”,一列“质量代码”,这样操作员就能通过表格快速判断这个数据点当时的采集状态是不是正常。
2.2 时间范围、刷新周期和行数上限:三个和性能强相关的坑
这个控件是能查出数据,但能不能“好用”,取决于另外三个参数。
第一个是时间范围。在线表格控件默认的查询窗口是相对时间,但新手很容易把整个归档时间都查出来,结果控件直接卡死。道理很简单:如果归档变量每秒记录一次,查一个月的时间范围就是260万条数据,控件要全部加载。所以建议做两件事:一是把时间范围做成画面上的输入框,让操作员自选;二是在控件属性里设置查询行数上限,默认值一般不建议超过几千行,超了就提示先缩小时间范围。
第二个是刷新周期。在线表格和在线趋势控件每隔一段时间会从归档库里取一次新数据,这个刷新周期要和你变量的归档周期匹配。变量归档周期是1秒,刷新周期也基本可以做到1秒;但如果归档周期是10秒,刷新周期设1秒意义不大,白白消耗性能。
第三个是缓存机制。WinCC的归档系统不是实时写库的,数据先进内存缓冲区,到一定条件才批量写入SQL Server。这意味着你打开表格控件查询“刚才那一刻”的数据,大概率会查不到最新的一条,要等归档段切换。这不是控件坏了,是WinCC内部机制决定的——查询窗口尽量选在当前时间几分钟之前的数据。
2.3 在线表格控件的“在线”到底是指什么
很多刚接触WinCC的工程师会误解“在线表格控件”里的“在线”,以为它显示的是实时数据。实际上,WinCC把数据分成两种模式:在线模式(Online)和归档模式(Archive)。
在线模式读取的是当前运行变量缓冲区里的值,适合看“现在的情况”;归档模式读取的是历史数据库里的值,适合回看“过去的情况”。报表需求百分之九十九都是归档模式。你在控件组态里看到类似“连接的数据源”再“归档”这样的选项,选归档模式就对了。
3. 历史趋势曲线控件的价值,一半在配置,一半在脚本
3.1 趋势控件不是拿来“看”的,是拿来“分析”的
在线趋势控件(WinCC Online Trend Control)和在线表格控件是一对搭档。表格给人具体的数值,趋势曲线给人直观的走势。项目里要做温度异常分析、压力波动判断的时候,靠表格一行行看会疯掉,趋势曲线一眼就能看出问题点。
配置方面和表格控件类似:拖控件、添加曲线、关联归档变量、设置时间轴。但趋势控件有几个专属属性,需要仔细调:
- 曲线颜色和线宽:多变量同屏显示时,颜色一定要区分清楚。推荐的做法是压力用暖色系、温度用冷色系、流量用中性色,别图好看乱配。
- 时间轴格栅:横轴刻度间隔要按时间范围自适应,查1小时的数据,刻度到分钟级;查24小时的数据,刻度到小时级。控件有自动刻度选项,建议开上。
- 数值轴范围:同一个控件里如果放压力和温度,数值差异可能很大,曲线会被压扁。这时候要么分开控件显示,要么在控件的数值轴里启用多轴模式,让不同变量用不同的纵轴。
3.2 历史趋势曲线脚本:怎么用代码控制曲线切换和导出
这是“wincc历史趋势曲线脚本”这个热词背后真正的需求。很多场景下,操作员不能每次都进组态去改曲线,必须做按钮,点一下切换时间范围,点一下显示某一组变量。这就得写脚本了。
下面这段VBS脚本的逻辑是:从画面上拿到趋势控件实例、清空旧曲线、添加两条新的归档变量曲线、设置最近4小时的时间窗口、刷新显示。
Dim objTrend Dim dStart, dEnd ' 获取画面上的趋势控件对象,名称要和画面里控件的实际名称一致 Set objTrend = ScreenItems("TrendControl1") ' 清空当前所有曲线 objTrend.ClearAll ' 添加两条归档变量曲线,变量名必须是开启了归档的变量 objTrend.AddCurve "Pressure_Tang", "P_Tang" objTrend.AddCurve "Temp_Tang", "T_Tang" ' 设置时间范围为最近4小时 dEnd = Now dStart = DateAdd("h", -4, dEnd) objTrend.SetTimeRange dStart, dEnd ' 刷新显示 objTrend.Refresh注意,WinCC不同版本的控件API名称会有差异,上面这个代码是逻辑框架,实际项目里要对照你那个版本的控件对象浏览器确认方法名。核心思路是通用的:取得控件对象、清空、添加曲线、设定时间窗口、刷新。
如果你连脚本都懒得写,也可以在控件属性里直接用“时间范围”的组态设置,绑定画面的按钮,配个“显示最近1小时”“显示最近1天”之类的固定值。灵活性和脚本比差一些,但胜在稳定,适合运维期不爱改代码的现场。
3.3 趋势曲线出“阶梯状”,不是坏了,是采样周期和压缩策略的事
我碰到过不少业主拿着趋势图过来问:“为什么这个压力曲线像楼梯一样一格一格的?”
原因通常有两个:一是变量归档周期设得太长(比如本来1秒记录一次,被改成了60秒),两次记录之间的变化自然显示不出来,曲线就成台阶了。二是在WinCC归档配置里启用了数据压缩,系统按死区/时间窗口做抽样,只保存特征点,画出来自然不是平滑的。
处理办法:趋势分析类的变量建议归档周期设到5秒以内,并且关闭压缩策略,或者把压缩死区设大一些,保证波动小的时候不记录、波动大的时候尽量记全。报表数据和趋势展示对数据密度的要求是不一样的,归档规划阶段要把两个场景一起想清楚。
4. 真正的“生产报表”是怎么做出来的:SQL取数加VBS导出
4.1 把WinCC当数据库查,而不是当控件用
当需求变成“我要一份交接班Excel报表,里面有全班次每个变量的平均值、最大值、最小值”的时候,在线表格控件和趋势控件就不够用了——它们能看、能打印,但做不了复杂的统计计算,也管不了Excel格式。
这时候的正确做法是:绕过报表控件,直接查WinCC的历史数据库。WinCC运行时的历史数据存在本机或服务器的SQL Server里,连接方式就是标准的ODBC或ADO。你完全可以把它当成一张普通的业务表来查询。
一个很容易踩的误区是去找“固定的表名”。WinCC的项目名不同、归档连接名不同,实际生成的表名也会不同,不同版本还有差异。所以别死记硬背表名,打开SQL Server Management Studio连上WinCC的运行时数据库,在sys.tables里翻一下实际表名,比什么教程都准。下面是通用的查询思路示例:
-- 表名请以实际数据库为准,先用下面这条语句看看有哪些表 -- SELECT name FROM sys.tables WHERE name LIKE '%Archive%' -- 查询某变量某时间段的归档数据 SELECT TagName, Value, Quality, Timestamp FROM dbo.Archive_Table -- 替换为实际表名 WHERE TagName = 'P_Tang' AND Timestamp >= '2025-01-01 00:00:00' AND Timestamp < '2025-01-01 08:00:00' ORDER BY Timestamp;4.2 VBS脚本把查询结果写进Excel,交接班报表自动化
数据查出来了,还差最后一步:生成Excel。这一步要么用WinCC全局脚本里的VBS,要么用外部程序做。我推荐VBS,因为直接在WinCC运行环境里就能跑,不用额外部署,配合画面按钮或者定时触发器就能自动执行。
来看一个精简后的脚本框架:
Dim objExcel, objWorkbook, objSheet Dim objConn, objRS, strConn, strSQL, iRow ' 创建Excel对象 Set objExcel = CreateObject("Excel.Application") Set objWorkbook = objExcel.Workbooks.Add Set objSheet = objWorkbook.Worksheets(1) ' 写表头 objSheet.Cells(1, 1) = "时间" objSheet.Cells(1, 2) = "压力" objSheet.Cells(1, 3) = "温度" ' 数据库连接和查询(连接串里的服务器名、库名按实际项目填) strConn = "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=YourWinCCDB;Integrated Security=SSPI;" strSQL = "SELECT Timestamp, Value FROM Archive_Table WHERE TagName='P_Tang' AND Timestamp > GETDATE()-1 ORDER BY Timestamp" Set objConn = CreateObject("ADODB.Connection") Set objRS = CreateObject("ADODB.Recordset") objConn.Open strConn objRS.Open strSQL, objConn ' 从第2行开始填数据 iRow = 2 Do While Not objRS.EOF objSheet.Cells(iRow, 1) = objRS.Fields("Timestamp").Value objSheet.Cells(iRow, 2) = objRS.Fields("Value").Value iRow = iRow + 1 objRS.MoveNext Loop ' 关闭连接 objRS.Close objConn.Close ' 导出格式 objSheet.Range("B:C").NumberFormat = "0.00" objWorkbook.SaveAs "D:\Report\RoutineReport.xlsx", 51 ' 51表示xlsx格式 objWorkbook.Close objExcel.Quit Set objRS = Nothing Set objConn = Nothing这段脚本有几个细节值得注意:
第一,Excel的单元格格式问题。很多从数据库直接写Excel的报表会出现“时间变成一堆数字”的情况,那是Excel把时间当成序列号了,需要在写完数据之后统一设置列格式,比如objSheet.Columns("A").NumberFormat = "yyyy-mm-dd hh:mm:ss"。
第二,别忘了清理Excel进程。脚本结尾如果没有Quit和对象置空,运行几次之后任务管理器里会堆一堆Excel后台进程,轻则内存暴涨,重则影响WinCC运行稳定。我见过一个项目报表跑了一个月,服务器上几十个Excel进程挂着不退出,最后把服务器拖到报警。
第三,定时触发放哪。交接班报表一般是每8小时跑一次,可以直接在WinCC全局脚本里用“定时触发器”来跑,也可以做成画面按钮让值班长手动点。我一般两种都做:手动按钮负责“补单”,定时触发负责“正常出表”。
4.3 平均值、最大最小值怎么算
报表最常要的不只是原始数据,而是统计值。SQL写起来不复杂,但有个坑:SQL Server的AVG,如果列里有NULL值或者质量码异常(Quality不是192),统计结果会让你怀疑人生。
建议在查询条件里加上质量码过滤,只统计质量正常的记录:
SELECT TagName, COUNT(*) AS Cnt, AVG(Value) AS AvgValue, MAX(Value) AS MaxValue, MIN(Value) AS MinValue FROM Archive_Table WHERE Timestamp >= '2025-01-01 00:00:00' AND Timestamp < '2025-01-01 08:00:00' AND Quality = 192 -- 192表示质量好,丢站或者满量程的数据别统计进去 GROUP BY TagName;质量码这个字段,新手很少看,老手天天看。WinCC归档数据里每条都有质量码,192是采样正常,128开头的一堆是异常。报表统计一定要把异常值过滤掉,否则一个传感器短时断线能把平均值拉出天际。
5. 现场最常见的两个“鬼问题”:数据刷不出来和V15.1许可证找不到
5.1 报表数据刷不出来,先按这个顺序排查
只要报表有问题,我都按固定顺序查,基本能覆盖八成情况:
第一步,查变量是否启用归档。变量管理里选中变量,看“记录”选项卡有没有勾选。没勾?报表肯定没数据。这一步占问题总量的四成以上,而且往往是最先要排除的。
第二步,查时间范围是否匹配。报表控件查询的时间段如果在归档开始之前、归档保留期之后,或者跨了归档段的切换窗口,都会出现查不到数据的情况。建议先把时间范围拉到最近半小时,一条条缩小范围试。
第三步,查归档服务和数据库连接。WinCC运行界面右下角的状态图标、Windows服务里的SQL Server服务、WinCC归档运行服务,这三个地方都得看一眼。只要有一个没起来,报表控件就是一摊死水。
第四步,查是不是权限问题。如果运行WinCC的用户账号没权限访问SQL Server的归档库,控件打开没报错,但也查不出任何数据。特别是域环境下,这种问题隐蔽得很。
5.2 V15.1找不到许可证,别急着重装,先按这个顺序查
“v15.1 找不到许可证 wincc comfort”这个搜索词眼熟吧?我在WinCC V15.1的Comfort版本项目里也翻过车,最后发现根本不是授权丢了,而是授权类型不对。
排查顺序是这样的:
第一,打开Automation License Manager看授权是否存在。如果授权列表里根本没有WinCC Comfort V15这一项,那问题就回到了“这台机器压根没装对应的授权”。
第二,看授权是不是被隐藏了。授权盘插在服务器上,但授权服务没启动,或者当前登录用户不是授权专用用户,ALM里就会找不到授权。把西门子相关的授权服务手动启动,再在ALM里点“重新读取”,多半能恢复。
第三,查系统时间。授权文件和系统时间绑定,如果现场有人把系统时间改回过去了,授权会暂时失效,因为防回溯机制会认为授权过期。改回正确时间后,重新读取一次授权就行。
第四,查授权版本匹配。这是最容易被冤枉的一点。原来装的是WinCC V14的授权,项目用V15.1打开,Comfort组件找不到V15对应授权。西门子的授权规则不是“高版本授权全覆盖”,而是需要对应版本的License Key,老项目跨版本时经常出这个问题。解决方法是做授权升级(License Upgrading),而不是重装软件。
第五,检查WinCC Comfort和WinCC Professional的区别。这两个是完全不同的授权产品线。用Comfort版授权打开Professional版项目,或者反过来,都会报“找不到许可证”。买授权之前一定先确认项目的实际编译目标版本是哪个。
5.3 团队协作时,报表模板打不开的坑也在这里
多工程师协作的项目里,如果一个人用WinCC V15.1,另一个人用V15.1 Update 4,报表控件版本不一致,画面模板很容易打不开或者控件属性丢失。这个问题看着像“报表模板坏了”,其实是控件版本被自动替换导致的。
项目组最好统一下发组态包版本,并且把报表画面所在的库文件(Pdl)和组件清单一起放进版本管理。我们在现场吃过亏之后,定了条规矩:凡是含有报表控件的画面,改完之后必须在同版本环境里打开验证一次再发版,别在个人电脑上改完直接丢服务器。
最后再分享一个我的习惯
做了这么多WinCC项目,我的切身体会是:报表控件这套东西,单看某一个环节都不难,难的是把“变量归档、控件显示、数据库查询、脚本导出”这条链路的上下游全部打通。
所以我每到一个新项目,第一周一定会做一件事:把所有需要出报表的变量整理成一张表,字段包括变量名、工艺位号、归档周期、压缩策略、报表用到的统计方式。这张表既是归档配置的依据,也是后面写SQL脚本的字典,更是和甲方确认报表口径的凭据。甲方说“我要平均值”,你问他“质量码异常的值算不算进去”,这一句话就能挡住以后无数扯皮。这个习惯,推荐你也试试。