news 2026/10/9 17:19:50

博图WinCC V16中ADODB与DataGrid实现SQL Server数据画面展示

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
博图WinCC V16中ADODB与DataGrid实现SQL Server数据画面展示

简介:这份文档面向工业自动化领域的博图WinCC V16使用者,尤其是需要在HMI画面上实时展示SQL Server数据的工程师与调试人员。内容围绕ADODB组件与DataGrid控件的配合展开,给出可直接参考的VB脚本示例,解决WinCC与数据库交互时数据无法呈现的常见难题。资源包为1个docx文件,约32KB,属于轻量级技术文档,便于快速查阅与复制代码。目前已有3693人学习下载,说明该方案在同类场景中具有较高参考价值。读者可从中获取完整的连接字符串配置思路、Recordset游标设置方法、DataGrid数据源绑定与刷新逻辑,以及连接关闭与对象清理的注意事项,同时能了解表名、字段名需按实际数据库结构调整的排错方向,适合作为WinCC数据库显示功能的入门与调试参考。

1. 博图WinCC V16 里把 SQL Server 数据搬上画面:ADODB 加 DataGrid 到底能解决什么问题

很多做产线监控的同行都遇到过这个场景:配方参数、批次记录、报警历史这些数据,现场操作工希望在 WinCC 画面上直接翻页查看,而不是跑到办公室开 SQL 客户端。博图 WinCC V16 自带的控件体系里,表格展示一直是个短板——要么用 ActiveX 控件凑合,要么自己写 VBS 脚本拼字符串。ADODB 加 DataGrid 这套组合,本质上是借 Windows 系统自带的数据库访问组件,把 SQL Server 里的结果集直接绑定到画面控件上,省去中间层。

这个方案适合谁?适合已经用 WinCC V16 做上位机、后台有独立 SQL Server 数据库、需要在不额外买选件的前提下实现数据查询展示的工程师。它不需要 .NET 开发环境,不需要装第三方报表工具,靠 VBS 脚本就能跑通。但要注意,这条路有它的边界——DataGrid 控件本身是 MSFlexGrid 或类似 ActiveX 的封装,样式定制能力有限,大数据量分页得自己处理。下面我把从环境准备到脚本落地的完整路径拆开讲。

2. 环境准备与控件注册:为什么你的 DataGrid 拖不出来

2.1 WinCC V16 的 ActiveX 控件容器机制

WinCC 画面里的控件分两类:一类是西门子自己的 WinCC 控件,另一类是 ActiveX 控件。DataGrid 属于后者,它不在 WinCC 默认控件面板里,需要手动注册。很多新手在控件面板里翻半天找不到 DataGrid,以为要装什么插件,其实系统里早就有了MSDATGRD.OCX,只是没注册到 WinCC 的控件列表里。

WinCC V16 用的是 32 位控件容器,哪怕你的操作系统是 64 位,注册控件时也要用 32 位的regsvr32。这一点是血泪经验——用 64 位的注册命令跑一遍,提示成功,但 WinCC 里就是看不到控件。原因是 WinCC 的图形编辑器进程是 32 位的,它只认SysWOW64目录下的注册信息。

注册命令如下:

:: 以管理员身份运行 CMD,注册 32 位 DataGrid 控件 cd C:\Windows\SysWOW64 regsvr32 MSDATGRD.OCX

执行后会弹出一个成功提示框。如果提示“模块加载失败”,检查文件是否存在于C:\Windows\SysWOW64\目录下。部分精简版系统会缺失这个文件,可以从完整的 Windows 安装镜像里提取。

注册完成后,在 WinCC 图形编辑器的控件面板里右键选择“添加/删除控件”,在 ActiveX 列表里找到“Microsoft DataGrid Control 6.0 (SP6)”,勾选后就能拖到画面上了。

2.2 ADODB 组件的版本选择与引用方式

ADODB 是 Windows 自带的数据库访问组件,不需要额外安装。在 VBS 脚本里引用它有两种方式:早期绑定和后期绑定。早期绑定需要先在脚本环境里添加引用,WinCC 的 VBS 编辑器不支持引用管理界面,所以只能用后期绑定——也就是用CreateObject动态创建。

