恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

WINCC SQL报表开发:VBScript+ActiveX实现查询打印

  • 首页
  • 资讯中心
  • /
  • WINCC SQL报表开发:VBScript+ActiveX实现查询打印

相关资讯

YashanDB数据库故障排查实战:7类高频问题处理指南 2026/10/11 19:43:19
从水货到实干:Java面试高频考点与原理复盘 2026/10/11 19:38:19
如何在10分钟内跑通OpenClaw on Android:面向新手的快速开始教程(F-Droid Termux到openclaw gateway) 2026/10/11 19:38:19

最新资讯

Pi 1.0 原生集成 MCP:从插件到内建的架构升级与迁移指南
MySQL数据可视化看板搭建:从数据准备到性能优化全指南
冒泡排序的全息解剖:从教学脚手架到嵌入式优选算法
向量数据库与PGVector选型:工程边界、索引调优与混合查询实践
Node.js开发环境搭建指南:版本选择、npm源切换与多版本管理
共享Buffer却带宽没降?DDR流量的五大根因与排查实战

今日推荐

Debian新手入门:从部署到日常操作的完整指南
MongoDB复制集扩缩容实战:从rs.add到选主事故复盘
条形码目标检测数据集实战:从YOLOv8训练到部署

本周热门

UE动画修改实战:从资产编辑到重定向与蒙太奇驱动
统计随机数生成器攻击下的KLJN安全密钥交换协议Matlab仿真
政务API安全治理:资产测绘、低代码编排与行标对标实践

本月精选

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

WINCC SQL报表开发:VBScript+ActiveX实现查询打印

