多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

WinCC报表进阶:用VBS脚本直连SQL Server绕过自带方案

WinCC报表进阶:用VBS脚本直连SQL Server绕过自带方案 1. 为什么WINCC报表必须绕过自带方案直接动数据库1.1 WINCC自带报表能力的真实边界在WINCC项目里接到报表需求多数人的第一反应是找自带功能表格控件、趋势控件或者加钱上Report选件。但真正干过几个现场项目的人都清楚这招对简单的实时数据显示还行一旦报表需求开始具体化——比如要按班次汇总产量、要查特定批次的质量趋势、要做多条件组合查询、要把数据导出给管理层——自带方案就开始露怯。WINCC自带的表格和趋势控件本质上是数据可视化组件强在实时看弱在事后查。数据在画面里看得见但导不出来也做不了灵活的汇总分析。Report选件走的是模板打印路线用起来有种报表软件的早期形态的感觉模板设计界面比较古早做复杂查询逻辑时限制明显而且这选件是需要单独授权的项目报价的时候没算进去后面想加就得补钱。更本质的原因在于架构层面WINCC自己的历史数据底层就是存放在SQL Server中的。组态软件只是在这个数据库之上套了一层自己的访问接口和界面。报表的本质就是查询数据库里的数据那么绕过自带壳子直接用一个脚本去查底层数据库反而是更直接、更可控的路径。这不是什么黑科技只是很多做组态的人平时不太往这个方向想——大家都默认用WINCC就得用WINCC的报表功能没意识到数据本来就裸躺在SQL Server里随时可以自己动手取。1.2 报表数据从哪里来WinCC的存储本质要直接动数据库首先得搞清楚WINCC的数据到底存在哪里。很多工程师在WINCC上做过变量归档配置但未必了解背后的存储机制。WINCC运行时产生的数据大体分几类变量归档数据你在变量管理处启用了归档的标签采集的原始值、平均值、瞬时值等最终落在项目数据库里的一组归档表中。报警记录报警发生时产生的记录同样存在于项目关联的数据库中。用户操作日志比如谁在几点登录、谁改了哪个参数这类审计性质的数据也在数据库里。这里有个容易踩坑的细节WINCC的变量归档是有生命周期的。归档数据默认按照设定好的存储周期滚动覆盖老数据会被自动清理或者压缩。过期不候不是说数据库无限大就能查无限久。所以做报表前第一件事不是写脚本而是确认要查询的数据到底还在不在归档里。如果项目已经运行了大半年归档周期却只设置了三个月那生产报表里缺了几个月的前期数据往回补都补不上。这也是为什么做正规报表项目时我们往往不只靠WINCC自带的归档还会自己建一张长期存储表定时把关键变量挪进去。这种数据落地的思路相当于给数据上了一道双保险也为后面做各种自定义报表打好了底子。1.3 什么时候该走SQL脚本这条路以我这些年看到的现场需求下面这几种情况建议果断上SQLVBS方案报表类型典型需求自带方案的短板班次汇总表早/中/夜班的产量、运行时长、报警次数自带控件难以按自定义时间段动态归组批次日志表每批配方、关键温度曲线点、与目标值对比单批数据来自多个标签组态控件做起来别扭设备效率报表运行、停机、待机时间占比OEE前身需要根据状态变化推算持续时长自带控件做不到操作审计表谁在几点改了哪个参数、改前改后值需要查WinCC内嵌的日志机制且格式不灵活MES/ERP对接定时把生产数据同步给上层管理系统本质上是数据接口不是报表展示判断标准其实很简单如果报表核心是把数据库里的数据按业务规则重新组织那就是SQL的活如果需要在画面上实时显示并允许操作员交互那才是组态控件的强项。现实情况往往是两者结合——WINCC画面提供查询入口和展示界面背后全部交给VBS脚本和SQL语句去干活。这篇文章的结构也照着这个思路来先讲怎么搭好连接环境再讲怎么写查询和写入逻辑然后是现场实战中遇到的坑最后聊怎么把报表做得更好用。不需要你精通VBS也不要求你会SQL优化按步骤抄就能跑起来。2. 搭好连接环境ODBC、连接字符串和驱动选型那些坑2.1 数据库端准备动手写脚本之前先把数据库这头的事情办好。我的习惯是单独建一个报表数据库不要直接在WINCC项目库里增删表。原因特简单WINCC项目库有自己的一套权限管理和备份机制你直接动它的表结构轻则影响WINCC启动重则把项目搞坏。而且项目库的表结构是为组态软件服务的数据结构不一定适合报表直接查询。我自己一般这么建库数据库名ReportDB看着直观就行账号设计wincc_reader只读账号专门给查询报表用wincc_writer写入账号给业务记录插入用绝不直接用sa跑业务连接定期备份报表数据表单独纳入备份计划数据丢了补不回来关于建表时的字段设计有一条经验值得提时间字段优先用datetime2或smalldatetime别为了省空间存成float类型的Unix时间戳。报表查询里最频繁的条件就是时间范围过滤时间字段建上索引后查询速度和没索引完全是两个量级。我曾经接手过一个现场对方把时间存成了double每次查询前还得在SQL里做一次时间戳转换数据量一大查询能卡出天际后来花了一个晚上改了表结构才算根治。2.2 ODBC数据源创建32位与64位的经典陷阱连接数据库最常用的是通过ODBC数据源。你以为在Windows的ODBC数据源管理器里建好了就行结果WINCC里的VBS脚本死活连不上——这个问题我见过太多次了。原因在于WINCC的核心组件跑在32位进程下即使在64位Windows Server上VBS脚本里创建ADO对象时使用的还是32位的ODBC环境。你在开始菜单打开ODBC数据源64位建的数据源32位程序根本看不见。两边各有各的数据源列表互不相通。正确的操作方式打开C:\Windows\SysWOW64\odbcad32.exe在这里面创建数据源。这个路径下打开的是32位的ODBC管理器。建的时候选System DSN系统数据源别选用户DSN——用户DSN在某些服务权限场景下会访问不到用系统DSN稳一些。ODBC Manager里创建数据源时可以选择驱动类型。如果是SQL Server 2000时代的习惯用SQL Server驱动没问题。如果装了新版SQL Server Native Client选ODBC Driver 17 for SQL Server或对应的SQL Server驱动。2.3 VBS脚本里的ADO连接写法两种方式对比VBS脚本访问SQL Server的核心组件是ADO全称叫ActiveX Data Objects。ADO提供了Connection连接、Recordset结果集、Command命令几个对象用起来就跟在编程语言里操作数据库一样。连接数据库有两种主流写法方式一走ODBC DSNDim conn Set conn CreateObject(ADODB.Connection) conn.ConnectionString DSNWinCCReportDSN;UIDwincc_reader;PWDyourpassword conn.Open方式二直接用OLEDB Provider不依赖DSNDim conn Set conn CreateObject(ADODB.Connection) conn.ConnectionString ProviderSQLOLEDB.1;Data Source192.168.1.10,1433;Initial CatalogReportDB;User IDwincc_reader;Passwordyourpassword;Persist Security InfoTrue conn.Open两种方式在工作中都很常见。DSN方式的好处是集中管理连接配置换服务器只需改一处DSN坏处是每台运行VBS的机器都要手动创建一个同名的DSN而且32位/64位区分容易踩坑。OLEDB方式的好处是连接字符串直接写在脚本里部署到新机器零配置坏处是你得确保目标机器装了对应的OLEDB驱动SQLOLEDB是老驱动新版SQL Server建议换用MSOLEDBSQL但要在目标机器安装驱动文件。我个人偏好第二种因为项目现场经常要跨机器调试把连接信息集中放在脚本顶部的一个变量里比逐台机器配置DSN省事得多。另外如果公司本身有配置管理规范也可以把连接字符串统一放到一个配置文件或注册表里VBS脚本只负责读取这样运维上更优雅。2.4 第一条验证查询写长篇的报表脚本之前先用一条最简单的查询验证整个链路。别一上来就甩个几百行的查询SQL出了错你根本分不清是连接的问题还是SQL的问题。我的调试工序是这样的先在SQL Server Management StudioSSMS里写好并验证SQL语句确认数据结果正确在VBS里建立连接先执行SELECT 1确认能够正常读取再执行正式的报表查询把结果集先输出到文本文件或弹窗里看效果最后再接入WINCC的画面对象做界面输出这套流程看着多了一步实际上能帮你避开一大堆无谓的排查。我见过很多人把SQL和界面绑定在一起调报错信息混在一起查了半天最后发现是SQL里多了个多余逗号白白浪费大半天。3. 把SQL查询逻辑想清楚报表才不返工3.1 时间范围查询与WINCC时间戳的匹配问题报表查询里最核心也最容易出错的就是时间。先说一个比较隐蔽的坑WINCC的变量归档表里时间戳存储的是UTC时间不是本地时间。中国处于UTC8时区所以从归档表里直接查数据时间字段的显示值会比本地时间早8个小时。白天看可能没感觉一到夜班数据就会跑偏做班次统计时非常容易出乱子。这里要区分两种情况如果数据是VBS脚本写入你自己的报表表那就完全由你控制。建议统一用本地时间插入时用GETDATE()函数或者VBS里的Now()函数查询时直接拿界面参数和时间字段比较不需要做任何换算。如果绕不开要直接读WINCC归档表查询条件里记得做时区偏移WHERE DATEADD(hour, 8, StartTime) BETWEEN startTime AND endTime但这样写有一个隐患在时间字段上套了函数之后索引会失效大数据量查询会变得很慢。更稳妥的做法是先把界面传入的本地时间换算成UTC时间再用原始字段做范围比较让索引正常工作。或者更彻底一点定期把WINCC归档数据同步到一张自定义的本地时间表里查询时只查这张同步表速度和准确性都好控制。3.2 按班次、按批次归组汇总工厂报表最典型的需求就是班次统计。早班从08:00到16:00中班16:00到00:00夜班00:00到08:00。逻辑本身不复杂但写SQL时有个边界问题要想清楚某天凌晨2点的数据其实属于前一天的夜班如果按自然日GROUP BY夜班统计就会缺掉一块。班次归组的推荐写法是CASE WHEN表达式SELECT CASE WHEN CONVERT(datetime, CONVERT(varchar(10), CreateTime, 120) 08:00:00) CreateTime AND CONVERT(datetime, CONVERT(varchar(10), CreateTime, 120) 16:00:00) CreateTime THEN 早班 WHEN CONVERT(datetime, CONVERT(varchar(10), CreateTime, 120) 16:00:00) CreateTime AND CONVERT(datetime, CONVERT(varchar(10), CreateTime, 120) 23:59:59) CreateTime THEN 中班 ELSE 夜班 END AS ShiftName, COUNT(*) AS BatchCount, SUM(GoodCount) AS TotalGood FROM dbo.ProductionLog WHERE CreateTime 2025-06-01 00:00:00 GROUP BY CASE ... END ORDER BY ShiftName这类逻辑在实际项目里不建议散落在每个VBS脚本里而是封装成一个视图或SQL函数。因为班次定义经常变有的工厂是三班倒早中夜有的工厂是两班倒08:00到20:00还有季节性调整。把时间换算逻辑集中在视图里改班次只动一处不用挨个报表脚本翻找。批次归组相对简单通常是按BatchID聚合。但要注意一个坑一个批次可能跨班次或者说一套配方从投料到出料横跨好几个小时甚至一天如果只按批次ID统计却不记录涉及哪个班次后续排产和绩效核算就说不清了。我一般建议在写入生产日志时就把批次和班次的对应关系算好存起来而不是查询时再临时推算——写入时算一次查询时能省无数事。3.3 多条产线、多个标签的组合查询一个报表里经常要同时看好几条产线的数据、好几个温度测点的值。最笨的办法是写循环对每个标签单独发一次查询再在VBS里拼接性能差且代码冗余度高。正确处理方式是让SQL一次把所有标签查出来。如果数据表是长表结构每条记录包含标签名和值字段可以用条件聚合一次成型SELECT CONVERT(varchar(10), RecordTime, 120) AS Date, MAX(CASE WHEN TagName Line1_Speed THEN Value END) AS Line1_Speed, MAX(CASE WHEN TagName Line2_Speed THEN Value END) AS Line2_Speed, AVG(CASE WHEN TagName Furnace_Temp THEN Value END) AS Furnace_Temp_Avg FROM dbo.TagHistory WHERE RecordTime BETWEEN start AND end GROUP BY CONVERT(varchar(10), RecordTime, 120)这种写法把N次查询合并成1次对报表性能的提升非常明显。WINCC下面跑的历史数据表动辄几十万上百万行哪怕每次查询省下一半的IO开销用户体验都是天壤之别。如果数据表是宽表结构每个标签占一列那查询就简单了直接SELECT需要的那几列就行。但宽表有一个运维麻烦每次新增一个监测点就要ALTER TABLE加一列改表结构会出现短暂的锁表。我在项目里通常会跟客户确认后续加监测点多不多如果频繁加选长表如果标签基本固定宽表的直观性对后期维护的人更友好。这个选型决定了后续所有报表SQL的写法开工之前值得花半天时间想清楚。3.4 参数化查询别在脚本里拼SQL字符串我看到过很多VBS脚本写查询习惯性地拼字符串sql SELECT * FROM dbo.ProductionLog WHERE CreateTime startTime AND CreateTime endTime rs.Open sql, conn, 1, 1这段代码在绝大多数场景下能跑通但它有两个隐患。首先是SQL注入风险。报表界面如果允许用户输入批次号或工单号输入框里万一包含单引号、分号之类的特殊字符SQL就会报错恶意一些的输入甚至可能执行额外语句。工业内网环境下大家都觉得无所谓但干这一行养成好习惯没有坏处。其次是执行计划缓存问题。每次拼接出来的SQL文本不一样SQL Server可能每次都重新编译执行计划高频访问时性能会受影响。更严谨的写法是使用参数化查询Dim cmd Set cmd CreateObject(ADODB.Command) cmd.ActiveConnection conn cmd.CommandText SELECT * FROM dbo.ProductionLog WHERE CreateTime ? AND CreateTime ? cmd.Parameters.Append cmd.CreateParameter(p1, 135, 1, 16, startTime) cmd.Parameters.Append cmd.CreateParameter(p2, 135, 1, 16, endTime) Set rs cmd.Execute这种写法下用户输入被当作参数处理不参与SQL文本的解析过程天然免疫注入问题同时固定的SQL文本更容易复用执行计划查询性能稳定代码维护性也好一大段查询不会被字符串拼接搞成乱麻。参数化查询多写几行代码刚开始确实会觉得麻烦。但报表脚本一旦定型后面全靠维护的人去改。你清爽清晰的代码就是给几个月后的自己和其他维护者省时间。4. 不只是查用VBS把WinCC实时数据写入SQL Server4.1 写入场景分析谈到WINCC和SQL Server联动很多人只想到读取和查询。实际现场里写入需求同样高频大概分三类操作记录操作员在WINCC画面上改了某个工艺参数、点击了某个启动按钮立即插入一条记录包含操作时间、操作人、操作内容、改前值、改后值。这是审计类需求出了质量事故或操作纠纷时就是证据。批次数据一批产品生产结束把批次号、开始时间、结束时间、关键工艺参数、产量合格数整批写入一张表。批次表是后面做追溯和统计的核心。状态变迁数据设备从运行切到停机、从停机切到待机每次状态变化插入一条带起止时间的记录方便后续算OEE和效率报表。这类数据用WINCC自带的变量归档做不了因为归档是连续采样的过程数据而这里是离散的业务事件。事件和趋势本质上是两种完全不同的数据模型。4.2 INSERT操作的完整流程与主键处理VBS里执行INSERT核心逻辑是这样Dim cmd Set cmd CreateObject(ADODB.Command) cmd.ActiveConnection conn cmd.CommandText INSERT INTO dbo.OperationLog (LogTime, UserName, ActionName, OldValue, NewValue) VALUES (GETDATE(), ?, ?, ?, ?) cmd.Parameters.Append cmd.CreateParameter(p1, 200, 1, 50, userName) cmd.Parameters.Append cmd.CreateParameter(p2, 200, 1, 50, actionName) cmd.Parameters.Append cmd.CreateParameter(p3, 200, 1, 50, oldValue) cmd.Parameters.Append cmd.CreateParameter(p4, 200, 1, 50, newValue) cmd.Execute这里有个设计细节主键怎么处理。我推荐用自增IDENTITY列或者GUID。千万不要用读取到的时间戳做唯一主键——为什么因为两台操作站可能同时操作时间戳会撞车而且WINCC脚本的写入事务和画面刷新时机差那么零点几秒业务时间并不保证唯一。另外写入操作务必带错误处理。VBS脚本跑在WINCC的运行环境里报错弹窗经常不明显甚至弹不出来如果不做错误捕获操作员根本发现不了数据没写进去。月底对账发现少了几十条记录那才是真头疼。On Error Resume Next cmd.Execute If Err.Number 0 Then 把错误写进本地日志文件便于排查 LogFileWrite INSERT失败: Err.Description End If On Error GoTo 04.3 写入与查询共存的锁与性能处理报表系统调通了写入也正常了接下来迎来的往往是性能问题运行的写入操作和报表查询互相锁表。SQL Server在默认事务隔离级别下一个INSERT可能会锁住对应行或页查询如果刚好要读同一区域的数据就会阻塞等待。WINCC的VBS脚本是单线程一旦等待超时可能引发连锁反应严重时连画面控件都卡住。我在项目里常用几个缓解手段报表查询语句加NOLOCK提示或设置隔离级别为READ UNCOMMITTED。报表本身容忍读到未提交的脏数据速度快是第一诉求。报表数据库的压力尽量和生产写入库分开。如果公司条件允许做只读副本是最干净的方案。大批量写入时用批量INSERT别一条条INSERT。把历史数据和当前热数据分开存储。每月定时把超过统计周期的数据归档到历史库报表查询只面对近期表速度稳定。在实际项目里我经常给生产日志表做一个按月分区或者按年归档的方案。比如每个月1号跑一个存储过程把上上个月的数据挪到历史库。这样报表表永远只保留最近一个多月的记录查询速度快备份也轻量。5. 踩坑实录我在现场调试中遇到的5个问题5.1 64位系统下ODBC源看不见有个客户现场是64位Windows Server我在控制面板里的ODBC管理器创建了数据源但在WINCC运行画面里点击查询按钮VBS报错未找到数据源。排查过程倒是很快因为我以前踩过这个坑。WINCC的画面运行进程是32位的VBS里的ADO组件运行在这个32位进程里它去查找ODBC源时只会找32位的注册表项。系统管理工具里打开的是64位的ODBC管理器两套来源在注册表里存放的位置不同互相看不到。解决办法运行C:\Windows\SysWOW64\odbcad32.exe在那里重新创建数据源。之后每次遇到DSN找不到的问题我第一反应就是看操作者是在哪个ODBC管理器里建的源。这个知识点在现场能帮同行省下不少测试时间。5.2 日期格式导致查询结果为空有次在客户那里调日报表点击查询后出来一个空表后台SQL手动执行同样的语句却有数据。折腾了一圈最后定位到系统区域设置上。客户的工控机区域设置是英语(美国)默认日期格式是MM/dd/yyyy而SQL Server的连接语言环境又设置了简体中文两种优先级一冲突VBS拼接出来的日期字符串根本没被当成预期的时间值。解决方式是把VBS脚本里所有时间拼接统一写成CONVERT(varchar, GETDATE(), 120)格式也就是YYYY-MM-DD HH:MI:SS。这个格式在任何一个区域设置下都不会被误解SQL Server也能正确解析。后来我在自己团队里立了个规矩VBS里所有时间格式一律用120样式谁用别的格式得说清楚为什么。5.3 脚本在WINCC里首次运行慢WINCC报表按钮第一次点击弹出来的画面和结果要等好一阵子。不是查询慢是COM组件首次加载慢。VBS脚本调用ADO、Excel等组件时进程首次创建和注册这些组件实例要花时间这表现在用户体验上就是点了没反应过几秒才出来。处理方法在WINCC画面加载事件里预先创建常用的ADO连接对象让COM组件提前加载。这样操作员点击查询时连接已经就绪速度体感会快很多。如果项目里用到Excel导出也可以提前把Excel对象创建出来或者接受冷启动慢但在界面上加一个正在初始化的友好提示。5.4 中文乱码VBS写入SQL Server中文正常但报表导出Excel后乱码或者反过来Excel里正常WINCC画面里显示乱码。这类问题大多出在编码环节。如果导出CSV文件注意编码选择。用UTF-8带BOM的方式写文件Excel打开时才不会把中文显示成乱码。如果在中文Windows上直接用GBK编码也没问题但放着UTF-8更通用。如果导出的是XLS/XLSX文件建议直接用Excel.Application对象逐格填入数据而不是拼文本转成文件。Excel对象写入不会出现编码问题只是速度稍慢。数据量大时用CSV曲线救国数据量小用Excel对象这两种方式在工程复现率上没有明显差异。5.5 报表数据与WINCC曲线对不上客户反馈报表里统计的温度平均值和WINCC趋势控件里看到的平均值不一致。刚听到这个问题时第一反应是SQL统计口径出了问题但仔细排查后发现两者算法本来就不一样。WINCC趋势控件默认展示的采样点通常是原始值按设定间隔抽出来的或者是按数据归档方式提取的代表值。报表SQL的AVG函数则是对所有原始值做算术平均。采集频率越高两种算法差异越小采集频率低且波动大时差别就明显了。技术上的原因很简单但业务上的教训比较深刻做报表前一定要跟客户确认统计口径——平均值是基于原始值、分钟值还是小时值最大值最小值同理。口径没确认就动手写SQL返工是大概率事件。项目会议上把这个问题讨论透比闷头开发完再推倒重来效率高得多。6. 让报表从能跑到好用定时任务和Excel导出6.1 定时生成报表的三种实现方式能查了能导了接下来一个常见需求是自动发报表每天早上八点昨天的班次报表自动生成发到生产主管的邮箱。实现三种方式WINCC全局脚本定时任务在WINCC的Global Script里配置时间触发器到点执行VBS脚本查询数据并发送。缺点是定时任务跟着WINCC的运行状态走画面重启或运行项卡住报表也就停了。Windows计划任务调用VBS写成独立的VBS脚本文件用操作系统计划任务定时调用。好处是和WINCC解耦WINCC挂了报表照样跑缺点是它只负责脚本执行不做数据处理的话拿不到WINCC内部变量。SQL Server作业如果统计逻辑不涉及画面和交互可以写成存储过程用SQL Server代理作业定时执行。最稳但需要额外的SQL作业配置和权限管理。我的建议是凡是需要用户在界面上交互的报表放WINCC画面里凡是纯自动化定时上报的报表用Windows计划任务独立跑别让WINCC的进程状态影响报表运转。这也是我在几个项目里试下来最省心的组合。6.2 一键导出Excel在WINCC操作画面上放一个导出Excel按钮背后是VBS调Excel.Application对象按固定模板将查询结果写入工作表。基本套路如下Dim xlApp, xlBook, xlSheet 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) 产量 Do While Not rs.EOF i i 1 xlSheet.Cells(i1,1) rs.Fields(CreateTime).Value xlSheet.Cells(i1,2) rs.Fields(ShiftName).Value xlSheet.Cells(i1,3) rs.Fields(TotalGood).Value rs.MoveNext Loop xlBook.SaveAs D:\Reports\DailyReport_ Format(Now, yyyyMMdd) .xlsx xlBook.Close xlApp.Quit三个常见坑提醒一下Excel工作表的Cells是1基索引第一行第一列而Recordset的Fields是0基索引习惯上容易弄混。xlApp.Quit之后记得Set xlApp Nothing否则Excel进程残留在后台时间久了服务器上挂一堆EXCEL.EXE内存全被吃光。如果服务器装了WPS而不是OfficeCreateObject(Excel.Application)会失败或指向不同的组件项目交付前先确认目标机器的办公软件类型。6.3 权限控制与账号安全项目做到最后整个VBS脚本体系里藏着数据库账号和密码。我见过不少工程现场把sa账号和明文密码直接写在脚本里图省事。这在放有防火墙的工业内网里风险没那么大但一旦发生问题溯源和责任界定也会变麻烦。我通常建议这样做查询账号只给SELECT权限写入账号只给INSERT和UPDATE权限不给DELETE。脚本里的密码集中放到一个配置文件中VBS脚本启动时读取不散落在各个画面脚本里。如果担心明文密码暴露也可以做简单的加密处理至少别让一个看画面的人顺手把sa密码抄走。报表做到这一步一个完整的数据闭环基本打通WINCC实时采集存入归档VBS定时写入业务表报表脚本查询统计输出Excel。后面无论是加趋势对比图、加异常预警、做KPI看板底层用的还是这套SQLVBS的链路。我个人这些年做WINCC报表最大的体会是报表这块活十次里有七次不是脚本写不出来而是数据模型没设计好、时间口径没统一、基础连接配置上栽了跟头。把本文里这些基础环节做扎实后面加什么功能都是顺理成章的事。最后分享一个小技巧调试VBS连SQL的脚本时别太依赖弹窗WINCC运行环境下VBS的错误弹窗经常被吞掉。在代码里临时加一行把Err.Number和Err.Description写到文本文件里排查问题的效率直接翻倍。要是再配合SQL Server Profiler监控查询执行情况那基本就是所见即所得级别的问题定位了。
返回列表