' 后期绑定创建 ADODB.Connection 对象 Dim conn Set conn = CreateObject("ADODB.Connection")

后期绑定的好处是不依赖具体的类型库版本,兼容性更好。缺点是 IDE 里没有智能提示,属性名拼错了要运行时才发现。我一般会在脚本开头把常用的对象都创建好,后面直接调用。

连接字符串是另一个关键点。SQL Server 的连接方式有好几种,WinCC 运行在工控机上,通常和数据库服务器在同一个局域网内。推荐用 SQL Server 原生客户端方式,不要用 ODBC 数据源——ODBC 数据源在 WinCC 服务模式下运行时经常读不到用户 DSN。

' 拼接 SQL Server 连接字符串 Dim connStr connStr = "Provider=SQLOLEDB.1;" & _ "Data Source=192.168.1.100;" & _ "Initial Catalog=PlantDB;" & _ "User ID=wincc_user;" & _ "Password=Abc12345;" & _ "Connect Timeout=10;"

参数说明:Data Source填 IP 加端口,默认 1433 可以省略端口;Initial Catalog是数据库名;User ID和Password建议用 SQL Server 身份验证,不要用 Windows 集成验证——WinCC 服务账户不一定有数据库访问权限。Connect Timeout设 10 秒,避免网络抖动时画面卡死。

3. 用 VBS 脚本打通 ADODB 到 DataGrid 的数据链路

3.1 查询逻辑与记录集获取

数据链路的核心是三步:建立连接、执行查询、把记录集绑定到 DataGrid。听起来简单,但每一步都有坑。先说查询,WinCC 画面上的查询通常带条件,比如按批次号筛选、按时间范围筛选。条件值来自画面上的输入框控件。

' 从画面控件读取查询条件 Dim batchNo batchNo = ScreenItems("txtBatchNo").Text ' 构建参数化查询,避免 SQL 注入 Dim cmd Set cmd = CreateObject("ADODB.Command") cmd.ActiveConnection = conn cmd.CommandText = "SELECT BatchNo, ProductName, Weight, CreateTime FROM ProductionLog WHERE BatchNo LIKE ?" cmd.Parameters.Append cmd.CreateParameter("batch", 200, 1, 50, batchNo & "%") ' 执行查询,获取记录集 Dim rs Set rs = cmd.Execute

这里用ADODB.Command而不是直接拼 SQL 字符串,是为了防止操作工在输入框里敲单引号导致脚本报错。CreateParameter的第二个参数 200 表示变长字符串,第三个参数 1 表示输入参数,第四个参数是最大长度。这些常量值在 VBS 里没有内置定义,得直接写数字。

记录集拿到后,不能直接往 DataGrid 上绑。WinCC 的 DataGrid 控件对 ADODB.Recordset 的支持有限,直接赋值Set DataGrid1.DataSource = rs在部分版本上会报“类型不匹配”。稳妥的做法是先断开记录集连接,再绑定。

' 断开记录集与数据库的连接,转为离线模式 Set rs.ActiveConnection = Nothing ' 绑定到 DataGrid 控件 ScreenItems("dgLog").DataSource = rs

3.2 DataGrid 控件的列宽与表头定制

绑定完成后,DataGrid 默认显示的是数据库字段名,操作工看不懂。需要在画面加载或查询完成后手动设置列标题和列宽。

' 设置 DataGrid 列标题和宽度 Dim grid Set grid = ScreenItems("dgLog") grid.Columns(0).Caption = "批次号" grid.Columns(0).Width = 1200 grid.Columns(1).Caption = "产品名称" grid.Columns(1).Width = 1500 grid.Columns(2).Caption = "重量(kg)" grid.Columns(2).Width = 800 grid.Columns(3).Caption = "生产时间" grid.Columns(3).Width = 1800