发布时间:2026/10/11 19:43:19
WINCC SQL报表开发:VBScript+ActiveX实现查询打印 简介面向工业自动化领域的WinCC组态与报表开发人员这份文档系统讲解如何利用VBScript脚本语言结合MSFlexGrid与MS DTPicker控件在SIMATIC WinCC中实现SQL数据库查询与报表展示解决生产数据实时监控与分析的需求。内容覆盖SQL Server 2005数据库与表结构创建、WinCC全局脚本中VBS写入与查询数据库的完整代码、报表画面组态以及控件注册、日期选择、数据导出打印等实操细节。包体为1个doc文档大小1.11MB结构按数据库创建、画面组态、脚本编写、附录代码逐步展开。该资源已有1680人学习下载适合具有一定WinCC使用基础、希望掌握VBScript与SQL交互开发方法的工程师学习。通过对照文中示例读者可快速搭建自己的WinCC SQL报表查询模块提升工业自动化系统的数据处理与可视化能力。1. 把 WINCC 的 SQL 报表拆开看不做“黑匣子”直接控制查询与打印做过程自动化项目的人几乎都遇到过同一个诉求现场操作员要按日期查历史趋势、统计 CPU 和内存占用率然后打印成日报表交班。WINCC 自带的报表功能用起来不够灵活而且对“某一天 8:00 到 23:59”这种自定义时间段的查询配置起来很别扭。我见过不少团队把这类需求外包给人做拿到手只是一个装好的画面脚本逻辑藏得严严实实出了毛病根本没法改。但实际上用 VBScript 和 MSFlexGrid、DTPicker 两个 ActiveX 控件完全可以自己搭一套“能查、能算、能打印”的 SQL 报表体系。这篇文章直接把创建数据库、组态画面、写查询脚本、打印导出的完整路径拆给你新手照着做能跑通熟手能看到哪些地方容易埋雷。2. 先搭数据库SQL Server 2005 建库建表与字段类型选择2.1 从 Management Studio 到新建数据库把“库名、表名、列名”一次定清楚SQL Server 2005 虽然是老版本但做单机版 WINCC 数据归档完全够用。打开 SQL Server Management Studio登录后左侧对象资源管理器里展开服务器节点右键 Databases 选 New Database。Database Name 这里我建议不要用带中文和短横线的名字否则后面 VBS 连接字符串里很容易出编码问题。比较稳妥的库名是ReportDB这类纯英文。建完库之后右键 Tables 选 New Table开始定义列。这个项目里需要存时间和三个性能指标我建议至少包含以下字段列名数据类型允许 Null说明timedatetime否采集时间戳cpureal是CPU 占用率ramreal是内存占用率harddiskreal是硬盘占用率提示real类型在 SQL Server 里是 4 字节浮点存百分数这种精度完全够。不要用float它占 8 字节报表数据量上来后索引页会变大。保存表名时我见过有人把表名设为report或VBSReport都能跑但注意后面脚本里连接字符串的Initial Catalog是库名INSERT INTO后面是表名这两个必须和创建时完全一致大小写不敏感但拼写错一个字母直接报错。2.2 全局脚本的数据写入ADODB 连接与 INSERT 语句的固定套路数据库建好只是第一步真正要让 WINCC 往 SQL 里写数据得在 WINCC 全局脚本里写一个周期触发的 VBS 函数。项目正文里给了一段action函数核心逻辑是读 WINCC 内部变量值拼一条 INSERT 语句再用 ADODB 连接执行。Option Explicit Function action Dim database, strcn, cn, is_SQL Dim a, b, c, d Dim DateTime a Now b HMIRuntime.Tags(cpu).Read c HMIRuntime.Tags(ram).Read d HMIRuntime.Tags(hd).Read strcn ProviderSQLOLEDB.1;Integrated SecuritySSPI;Persist SecurityInfoFalse;Initial CatalogReportDB;Data Source.\wincc Set cn CreateObject(ADODB.connection) cn.connectionString strcn cn.Open is_SQL insert into VBSReport(time,cpu,ram,hd) Values( a , b , c , d ) cn.Execute is_SQL cn.Close End Function这段脚本的逻辑不复杂但有两个地方必须说清楚。a Now取的是系统本地时间如果 WINCC 运行在工控机上要保证工控机时间跟标准时间一致否则查询时按BETWEEN过滤会漏数据。HMIRuntime.Tags(cpu).Read读的是 WINCC 内部变量cpu的当前值这三个变量必须在 WINCC 变量管理器里先建好。strcn里的Data Source.\wincc表示连接本机默认实例如果 SQL Server 是命名实例要改成主机名\实例名。Integrated SecuritySSPI用的是 Windows 身份验证要求 WINCC 运行账户对 SQL Server 有访问权限——这是初学者最容易卡住的地方装 SQL Server 时选了混合认证但 WINCC 服务用的是本地系统账户连不上数据库。执行完cn.Execute is_SQL后一定要cn.Close不释放连接对象的话周期触发几次后会出现“连接池已满”的报错。全局脚本的触发条件我一般设置为 1 分钟一次用触发器里的“时间周期”事件。2.3 验证写入结果先查表再组态别急着回 WINCC脚本写完先别回 WINCC 组态画面直接在 SQL Server Management Studio 里执行SELECT TOP 10 * FROM VBSReport ORDER BY time DESC能看到时间、cpu、ram、hd 四列数据就说明写入链路通了。如果表是空的优先排查这几项WINCC 全局脚本是否处于激活状态脚本编辑器里有个“启用”开关触发器周期是否设置正确脚本有没有语法错误VBS 编辑器里编译一次注意我在实际项目里遇到过一种情况SQL Agent 服务没启动导致脚本执行了但数据没落库。检查 Windows 服务列表里 SQL Server 相关的服务确保代理服务处于运行状态。3. WINCC 画面组态从控件注册到报表布局的完整步骤3.1 为什么选 MSFlexGrid 和 DTPicker轻量、免授权、够用WINCC 自带的表格控件如 ListView 或 Table Control在报表场景下要么操作繁琐要么样式不灵活。MSFlexGrid 是 VB6 时代就存在的 ActiveX 表格控件支持合并单元格、列宽自由调整、按行列读写文本正好满足“查询结果展示 → 统计行追加 → 打印到 Excel”这条需求链。DTPicker 是日期时间选择控件用户点一下就能选日期比手输文本框省事得多也避免了“2024-05-08”和“2024/05/08”格式不统一导致的查询失效。这两个控件在 WINCC 里属于 ActiveX Controls添加方式如下。3.2 控件添加与注册regsvr32 的两种情况新建 WINCC 项目后在图形编辑器里打开报表画面从右侧控件面板选 ActiveX Controls右键 Add/Remove在弹出的对话窗口里找 Microsoft FlexGrid Control 6.0 和 Microsoft Date and Time Picker Control 6.0 (SP4)。如果列表里找不到 FlexGrid大概率是系统里没有这个 OCX。项目正文里提到的方式非常实用先把MSFLXGRD.OCX拷贝到C:\WINDOWS\system32然后在“开始 → 运行”里输入注册命令regsvr32 MSFLXGRD.OCX解除注册的命令是regsvr32 /u MSFLXGRD.OCX。DTPicker 对应的文件是MSCOMCT2.OCX如果 FlexGrid 注册成功但 DTPicker 还是灰色不可选用同样方式注册 MSCOMCT2.OCX。注意64 位系统上 System32 目录存的是 64 位 DLL而 WINCC 早期版本可能是 32 位应用需要把 OCX 放到C:\Windows\SysWOW64目录下再注册。这个问题我踩过一次32 位 WINCC 死活找不到控件后来放到 SysWOW64 里一次就解决了。3.3 画面布局与控件属性名称、列数、合并选项把两个控件拖到画面上后在属性窗口里改名。DTPicker 我建议命名为Date1和Date2分别表示起始日期和结束日期MSFlexGrid 命名为Grid1。脚本里用ScreenItems(Date1)取控件对象名称写错直接报“未找到对象”的错。MSFlexGrid 的关键属性设置如下属性推荐值作用Cols5固定 5 列序号、时间、CPU、内存、硬盘Rows10初始行数脚本运行时按记录数动态扩展FixedRows1固定首行作为表头FixedCols1固定首列作为序号列AllowUserResizing2允许用户调整列宽MergeCells4允许自由合并单元格MergeRowTrue按行合并这些属性在属性窗口里直接改也可以在 VBS 脚本里动态设置。脚本里动态设置的好处是换电脑时不用重新配控件但初学阶段建议先手工配好脚本里只负责给格子填值。3.4 查询和打印按钮与 ActiveX 控件通信的前提画面上再放两个按钮一个文本改成“查询”一个改成“打印”。这两个按钮的鼠标单击事件会触发 VBS 子程序。按钮和控件属于同一画面脚本里通过ScreenItems访问跨画面的直接访问要写ScreenItems(画点名.控件名)我一般不这么干而是把查询和打印逻辑集中在一个画面上降低耦合。4. VBS 脚本详解把日期选择、SQL 查询、结果显示串成一条线4.1 构造查询条件DTPicker 值转为字符串的细节查询按钮的脚本是整个方案的心脏。先看前半段——日期读取和字符串拼接Set Date1 ScreenItems(Date1) Set Date2 ScreenItems(Date2) By Year(Date1.Value) Bm Month(Date1.Value) Bd Day(Date1.Value) Ny Year(Date2.Value) Nm Month(Date2.Value) Nd Day(Date2.Value) BeginDate By - Bm - Bd 00:00:00 EndDate Ny - Nm - Nd 23:59:59Date1.Value返回的是日期时间类型直接用Year()、Month()、Day()拆开再拼字符串是为了保证 SQL 里BETWEEN的范围精确到秒。这里有一个容易翻车的细节Bm和Bd在没有前导零的情况下如果用户选的是 2024-06-05拼接出来是2024-6-5SQL Server 能识别但如果你用CONVERT(char(19), shijian, 20)去格式化时间字段那2024-6-5和2024-06-05的字符串在同一张表里会出现两种格式后边排序和匹配都会乱。我一般会在拼接前做一次零填充If Bm 10 Then Bm 0 Bm If Bd 10 Then Bd 0 Bd同理处理 EndDate。这段代码放在最前面后面所有 SQL 都基于统一的日期格式能少很多排查时间。4.2 两条 SQL 的配合明细查询与统计查询项目正文里给出了两条 SQL一条是查明细一条是查统计这是非常聪明的设计。明细查询负责把指定时间段内的每条记录都拉出来SELECT CONVERT(char(19), time, 20) AS time, cpu, ram, harddisk FROM report WHERE time BETWEEN 起始时间 AND 结束时间 ORDER BY timeCONVERT(char(19), time, 20)是 SQL Server 的日期格式化方法20 代表yyyy-MM-dd HH:mm:ss这种保留到秒的格式。如果不做这步转换ODBC 驱动返回的日期时间对象在 VBS 里赋值给 MSFlexGrid 时会产生一串乱的序列号绝对不能用。统计查询负责算聚合值SELECT AVG(cpu) AS ylp, AVG(ram) AS wdp, AVG(harddisk) AS llp, MIN(cpu) AS ylx, MIN(ram) AS wdx, MIN(harddisk) AS llx, MAX(cpu) AS yld, MAX(ram) AS wdd, MAX(harddisk) AS lld FROM report WHERE time BETWEEN 起始时间 AND 结束时间聚合查询的结果只有一行访问方式和明细不同明细用oRs.Fields(0).Value按列号取聚合用oRs1(ylp)按别名取。项目正文里的代码就是这么干的顺序读取聚合结果列名时手别抖写错一个别名就会报“列名无效”。4.3 ADODB 组件组合方式Recordset、Command、Connection 的角色分配Set conn CreateObject(ADODB.Connection) conn.ConnectionString strcn conn.CursorLocation 3 adUseClient conn.Open Set oRs CreateObject(ADODB.Recordset) Set oCom CreateObject(ADODB.Command) oCom.CommandType 1 adCmdText Set oCom.ActiveConnection conn oCom.CommandText Sql Set oRs oCom.ExecuteCursorLocation 3是关键它让客户端来缓存记录集这样oRs.RecordCount才不是 -1。如果用服务器端游标RecordCount 在仅前向游标下会返回 -1后续oRs.RecordCount参与的行数计算全错。CommandType1代表adCmdText表示 CommandText 属性里的内容是纯 SQL 文本。这里可以不建 Command 对象直接用conn.Execute(Sql)但 Command 能复用连接遇到连续跑查询和聚合的情况性能更好。4.4 MSFlexGrid 填值合并单元格、表头、统计行不再错位MSFlexGrid 填值前要清空旧数据并重置行列MSFlexGrid1.Clear MSFlexGrid1.rows oRs.RecordCount 6 MSFlexGrid1.ColWidth(0) 900 MSFlexGrid1.ColWidth(1) 1900 MSFlexGrid1.ColWidth(2) 1000 MSFlexGrid1.ColWidth(3) 1000 MSFlexGrid1.ColWidth(4) 1100 表头合并 MSFlexGrid1.row 0 For z 0 To 4 MSFlexGrid1.col z MSFlexGrid1.text Computer Utilization Message(per Day) Next MSFlexGrid1.MergeCells 4 MSFlexGrid1.MergeRow(0) Truerows oRs.RecordCount 6的意思是明细数据从第二行开始填加上表头占一行、空行留一行、统计占 MAX/MIN/AVG 三行总共多留 6 行。如果RecordCount为 0rows会被设成 6画面还能正常显示统计行不会瘫掉。填数据时我建议用TextMatrix属性它比先row i再col j再text 值更直观For i 1 To oRs.RecordCount MSFlexGrid1.TextMatrix(i1, 0) i Next这段先把序号列填好然后在Do While Not oRs.EOF循环里按行填其余列。项目正文里的代码有一个亮点判断起始日期和结束日期是否在同一天如果是时间列只显示Mid(t,11,16)即HH:mm:ss如果不是显示完整日期时间。这个细节在日报表场景下非常实用——同一天的报表表头已经写了日期每行再带日期就是视觉噪音。4.5 打印脚本从 MSFlexGrid 到 Excel 的格点搬运Set ExcelApp CreateObject(Excel.Application) Set ExcelBook ExcelApp.Workbooks.Add Set ExcelSheet ExcelBook.Worksheets(1) ExcelApp.Visible True For irow 0 To MSFlexGrid1.Rows - 1 For ICOL 0 To MSFlexGrid1.Cols - 1 z MSFlexGrid1.Rows ExcelSheet.Cells(irow 1, icol 1) Trim(MSFlexGrid1.TextMatrix(irow, ICOL)) Next Next这里ExcelSheet.Cells(irow 1, icol 1)的偏移是因为 Excel 从第 1 行第 1 列开始MSFlexGrid 从第 0 行第 0 列开始。Trim去掉 MSFlexGrid 里可能存在的空格防止 Excel 里出现“看起来一样但就是匹配不上”的单元格。打印部分项目正文里用了ExcelSheet.printpreview这是打印预览。第一次调试建议保留预览确认格式没问题再放开注释掉的ExcelSheet.PrintOut。边框设置那几行Borders(1)到Borders(4)分别对应上下左右四边1 代表底边、2 代表顶边、3 代表左边、4 代表右边——这是 Excel 对象模型的枚举值别记混。5. WINCC SQL 报表避坑记录五条血泪经验逐个说这个方案我用过不止一次每次换电脑换系统版本都会冒出新问题。把踩过的坑整理成五条按“现象 → 原因 → 解决”的顺序写能帮你省至少两天的调试时间。5.1 控件添加了但画面上不显示现象从 ActiveX Controls 列表选了 MSFlexGrid画面上却是一片空白运行时也看不见。原因OCX 控件注册不完整或者控件依赖的 DLL如 MSVBVM60.DLL缺失控件对象在图形编辑器里能添加但显示时被 WinCC 运行时引擎跳过。解决检查系统里是否存在MSVBVM60.DLL没有就装 Visual Basic 6 运行时库。再用regsvr32 /u解除 MSFLXGRD.OCX 注册重新regsvr32注册一次。修改注册后要完全关闭 WINCC 图形编辑器再重新打开光刷新不行。5.2 查询时报“未找到提供程序”现象点查询按钮后弹窗报Provider could not be found数据库连接根本没建立。原因连接字符串里写ProviderSQLOLEDB.1但系统缺少 SQL Server OLEDB 驱动程序。尤其是精简版 Windows 或阉割版工控系统OLE DB 组件可能被裁掉了。解决优先在系统里装 Microsoft SQL Server Native Client。如果装不了把连接字符串改成ProviderSQLNCLI11或SQLNCLI10版本号在“已安装的程序”里能看到。改完 Provider 后重启 WINCC 图形运行系统脚本里的 Connection 对象才用得上新驱动。5.3 查询结果统计行全跑到同一行去了现象MSFlexGrid 底部 MAX、MIN、AVG 三行数据挤在同一行显示或者像被覆盖了。原因TextMatrix(oRs.RecordCount 3, 0)的写法在oRs.RecordCount变化后没有同步更新rows属性。比如先执行一次查询返回 50 条记录再查 30 条RecordCount变小但rows还是 56表格底部统计行错位。解决每次点击查询时在填值前强制重置rows和colsMSFlexGrid1.rows 1 MSFlexGrid1.cols 5 MSFlexGrid1.Clear MSFlexGrid1.rows oRs.RecordCount 6这段先缩到最小值再扩展能彻底清除上一次查询残留的行列数据。5.4 导出 Excel 后边框线部分丢失现象打印脚本跑完Excel 打开表格看到数据但边框线只有部分行有标题字体也没变粗。原因ExcelSheet.Range(A1:E z).Borders(1).Weight 2循环只设置了四条边没有设置内部边框。实际打印预览时内部横线纵线缺了很多。解决用无参方式的 Borders 一次性设置全部边框ExcelSheet.Range(A1:E z).Borders.Weight 2Borders不带参数时代表所有边框单元.Weight 2设为细实线设置后所有单元格四个方向的线全有了。5.5 SQL 查询时快时慢数据量大时报表要卡几秒现象查询几百条记录没问题但查一个月的数据时画面卡住转圈十秒以上。原因BETWEEN条件里的字段没建索引SQL Server 走全表扫描。ORDER BY time又触发一次排序。WinCC 那台工控机如果是机械硬盘性能更差。解决在 SQL Server Management Studio 里对report表建复合索引SQL 语句如下CREATE INDEX idx_report_time ON report(time);如果查询条件经常用WHERE time BETWEEN …单独在time列建索引就够了。索引会占磁盘空间但报表表撑死了几十万行建索引的收益远大于空间开销。6. 进阶把报表从“能用”做到“好用”的三点习惯6.1 数据不足时的容错提示别让操作员面对空白表格发懵If n 0 Then MsgBox 对不起,没有找到符合条件的数据, vbOK, 没有相关数据 End If这段判断n0时弹窗提示让用户知道是没数据不是查询按钮坏了。我建议把它提到oRs.Requery之后、开始填表格之前执行。如果放在最后前面所有填值操作白做了界面已经动态画了一遍空行体验不好。同时日期合法性校验要放在构造 SQL 之前。项目正文里有判断“起始日期大于结束日期”的逻辑If By Ny Or By Ny And Bm Nm Or By Ny And Bm Nm And Bd Nd Then MsgBox 输入的时间不正确, vbOK, 错误的起始时间 Exit Sub End IfExit Sub必须有否则用户选了非法日期后程序继续往下走拼出来的BeginDate EndDate会导致 SQL 返回空结果白查一遍。6.2 脚本运行效率一次连接多次执行别反复开关查询按钮的脚本里有一个可以马上实现的优化点。当前写法是建一个oCom执行明细查询建第二个oCom1执行聚合查询但两者共用同一个conn这比每次新建 Connection 再打开连接高效得多。顶部那句conn.CursorLocation 3也别删虽然这段代码看起来只是“往下哪都没用到游标位置”实际上oRs.RecordCount的值和它直接相关。把这一行删掉统计行数量全乱这是最容易误删却最难定位的一次事故。6.3 验证整套流程的半小时检查法每次改完脚本我习惯按这个顺序走一遍检查 WINCC 变量cpu、ram、hd在变量管理器中存在并且类型为浮点数类型不对会导致HMIRuntime.Tags(cpu).Read返回字符串拼进 SQL 后数据库会因类型转换失败而拒收。在 SQL Server Management Studio 里手动执行一次完整查询 SQL确认能返回预期行数。这一步能排除 SQL 语法问题。用 VBS 编辑器单独做一个测试脚本不经过 WINCC 直接连数据库查验证 ADODB 连接字符串和查询语句在当前机器上都正常。最后才从 WINCC 画面点查询按钮看 MSFlexGrid 表头、明细行、统计行是否都对。第三项检查是我从某一次被 WINCC 全局脚本缓存坑过之后养成的强制动作。全局脚本在编辑器里保存后实时运行时没重新加载我改的脚本根本没生效还以为是 SQL 的问题。从那时起我每次改脚本都在运行时监控里看一眼脚本执行记录确认“重新加载脚本”操作确实执行了才点下最终的测试按钮。希望这篇拆解能帮你在 WINCC 报表这条路上少走几步弯路。本文还有配套的精品资源点击获取

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号