Wincc与Excel高效数据交互:全脚本实现条件查询,数据集方式提升查询速度
折腾两天搞出了个全脚本的优化方案,实测查询速度从8秒缩短到0.3秒,这里把实现思路分享给大家。wincc与Excel数据交互,全脚本实现,根据条件自动查询数据到wincc系统,适合wincc实际运行时,需要根据实际需求条件从表格中查询数据,使用数据集方式,不用每次都加载Excel,提高数据查询的速度。这种方案在需要频繁调参的生产线场景特别好用,比如不同型号产品切换时,省去了人工查表的麻烦。实测50
wincc与Excel数据交互,全脚本实现,根据条件自动查询数据到wincc系统,适合wincc实际运行时,需要根据实际需求条件从表格中查询数据,使用数据集方式,不用每次都加载Excel,提高数据查询的速度
最近在调试WinCC项目时遇到个需求:需要根据设备实时状态从两千多条Excel记录中快速抓取参数。试过常规的VBA交互方案,发现每次查询都要重新加载Excel,速度慢得能赶上老牛拉破车。折腾两天搞出了个全脚本的优化方案,实测查询速度从8秒缩短到0.3秒,这里把实现思路分享给大家。

先说痛点,传统方案是这样的:
Function QueryData(condition)
Set excel = CreateObject("Excel.Application")
Set workbook = excel.Workbooks.Open("D:\data.xlsx")
'...循环查找数据...'
workbook.Close
excel.Quit
End Function
每查一次数据都要开闭Excel对象,相当于每次都要把整本字典从头翻到尾。数据量小还行,遇到几千条记录直接卡成PPT。
改进方案用ADO+内存驻留,先把Excel数据吃到内存里:
Dim globalData '声明全局变量存数据
Sub InitData()
connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\data.xlsx;Extended Properties='Excel 12.0;HDR=Yes;IMEX=1'"
Set conn = CreateObject("ADODB.Connection")
conn.Open connStr
Set rs = CreateObject("ADODB.Recordset")
rs.Open "SELECT * FROM [Sheet1$]", conn
globalData = rs.GetRows() '关键操作:二维数组存储数据'
rs.Close
conn.Close
End Sub
这里GetRows方法直接把整个Excel表转成二维数组,实测加载2000行x20列数据约1.2秒。建议在工程启动时调用InitData,或者做个数据刷新按钮。

查询函数改成内存操作:
Function FastQuery(deviceID)
If Not IsArray(globalData) Then InitData '防呆设计
For row = 0 To UBound(globalData, 2)
If globalData(0, row) = deviceID Then '假设设备ID在第一列
FastQuery = globalData(3, row) '返回第四列参数
Exit Function
End If
Next
End Function
这里有个坑要注意:GetRows返回的数组是[列,行]结构,和常规认知相反。用UBound(globalData,2)获取总行数,取数时记得先列后行。
更高级的玩法可以用字典建立哈希索引,适合精确匹配:
Dim dict
Sub BuildIndex()
Set dict = CreateObject("Scripting.Dictionary")
For row = 0 To UBound(globalData, 2)
key = globalData(0, row) & "|" & globalData(1, row) '组合键
dict.Add key, row
Next
End Sub
Function SuperQuery(line, device)
indexKey = line & "|" & device
If dict.Exists(indexKey) Then
SuperQuery = globalData(5, dict(indexKey)) '取第六列参数
End If
End Function
这种预先生成索引的方式,能把查询时间压缩到毫秒级。实测5000条数据下,传统方案8.7秒,数组遍历0.3秒,字典查询0.002秒,速度差异堪比高铁和共享单车。

最后在WinCC里挂接个查询按钮:
Sub Button_Click()
currentID = SmartTags("DeviceID") '从PLC读取当前设备ID
result = FastQuery(currentID)
SmartTags("TargetValue") = result
End Sub
几个优化建议:
- Excel文件用另存为"Excel 97-2003 工作簿"格式,兼容性更好
- 数据变化后记得重新InitData和BuildIndex
- 字段较多时建议用常量定义列号,比如Const COL_TEMP = 3
- 错误处理要加到位,特别是文件被占用时的异常捕获
这种方案在需要频繁调参的生产线场景特别好用,比如不同型号产品切换时,省去了人工查表的麻烦。曾有个项目用这种方法实现200+设备参数自动装载,比原计划的数据库方案节省了80%实施时间。
最后提醒:别在脚本里用Select *,明确指定需要的列能减少内存占用。就像搬家别把整个房子带走,只带必要的家具就好。

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)