列宽的单位是缇(twip),1 磅约等于 20 缇。这个数值需要根据画面分辨率调整,没有万能值。我一般先在画面上目测,然后微调。注意Columns的索引从 0 开始,顺序和 SQL 语句里的 SELECT 字段顺序一致。

如果查询返回的字段数量不固定,比如动态拼接的 SQL,那就得先遍历记录集的 Fields 集合来设置列标题。这种做法灵活性高,但代码量会翻倍,一般用在通用查询画面上。

3.3 分页加载与大数据量优化

DataGrid 绑定全量记录集时,如果数据超过几千行,画面会明显卡顿。WinCC 的画面刷新周期通常是 250ms 到 1s,大数据量绑定会拖慢整个画面的响应。解决办法是分页查询,每次只取一页数据。

' 分页查询:每页 50 条,查询第 pageIndex 页 Dim pageSize, pageIndex, startRow pageSize = 50 pageIndex = CInt(ScreenItems("txtPage").Text) startRow = (pageIndex - 1) * pageSize ' 用 ROW_NUMBER() 实现分页 Dim sql sql = "SELECT * FROM (" & _ "SELECT ROW_NUMBER() OVER (ORDER BY CreateTime DESC) AS RowNum, " & _ "BatchNo, ProductName, Weight, CreateTime " & _ "FROM ProductionLog WHERE BatchNo LIKE ?" & _ ") AS T WHERE RowNum BETWEEN ? AND ?" cmd.CommandText = sql cmd.Parameters.Append cmd.CreateParameter("batch", 200, 1, 50, batchNo & "%") cmd.Parameters.Append cmd.CreateParameter("start", 3, 1, , startRow + 1) cmd.Parameters.Append cmd.CreateParameter("end", 3, 1, , startRow + pageSize)

ROW_NUMBER()是 SQL Server 2005 以后都支持的开窗函数,用它做分页比TOP加NOT IN效率高得多。参数类型 3 表示整数。分页大小设 50 是经验值——太小了翻页频繁,太大了绑定慢。如果单页数据超过 200 行,建议降到 30 行一页。

翻页按钮的脚本就是修改txtPage的值,然后重新触发查询。注意翻页时要先清空 DataGrid 的 DataSource,否则旧数据会残留。

' 翻页前清空 DataGrid ScreenItems("dgLog").DataSource = Nothing ' 更新页码后重新查询 ScreenItems("txtPage").Text = CStr(pageIndex + 1) ' 调用查询子过程 Call RefreshData()

4. 避坑与排查:ADODB 加 DataGrid 在 WinCC 里最容易翻车的五个点

4.1 连接字符串写对了但提示“未找到数据源”

现象:脚本运行到conn.Open时报错,错误信息是“未找到数据源名称且未指定默认驱动程序”。原因通常是连接字符串里用了DSN方式,但 WinCC 服务账户读不到用户 DSN。解决方法是改用Provider=SQLOLEDB.1的无 DSN 连接方式,把服务器地址、数据库名、账号密码全部写在连接字符串里。如果必须用 DSN,要创建系统 DSN 而不是用户 DSN。

4.2 DataGrid 绑定后画面切换回来数据消失

现象:在画面 A 查询出数据,切到画面 B 再切回来,DataGrid 空了。原因是 WinCC 画面切换时会销毁画面对象的实例,DataGrid 的 DataSource 绑定关系随之丢失。解决办法是在画面的“显示”事件里重新执行查询,或者把记录集存到全局脚本的变量里,画面加载时重新绑定。我一般用后者,把 Recordset 对象存在 WinCC 的内部变量里,虽然不太规范,但省事。

4.3 查询返回中文乱码

现象:数据库里存的是中文,DataGrid 显示成问号或方块。原因是 ADODB 默认用 Unicode 读取,但 DataGrid 控件的字体不支持中文,或者连接字符串里没指定字符集。解决办法是在连接字符串末尾加;CharacterSet=utf8;,同时把 DataGrid 的字体设为“宋体”或“微软雅黑”。如果数据库字段是nvarchar类型,一般不会有问题;如果是varchar且排序规则不是中文,那就得在 SQL 里用COLLATE转换。

