ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

WinCC V16 ADODB+DataGrid直连SQL Server工业落地指南

WinCC V16 ADODB+DataGrid直连SQL Server工业落地指南 简介本资源是一份面向工业自动化工程师与WinCC开发者的实战技术文档聚焦博图TIA Portal WinCC V16环境下通过ADODB组件直连SQL Server并结合DataGrid控件实现数据库表格数据动态展示的完整方案。文档详细解析VB脚本编写逻辑、连接字符串配置要点、Recordset游标设置、DataGrid数据绑定与刷新机制并附带可直接复用的查询按钮脚本及运行效果说明有效解决WinCC中SQL数据可视化这一高频难点。资源为单文件Word文档.docx共1个文件大小仅32KB内容精炼、即开即用适合快速查阅与工程落地参考。目前已有3689人学习下载涵盖从连接配置、字段映射到界面刷新的全流程关键代码与排错提示特别适合作为HMI开发中的SQL集成速查手册与二次开发基础模板。1. 博图 WinCC V16 用 ADODB DataGrid 直连 SQL Server不是“能连上就行”而是“连得稳、刷得快、改得准”的工业级数据看板落地实操你在 WinCC 画面里拖一个 DataGrid填几行 VBScript 脚本点仿真——结果空表、报错“ActiveX 组件不能创建对象”、或者数据刷出来但一动就卡死、修改后点保存直接崩画面……这不是玄学是博途 V16 下 ADODBDataGrid 这套组合拳没打对节奏。这份.docx文档不是泛泛讲“怎么连数据库”它是一线工程师在产线 HMI 上反复压测三个月后把 ADODB 连接字符串的字符集陷阱、DataGrid 列绑定时的字段类型强转规则、SQL 查询语句中datetime2与smalldatetime的隐式转换坑、以及 WinCC Runtime 中 VBScript 引擎对Recordset.Fields.Item(i).Value的内存释放机制全拆开揉碎写进文档里的血泪经验。它适合正在用博途 V16 做 MES 数据看板、设备参数下发、历史报警查询的现场工程师——你不需要从零学 SQL 或 COM 编程但必须知道为什么ProviderSQLOLEDB.1在 V16 下比ProviderSQLNCLI11.1更稳为什么 DataGrid 的ColumnHeaders属性设成True反而让列宽自适应失效为什么rs.MoveFirst在 WinCC 里调用一次就可能引发 Runtime 崩溃这篇笔记就是帮你绕过这些黑匣子把 SQL Server 数据真正“钉”在 WinCC 画面上。2. ADODB 连接层从连接字符串到 Recordset 实例化的四步闭环ADODB 不是 WinCC 内置功能它是 Windows 系统级 COM 组件WinCC V16 通过 VBScript 调用其接口。关键不在于“能不能连”而在于“连得是否可维护、可诊断、可复用”。下面这四步是我现在每次新建数据控件前必写的模板骨架少一步都可能埋下半夜被电话叫醒的隐患。2.1 连接字符串Provider、Server、Database、UID、PWD 的硬编码陷阱与安全替代方案WinCC V16 的 VBScript 不支持环境变量或配置文件读取但硬写密码在.docx或脚本里是重大风险。这份文档给出的解法是用 Windows 凭据管理器Credential Manager存储 SQL 登录凭据VBScript 通过WScript.Network获取当前用户 SID再调用cmdkey /generic:SQL_CRED /show提取加密凭据——但这在 WinCC Runtime 下权限受限实际更可靠的做法是 推荐写法使用集成 Windows 身份验证 应用程序角色 Dim connStr connStr ProviderSQLOLEDB.1; _ Data Source192.168.1.100; _ Initial CatalogHMI_Data; _ Integrated SecuritySSPI; _ Application NameWinCC_V16_HMI; _ Connection Timeout15;提示ProviderSQLOLEDB.1是 V16 兼容性最稳的选择SQLNCLI11.1SQL Native Client虽支持新特性但在 WinCC Runtime 的 VBScript 引擎中偶发内存泄漏OLE DB Driver for SQL Server (MSOLEDBSQL)则完全不兼容。Application Name参数至关重要——它让 SQL Server Profiler 能精准过滤出 WinCC 发起的会话排查慢查询时省去 80% 时间。2.2 Connection 对象创建与错误捕获别让“对象未设置”毁掉整个画面WinCC 的 VBScript 引擎对 COM 对象异常处理极弱On Error Resume Next是双刃剑。文档强调必须在Set conn CreateObject(ADODB.Connection)后立即检查conn.State且conn.Open后必须用If Err.Number 0 Then捕获而非依赖Err.Description字符串匹配On Error Resume Next Set conn CreateObject(ADODB.Connection) If Err.Number 0 Then MsgBox ADODB.Connection 创建失败 Err.Description (错误号 Err.Number ) Exit Sub End If Err.Clear conn.Open connStr If Err.Number 0 Then MsgBox 数据库连接失败 Err.Description vbCrLf _ 请检查1. SQL Server 是否运行2. 防火墙是否放行 1433 端口3. 登录账户是否有 HMI_Data 数据库的 db_datareader 权限 Set conn Nothing Exit Sub End If On Error GoTo 0 关键恢复严格错误模式参数说明On Error GoTo 0必须在连接成功后立即执行。WinCC Runtime 的 VBScript 引擎若长期处于Resume Next模式后续脚本中任何语法错误都会静默跳过导致 DataGrid 绑定逻辑彻底失效却无任何报错——这是产线最常翻车的场景之一。2.3 Recordset 构建Command 对象封装查询 vs 直接 Open哪种更适合 WinCC文档对比了两种主流写法直连rs.Open sql, conn简单但无法复用 Command 对象参数化查询难实现SQL 注入风险高用Command对象封装多两行代码但支持Parameters.Append且Command.Execute返回的 Recordset 自带字段元数据对 DataGrid 列绑定极其友好。Dim cmd, rs Set cmd CreateObject(ADODB.Command) Set cmd.ActiveConnection conn cmd.CommandText SELECT TOP 100 ID, MachineID, AlarmCode, AlarmTime, Status FROM dbo.AlarmLog WHERE Status ? ORDER BY AlarmTime DESC cmd.Parameters.Append cmd.CreateParameter(Status, 200, 1, 50, Active) adVarChar, adParamInput Set rs cmd.Execute If rs.EOF Then MsgBox 未查到活动报警数据 Set rs Nothing Exit Sub End If逻辑说明adVarChar200对应 SQL Server 的varchar类型adParamInput1表示输入参数cmd.Parameters.Append的顺序必须与 SQL 中?占位符顺序严格一致。WinCC V16 的 VBScript 对adInteger3、adBoolean11等类型映射稳定但adDate7易因区域设置导致解析失败文档建议一律用adVarChar传日期字符串SQL 侧用CONVERT(datetime, ?, 120)转换。2.4 Recordset 生命周期管理为什么rs.Close和Set rs Nothing缺一不可WinCC Runtime 的内存回收机制对 ADODB 对象不友好。文档实测发现仅rs.Close不释放底层 COM 引用连续刷新 10 次后 Runtime 内存占用飙升 300MB仅Set rs Nothing不关闭游标下次cmd.Execute会报“游标已关闭”。必须成对出现 正确释放顺序缺一不可 If Not rs Is Nothing Then If rs.State 1 Then rs.Close adStateOpen 1 Set rs Nothing End If If Not cmd Is Nothing Then Set cmd Nothing If Not conn Is Nothing Then If conn.State 1 Then conn.Close Set conn Nothing End If避坑重点rs.State 1是唯一可靠的判断依据rs.EOF And rs.BOF不能代替rs.State——当 Recordset 为空时rs.State仍为 1打开状态但rs.EOF为 True。这个细节在文档第 3 页有截图验证。3. DataGrid 控件绑定从字段映射到实时刷新的七处硬核配置DataGrid 是 WinCC V16 中唯一原生支持双向绑定的 ActiveX 控件但它不是“拖进去就能用”。文档花了 12 页详述其属性矩阵核心是列定义Columns、数据源DataSource、编辑行为AllowUpdate、刷新触发Refresh三者必须协同否则要么数据不动要么改完就丢。3.1 Columns 集合预定义为什么必须手动 Add Column 而非依赖 AutoGenerateColumnsWinCC V16 的 DataGridAutoGenerateColumnsTrue会将所有 Recordset 字段转为字符串显示丢失数值精度、日期格式、布尔值图标。文档强制要求每列必须用Columns.Add显式声明且DataType必须与 SQL 字段类型严格匹配 清空原有列重新构建 DataGrid1.Columns.Clear 第1列ID整数右对齐不可编辑 With DataGrid1.Columns.Add .DataField ID .Caption 序号 .DataType 3 adInteger .Alignment 1 dgRight .Locked True End With 第2列AlarmTime日期格式化显示 With DataGrid1.Columns.Add .DataField AlarmTime .Caption 发生时间 .DataType 7 adDate .Format yyyy-mm-dd hh:nn:ss 注意WinCC 中用 nn 代表分钟非 mm月份 .Width 120 End With 第3列Status字符串下拉选择 With DataGrid1.Columns.Add .DataField Status .Caption 状态 .DataType 200 adVarChar .DropDownStyle 2 vbComboDropDownList只读下拉 .ListItems.Add Active .ListItems.Add Cleared .ListItems.Add Acknowledged End With参数说明.DataType 7adDate是 WinCC DataGrid 支持日期格式化的前提.Format中nn是 WinCC 特有语法mm会被识别为月份导致时间显示错乱.DropDownStyle 2确保用户只能从预设项中选择避免脏数据写回数据库。3.2 DataSource 绑定Recordset 的 CursorLocation 与 CursorType 如何决定编辑能力DataGrid 的DataSource属性接受 ADODB.Recordset但并非所有 Recordset 都支持编辑。文档指出必须设置rs.CursorLocation 3adUseClient且rs.CursorType 3adOpenStatic否则AllowUpdateTrue无效双击单元格直接报错“操作不允许”rs.CursorLocation 3 adUseClient客户端游标支持更新 rs.CursorType 3 adOpenStatic静态游标支持书签和定位 rs.LockType 3 adLockOptimistic乐观锁WinCC 最常用 注意adOpenDynamic 在 WinCC 中会导致 DataGrid 刷新异常逻辑说明adUseClient将 Recordset 数据缓存在 WinCC Runtime 内存中使 DataGrid 可离线编辑adOpenStatic确保rs.Bookmark可用这是 DataGrid 定位当前行的基础。若用adOpenForwardOnly0则rs.MoveFirst失效DataGrid 无法响应“首页”按钮。3.3 AllowUpdate 与 EditMode如何让 DataGrid 真正支持“双击修改 回车提交”DataGrid 默认AllowUpdateFalse即使绑定了可更新 Recordset 也无法编辑。文档强调AllowUpdateTrue仅开启编辑入口真正的提交动作需监听BeforeColEdit和AfterColEdit事件并手动调用rs.Update 在 DataGrid 的 BeforeColEdit 事件中画面脚本 Sub DataGrid1_BeforeColEdit(ByVal ColIndex, ByVal Value, Cancel) 可在此校验输入值如 Status 列只允许预设值 If ColIndex 2 Then Status 列索引为20起始 If Value Active And Value Cleared And Value Acknowledged Then MsgBox 状态值非法请从下拉列表选择 Cancel True 阻止编辑 End If End If End Sub 在 DataGrid 的 AfterColEdit 事件中画面脚本 Sub DataGrid1_AfterColEdit(ByVal ColIndex, ByVal Value) 获取当前行 Recordset 位置 Dim bookmark bookmark DataGrid1.DataSource.Bookmark 定位到当前行并更新 DataGrid1.DataSource.Bookmark bookmark DataGrid1.DataSource.Fields(ColIndex).Value Value DataGrid1.DataSource.Update 关键显式提交到 Recordset 注意此处不直接写回 SQL Server需另触发 Save 按钮逻辑 End Sub避坑重点DataGrid1.DataSource.Update只更新 Recordset 内存副本不是写回数据库。文档在第 5 页明确区分了“Recordset 更新”和“SQL 提交”两个阶段避免工程师误以为编辑即生效。3.4 Refresh 与 Requery手动刷新的三种触发时机与性能代价DataGrid 的Refresh方法仅重绘界面不重新查询数据库Requery才会执行rs.Requery并拉新数据。文档列出三种典型场景触发场景推荐方法性能影响适用说明画面首次加载Requery高全量查必须确保初始数据最新用户点击“刷新”按钮Requery高建议加 Loading 提示后台定时轮询如每30秒Refresh极低仅当 Recordset 已被其他脚本更新如通过rs.AddNew插入新报警 定时轮询示例放在画面脚本的 Timer 事件中 Sub Timer1_Timer 检查 Recordset 是否有新数据通过比较行数 Dim currentCount currentCount DataGrid1.DataSource.RecordCount If currentCount lastRecordCount Then DataGrid1.Refresh 仅重绘不查库 lastRecordCount currentCount End If End Sub参数说明lastRecordCount需在画面脚本顶部声明为全局变量。WinCC V16 的 Timer 间隔最小为 100ms但文档实测 500ms 是平衡实时性与 CPU 占用的甜点值。4. 避坑指南ADODBDataGrid 在 WinCC V16 中的五个高频翻车点这份.docx文档最硬核的部分是它用真实产线日志截图Wireshark 抓包SQL Profiler 跟踪还原了五个让工程师连续加班三天的典型问题。以下每条都按“现象→原因→解决”结构展开拒绝模糊描述。4.1 现象DataGrid 显示数据但双击单元格无反应F2 键也不激活编辑原因DataGrid 的Enabled属性为False或ReadOnly属性为True或AllowUpdate未设为True。更隐蔽的是DataSource绑定的 RecordsetLockType为adLockReadOnly1导致控件自动禁用编辑。解决在画面脚本OnPictureActivate事件中强制设置DataGrid1.Enabled True DataGrid1.ReadOnly False DataGrid1.AllowUpdate True 并确认 Recordset 创建时rs.LockType 3 adLockOptimistic4.2 现象SQL Server 中 datetime 字段值为2023-05-20 14:30:00.000DataGrid 显示为2023-05-20秒级精度丢失原因DataGrid 的Format属性未正确设置或 Recordset 字段DataType误设为adVarChar导致自动截断。WinCC V16 对adDate类型的毫秒部分默认舍弃。解决Recordset 字段DataType必须为7adDateDataGrid 列Format设为yyyy-mm-dd hh:nn:ss.000若仍丢失SQL 查询中显式转换CONVERT(varchar(23), AlarmTime, 121) AS AlarmTimeStr并在 DataGrid 中绑定AlarmTimeStr字段DataType200。4.3 现象点击 DataGrid 行时CurrentCellChanged事件不触发无法联动其他控件原因DataGrid 的TabStop属性为False或TabIndex与其他控件冲突导致焦点未落入 DataGrid。WinCC V16 中若 DataGrid 未获得焦点行选择事件不会触发。解决在画面属性中确保 DataGrid 的TabStopTrue在OnPictureActivate中添加DataGrid1.SetFocus检查同一画面中是否存在TabIndex为 0 的按钮/文本框将其TabIndex设为 100 以上避免抢焦点。4.4 现象执行rs.Update后SQL Server 数据库未更新但 Recordset 内存中值已变原因Recordset 的CursorType为adOpenForwardOnly0或adOpenKeyset1这两种游标类型不支持Update方法。adOpenStatic3是唯一保证Update生效的类型。解决创建 Recordset 时严格指定rs.CursorLocation 3 adUseClient rs.CursorType 3 adOpenStatic rs.LockType 3 adLockOptimistic rs.Open sql, conn4.5 现象WinCC Runtime 启动后DataGrid 首次加载慢10秒后续正常原因ADODB 连接池未预热首次CreateObject(ADODB.Connection)触发 COM 组件注册加载且ProviderSQLOLEDB.1在 V16 下首次初始化耗时显著。解决在项目启动画面如 Login 画面的OnPictureActivate中预先创建并立即释放一个测试连接Dim testConn Set testConn CreateObject(ADODB.Connection) testConn.Open ProviderSQLOLEDB.1;Data Sourcelocalhost;Initial Catalogmaster;Integrated SecuritySSPI; testConn.Close Set testConn Nothing 此操作让 ADODB 组件在 Runtime 启动初期完成加载后续画面连接提速 70%5. 生产级加固SQL Server 连接池、DataGrid 列隐藏与跨画面数据同步做到“能连、能显、能改”只是入门产线要求的是“7×24 小时不掉线、列信息不外泄、多画面数据实时一致”。这份文档在最后章节给出了三个经过 12 条产线验证的加固方案不是理论是抄了就能用的配方。5.1 SQL Server 连接池复用避免每画面都新建 Connection 对象WinCC V16 的 VBScript 作用域隔离严格但可通过全局变量GlobalVars实现 Connection 复用。文档提供标准做法 在项目全局脚本Global Script中声明 Dim g_connPool Set g_connPool CreateObject(Scripting.Dictionary) 获取连接函数各画面调用 Function GetSQLConnection(serverName, dbName) Dim key key serverName | dbName If Not g_connPool.Exists(key) Then Dim connStr connStr ProviderSQLOLEDB.1;Data Source serverName ;Initial Catalog dbName ;Integrated SecuritySSPI; Set g_connPool(key) CreateObject(ADODB.Connection) g_connPool(key).Open connStr End If Set GetSQLConnection g_connPool(key) End Function 释放连接函数画面退出时调用 Sub ReleaseSQLConnection(serverName, dbName) Dim key key serverName | dbName If g_connPool.Exists(key) Then If g_connPool(key).State 1 Then g_connPool(key).Close Set g_connPool(key) Nothing g_connPool.Remove key End If End Sub逻辑说明g_connPool是 Dictionary 对象以Server|DB为 Key 存储 Connection 实例。每个画面只需调用GetSQLConnection(192.168.1.100, HMI_Data)避免重复连接开销。文档实测10 个并发画面连接建立时间从平均 800ms 降至 120ms。5.2 DataGrid 列隐藏用VisibleFalse还是Width0哪个更安全产线常需隐藏主键 ID、操作员编号等敏感列但又需在后台逻辑中引用。文档对比两种方式方式VisibleFalseWidth0安全性✅ 完全不可见无法通过右键菜单显示⚠️ 列仍存在于 Columns 集合Columns.Item(i).DataField可被脚本读取性能✅ 不渲染节省 GPU 资源✅ 同样不显示但列对象仍在内存稳定性✅ WinCC V16 兼容性完美⚠️ 某些显卡驱动下Width0 列可能导致 DataGrid 整体渲染错位 推荐用 VisibleFalse 隐藏 ID 列索引0 DataGrid1.Columns.Item(0).Visible False 后台脚本中仍可获取值 Dim currentID currentID DataGrid1.DataSource.Fields(ID).Value参数说明VisibleFalse后该列不再响应鼠标事件但DataSource中字段依然可用。文档强调禁止用Columns.Remove隐藏列因为移除后DataField绑定断裂刷新时会报错。5.3 跨画面数据同步用 WinCC 的Tag机制桥接 DataGrid 与全局变量DataGrid 编辑的数据需同步到其他画面如报警确认画面但 VBScript 无法直接跨画面访问控件。文档方案是用 WinCC 内置 Tag 作为中转站DataGrid 编辑后写 Tag其他画面监听 Tag 变化 在 DataGrid 的 AfterColEdit 事件中 Sub DataGrid1_AfterColEdit(ByVal ColIndex, ByVal Value) DataGrid1.DataSource.Fields(ColIndex).Value Value DataGrid1.DataSource.Update 将当前行 ID 和修改字段写入 WinCC Tag Dim currentID, fieldName currentID DataGrid1.DataSource.Fields(ID).Value fieldName DataGrid1.Columns.Item(ColIndex).DataField 写 TagHMI_DataGrid_Update_IDDINTHMI_DataGrid_Update_FieldStringHMI_DataGrid_Update_ValueString HMIRuntime.Tags(HMI_DataGrid_Update_ID).Write currentID HMIRuntime.Tags(HMI_DataGrid_Update_Field).Write fieldName HMIRuntime.Tags(HMI_DataGrid_Update_Value).Write CStr(Value) End Sub逻辑说明三个 Tag 作为轻量级消息总线。其他画面在Tag的OnValueChange事件中读取这三个 Tag执行对应逻辑如刷新关联画面、触发 OPC 写入 PLC。文档实测Tag 通信延迟 50ms远低于跨画面 VBScript 调用。6. 我的后悔药从那以后我每次部署 DataGrid 前都强制走一遍这三步验证清单这份.docx文档最后一页没有代码只有一张手写扫描的 checklist 表格标题是“WinCC V16 DataGrid 上线前 3 分钟自查表”。它来自我在汽车焊装车间连续修复 7 次报警看板崩溃后的肌肉记忆。现在我把它变成可执行的验证流程不是为了炫技是怕自己哪天手抖漏掉一行Set rs Nothing又得陪产线熬通宵。6.1 连接层验证用 SQL Server Profiler 抓取真实连接行为在部署前我必做这三件事启动 SQL Server Profiler新建跟踪筛选ApplicationName WinCC_V16_HMI在 WinCC 中打开含 DataGrid 的画面观察 Profiler 是否捕获到RPC:Completed事件且TextData显示执行的 SQL 语句点击 DataGrid 编辑单元格确认 Profiler 中出现sp_executesql调用且参数值与输入一致。教训曾有一次Profier 捕获到SELECT * FROM AlarmLog但WHERE条件被 VBScript 拼接错误丢弃导致全表扫描拖垮 SQL Server。从此我坚持用 Profiler 看真实 SQL而不是信脚本里的sql变量。6.2 DataGrid 属性快照导出当前配置到文本文件作为基线比对WinCC V16 的画面属性无法批量导出但 DataGrid 的关键属性可用 VBScript 提取并写入文本 在画面调试按钮中执行 Dim fso, file, i Set fso CreateObject(Scripting.FileSystemObject) Set file fso.CreateTextFile(C:\HMI\DataGrid_Config_ Now() .txt, True) file.WriteLine DataGrid1 配置快照 file.WriteLine AllowUpdate: DataGrid1.AllowUpdate file.WriteLine DataSource State: DataGrid1.DataSource.State file.WriteLine Column Count: DataGrid1.Columns.Count For i 0 To DataGrid1.Columns.Count - 1 file.WriteLine Column i : DataGrid1.Columns.Item(i).DataField | Visible DataGrid1.Columns.Item(i).Visible | Width DataGrid1.Columns.Item(i).Width Next file.Close MsgBox 配置已导出至 C:\HMI\DataGrid_Config_*.txt技巧每次升级博途版本或修改画面后我都运行此脚本用 Beyond Compare 对比新旧文件。列宽突变、Visible值反转、DataField拼写错误——这些肉眼难察的差异一眼就能揪出来。6.3 Runtime 内存监控用 Process Explorer 实时观察 ADODB 对象泄漏WinCC Runtime 的内存泄漏往往藏在 ADODB 对象未释放。我的标准动作是启动 Process Explorer微软官方工具附加到WinCCRTm.exe进程切换到DLLs标签页搜索sqloledb.dll和msado15.dll确认加载次数反复打开/关闭 DataGrid 画面 5 次观察 DLL 加载计数是否递增若递增说明CreateObject(ADODB.Connection)后未Set conn Nothing或conn.Close未执行。教训有次发现msado15.dll加载数从 1 增至 12定位到某画面OnPictureDeactivate事件中漏写了conn.Close。从那以后我每次写CreateObject都强制在同作用域内写下Set xxx Nothing哪怕中间隔着 20 行代码——因为 WinCC 的 VBScript 作用域规则比你想的更脆弱。希望帮到你。本文还有配套的精品资源点击获取
返回列表