4.4 脚本执行到一半卡死,画面无响应

现象:点击查询按钮后,画面卡住十几秒,然后弹出超时错误。原因是数据库连接超时或查询本身太慢。WinCC 的 VBS 脚本是单线程执行的,脚本不返回,画面就不刷新。解决办法是设Connect Timeout=5和Command Timeout=10,同时在查询前加一个“正在加载”的提示标签,让操作工知道系统没死。如果查询确实需要几十秒,建议改成异步方式——用 WinCC 的 C 脚本起一个后台线程,但那就复杂了。

4.5 多用户同时查询时数据库连接数暴涨

现象:产线上三台 WinCC 客户端同时查询,SQL Server 的会话数直接冲到几十个。原因是每个查询都新建一个 ADODB.Connection,用完没有关闭。解决办法是在脚本末尾显式关闭连接和记录集。

' 脚本结束前释放资源 If Not rs Is Nothing Then If rs.State = 1 Then rs.Close Set rs = Nothing End If If Not conn Is Nothing Then If conn.State = 1 Then conn.Close Set conn = Nothing End If

State属性为 1 表示对象已打开。这段代码要放在错误处理块里,确保即使查询出错也能释放连接。更优雅的做法是用连接池,但 WinCC 的 VBS 环境不支持连接池配置,只能靠及时关闭来缓解。

5. 进阶技巧:让 DataGrid 查询更快、更稳、更好用

5.1 用存储过程替代内联 SQL

当查询逻辑复杂到需要多表关联加聚合时,内联 SQL 字符串会变得又长又难维护。更好的做法是把查询逻辑封装到 SQL Server 的存储过程里,WinCC 这边只负责传参和取结果。

-- 在 SQL Server 里创建存储过程 CREATE PROCEDURE GetProductionLog @BatchNo NVARCHAR(50), @PageIndex INT, @PageSize INT AS BEGIN DECLARE @StartRow INT SET @StartRow = (@PageIndex - 1) * @PageSize SELECT BatchNo, ProductName, Weight, CreateTime FROM ( SELECT ROW_NUMBER() OVER (ORDER BY CreateTime DESC) AS RowNum, * FROM ProductionLog WHERE BatchNo LIKE @BatchNo + '%' ) AS T WHERE RowNum BETWEEN @StartRow + 1 AND @StartRow + @PageSize END

WinCC 这边调用时,把CommandType设为 4(表示存储过程),然后传参。

cmd.CommandType = 4 cmd.CommandText = "GetProductionLog" cmd.Parameters.Append cmd.CreateParameter("BatchNo", 200, 1, 50, batchNo & "%") cmd.Parameters.Append cmd.CreateParameter("PageIndex", 3, 1, , pageIndex) cmd.Parameters.Append cmd.CreateParameter("PageSize", 3, 1, , pageSize)

存储过程的好处是执行计划可以缓存,重复查询时 SQL Server 不需要重新编译。对于产线上高频查询的画面,响应时间能从几百毫秒降到几十毫秒。

5.2 把查询结果缓存到 WinCC 内部变量

如果同一个查询结果在多个画面上都要用,每次都查数据库就浪费了。可以把记录集的关键字段存到 WinCC 的内部变量数组里,画面直接从变量读。

' 把记录集写入 WinCC 内部变量 Dim i i = 0 Do While Not rs.EOF HMIRuntime.Tags("Cache_BatchNo_" & i).Write rs.Fields("BatchNo").Value HMIRuntime.Tags("Cache_ProductName_" & i).Write rs.Fields("ProductName").Value rs.MoveNext i = i + 1 Loop

这种做法的代价是要预先在 WinCC 变量管理器里建好足够多的变量,而且变量数量有上限。我一般只缓存最近一页的数据,翻页时重新查询。缓存的有效期也要控制,比如 30 秒后自动失效,避免操作工看到过期数据。

5.3 用 DataGrid 的点击事件做联动查询

DataGrid 控件支持Click事件,可以在 VBS 里绑定事件处理脚本。操作工点击某一行时,自动带出该批次的详细信息。

' DataGrid 的 Click 事件处理 Sub dgLog_Click() Dim row row = ScreenItems("dgLog").Row If row >= 0 Then Dim batchNo batchNo = ScreenItems("dgLog").Columns(0).Value ' 用批次号查询明细并显示到另一个控件 ScreenItems("txtDetail").Text = GetBatchDetail(batchNo) End If End Sub

Row属性返回当前选中行的索引,从 0 开始。Columns(0).Value取第一列的值。这个联动逻辑在配方管理画面上特别实用——左边表格列出所有配方,点击某一行,右边显示该配方的详细参数。

5.4 验证方法:怎么确认数据链路真的通了

写完脚本别急着上产线,先在 WinCC 的脚本调试器里跑一遍。WinCC V16 的图形编辑器有“调试”功能,可以在脚本里打断点,看变量值。我一般会在关键节点加HMIRuntime.Trace输出。

HMIRuntime.Trace "连接字符串: " & connStr & vbCrLf HMIRuntime.Trace "查询条件: " & batchNo & vbCrLf HMIRuntime.Trace "记录集行数: " & rs.RecordCount & vbCrLf

Trace 信息会输出到 WinCC 的诊断窗口里。如果RecordCount返回 -1,说明记录集的游标类型不支持计数,需要在打开记录集时指定CursorType=3(静态游标)。这个细节在 ADODB 文档里写得很清楚,但实际写脚本时经常忘。

最后说一个我自己的习惯:每次改完脚本,先在测试画面上跑一遍全流程——连接、查询、绑定、翻页、关闭——确认没有内存泄漏再部署到产线画面。WinCC 的 VBS 脚本没有垃圾回收机制,忘记释放对象的话,跑上几天内存就满了,画面会越来越卡。这个坑我踩过不止一次,希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/9 17:17:00

全类目加属性SQL:三表模型与行转列宽表实战

简介:一份包含淘宝全量类目、属性及属性值的SQL数据文件,主要面向电商后台开发、数据分析以及数据库学习者,可用于还原淘宝类目树结构、梳理属性与属性值的枚举关系,也为商品筛选、竞品分析或推荐系统原型提供真实数据支撑。压缩包…

作者头像 李华
网站建设 2026/10/9 17:15:59

C# WinForms文件夹目录结构对比工具:备份校验与同步检查实践

简介:面向IT开发与运维人员的文件夹目录结构对比工具,适用于版本控制、备份恢复、目录同步等场景,快速核对两个文件夹的内容是否一致。不同于基于MD5的完整校验,它递归遍历文件系统,比较文件大小、修改时间和创建时间等…

作者头像 李华
网站建设 2026/10/9 17:13:56

JS实现window.open弹窗屏幕居中:坐标计算与多屏适配详解

简介:这是一份面向Web前端初学者的JavaScript工具脚本,专门解决新窗口弹出后默认位置不固定、影响操作体验的问题。资源以PDF格式收录了完整的MM_openBrWindow函数源码,通过screen.width与screen.height计算居中坐标,并兼容Netsca…

作者头像 李华
网站建设 2026/10/9 17:13:34

PCA9422与PIC18F4525电池供电方案:PMIC+MCU电源管理设计详解

去年做一款便携式环境监测记录仪时,最让我花心思的不是传感器算法,而是电源管理。电池供电的设备,既要保证充电安全,又要给不同模块提供多路稳定电压,还要在待机时把整机功耗压到最低,最后我定了 PCA9422 …

作者头像 李华
网站建设 2026/10/9 17:11:57

遗传算法优化LSTM超参数,股市预测自动化调参实战

简介:这份资源是Python基于遗传算法优化LSTM模型的股市预测完整项目,适合需要完成毕业设计、期末大作业或课程设计的Python学习者,也适合对量化交易与时间序列预测感兴趣的开发者。资源内含源代码、训练好的模型和配套数据集,代码…

作者头像 李华