☰
Intouch与SQL Server数据对接及Excel报表实战
2026/10/31 11:24:42 网站建设 项目流程

简介:面向SCADA与工业自动化从业者的实操文档,聚焦WonderWare Intouch 2014 R2平台与SQL Server 2012数据库的集成,以及基于Excel的报表系统搭建,适合需要打通HMI数据存储与报表展示环节的工程师参考。内容涵盖数据库登录方式与权限配置、新建库表、标记名字典中内存变量的建立、SQL访问管理器绑定列表、SQLConnect与SQLDisconnect连接脚本编写,以及Excel报表模板与VBA引用设置、数据库文件附加恢复等模块,形成从数据写入到报表呈现的完整链路。资源包共1个doc文件,约2.48MB,以图文步骤形式记录配置细节与脚本示例,便于对照操作与排错。已有533人学习,适合作为Intouch数据归档与报表开发的案头参考。

1. 从一份工控现场笔记说起:Intouch 写库与 Excel 报表到底怎么落地

凌晨两点,某产线的历史数据突然断档,值班的人翻遍 Intouch 画面也找不到问题——数据在画面上跳得好好的,数据库里却一条新记录都没有。这类现场问题,十有八九卡在 Intouch 与 SQL Server 的对接环节,而不是 HMI 本身。手上这份文档,讲的正是 WonderWare Intouch 2014 R2(IDE 平台)把数据写进 SQL Server 2012、再用 Excel 做报表取数的完整链路,外加数据库文件的备份与附加恢复。它适合正在做 SCADA 报表模块的自动化工程师、需要给产线补历史数据存储的现场实施人员,也适合刚接手一套老 Intouch 项目、要搞清“数据到底怎么进库”的维护者。文档不是理论教材,是一份按步骤能照着做的操作记录,下面我把它拆成能复现的路径,顺带把几个容易翻车的点标出来。

2. 打通 Intouch 到 SQL Server 2012:连接、标记与绑定列表

Intouch 写库这件事,本质是三层对齐:数据库侧要有表、Intouch 侧要有标记、中间靠绑定列表把两者按列名和数据类型一一挂上。任何一层错位,写入都会静默失败——这是这套方案最坑的地方,它不报错,只是数据不进库。所以这一章按“库→标记→绑定→脚本”的顺序推,每一步都给出可核对的落点。

2.1 数据库侧:身份验证模式与登录名权限

先解决“连得上”的问题。用 SQL Server Management Studio 进库,在服务器属性里把身份验证改成“SQL Server 和 Windows 身份验证模式”,否则后面 Intouch 用 SQL 账号连接会直接被拒。改完必须重启 SQL 服务才生效,这一步很多人漏掉,表现为连接字符串明明写对了却报登录失败。

接着在“安全性→登录名”下新建或修改账号。常见做法是给报表和写库单独建一个账号,只授予目标库的 db_datareader 和 db_datawriter,不要图省事直接用 sa。文档示例里用了 sa,现场能跑,但权限过大,一旦连接字符串泄露就是整库风险。新建登录名时在“常规”页设密码,在“服务器角色”页按需勾选,再到“用户映射”里把目标数据库勾上并指定角色,这套流程走完账号才算真正可用。

数据库和表建好后,重点核对列名与数据类型。表里的列名要和后面 Intouch 绑定列表里的变量名严格对应,数值列用 float 或 int、时间列用 datetime,别用 nvarchar 存数值再指望它自动转——写入时类型不匹配,SQLInsert 会失败且不留明显痕迹。

2.2 标记名字典:三个基础内存标记的用途

Intouch 的标记名字典是整套逻辑的变量池。文档里建了三个关键标记,各有明确分工:

标记名类型作用
Connid1内存整型保存 SQLConnect 返回的连接号,后续所有 SQL 函数都靠它定位连接
GetDateTimeS内存消息存连接时刻的时间字符串,便于排查连接时序
NodeName内存消息存本机计算机名,用于多站场景下判断“该由哪台机器写库”
WSQLS内存离散写库完成标志位,防止同一周期重复写入

建标记时注意“内存”类型不参与 I/O 扫描,只做内部运算,别误建成 I/O 型去绑 PLC 地址。Connid1 必须是整型,因为 SQLConnect 的第一个参数就是连接号输出位;WSQLS 用离散型,后面脚本里靠它做一次性写入的闸门。

2.3 绑定列表:列名与类型的双向对齐

在左侧工具视图里打开 SQL 访问管理器,进“绑定列表”。这里做的事是把 Intouch 变量映射到数据库表的列。规则只有一条但极容易错:绑定列表里的变量名、顺序、数据类型,必须和数据库表的列名、列顺序、列类型完全一致。差一个字母、顺序颠倒、int 对 float,写入就失败。

实操时建议先在 SSMS 里把目标表的列结构截图或导出,再对着建绑定列表,建完用一条手工 SQLInsert 试写一次,确认库里能看到记录再往下走。绑定列表本身不产生数据,它只是“翻译表”,真正触发写入的是脚本里的 SQLInsert。

2.4 连接与写入脚本:SQLConnect、SQLInsert 与关闭时释放

脚本分两处:应用程序脚本的“运行时”负责连接和周期写入,“关闭时”负责断开。先看连接与写入的核心逻辑,下面这段是按文档思路整理的等价写法:

' 应用程序脚本 - 运行时,条件 $Second==5,为真时执行 GetNodeName(NodeName, 131); ' 取本机计算机名存入 NodeName IF NodeName == "OP_01" THEN ' 只让指定站写库,避免多站重复写 IF $Minute >= 58 THEN ' 每小时最后两分钟触发一次汇总写入 IF WSQLS == 0 THEN ' 本周期尚未写过才进入 SQLInsert(Connid1, "TDays", "TDays"); ' 连接号, 表名, 绑定列表名 WSQLS = 1; ' 置位,锁住本周期 ENDIF; ELSE WSQLS = 0; ' 非写入窗口复位标志,为下个周期让路 ENDIF; ENDIF;

逐行说清楚:GetNodeName第二个参数 131 是取计算机名的模式码,结果写进 NodeName;NodeName == "OP_01"是站点过滤,多台 HMI 都连同一个库时,不加这层判断会重复插入;$Minute >= 58是时间窗口,按业务改成整点或班次边界;WSQLS是防重入闸门,没有它,条件为真的每个扫描周期都会插一条,一分钟能灌进几十条脏数据。SQLInsert三个参数依次是连接号、数据库表名、绑定列表名,两个 "TDays" 一个是表一个是绑定列表,名字可以不同,但都要和实际对象对上。

连接本身在更早的时机建立,等价写法:

' 应用程序脚本 - 运行时,条件 $Second==3,为真时执行 SQLConnect(Connid1, "provider=sqloledb;Data Source=OP_01;Initial Catalog=YADC_BB;UserID=report;Password=******");

连接字符串五段用分号隔开:provider 固定 sqloledb;Data Source 是数据库所在计算机名;Initial Catalog 是库名;UserID 和 Password 是 2.1 里建的账号。任何一段写错,Connid1 会拿到无效值,后续 SQLInsert 全部失败。最后别忘了“关闭时”脚本加SQLDisconnect(Connid1);,否则应用重启后旧连接可能残留,表现为连不上或连接数耗尽。

提示:改完脚本先在 WindowMaker 里用“逻辑→验证”过一遍语法,再切运行态观察 Connid1 是否变成有效连接号,比直接上线试错省时间。

3. Excel 报表系统:模板、VBA 引用与取数链路

数据进了库,下一步是把它变成人看得懂的报表。这套方案用 Excel 做前端,靠 VBA 连 SQL Server 取数,好处是现场人员熟悉 Excel、模板改起来快;代价是 VBA 引用和连接配置一旦错,报错信息很含糊。这一章把模板搭建和取数脚本拆开讲。

3.1 报表模板结构:控制面板页与参数日报页

模板分两个工作表。“控制面板”页放查询参数——起止时间、班次、设备号这类输入项,以及一个“生成报表”按钮;“参数日报”页是数据落地区,表头固定,数据区留空由 VBA 填充。这种分页设计的好处是参数和结果分离,改查询条件不用动数据区格式。

建模板时先把“参数日报”页的表头列名定死,并且和数据库查询结果的列顺序一致,VBA 里按列号回填时就不会错位。日期格式要在系统“日期和时间”设置里统一成 yyyy-MM-dd,Intouch 写入的时间字符串和 Excel 查询条件都用这个格式,否则会出现“查得到记录但日期对不上”的玄学问题。

3.2 VBA 引用与 ADO 连接:三处必须勾选的引用

打开“参数日报”页右键“查看代码”进 VBA 编辑器,在“工具→引用”里至少勾选三项:Microsoft ActiveX Data Objects 库(用于 ADO 连接)、Microsoft Excel 对象库(模板自身操作)、以及 OLE 自动化相关库。少勾一个,编译时就报“用户定义类型未定义”,这是新手最常见的翻车点。

连接串和 Intouch 侧保持同源,避免两套账号两套配置:

' 参数日报页 VBA:按控制面板参数查询并回填 Dim conn As ADODB.Connection Dim rs As ADODB.Recordset Dim sql As String Set conn = New ADODB.Connection conn.ConnectionString = "Provider=SQLOLEDB;Data Source=OP_01;" & _ "Initial Catalog=YADC_BB;User ID=report;Password=******;" conn.Open sql = "SELECT LogTime, TagValue FROM TDays " & _ "WHERE LogTime BETWEEN '" & Sheets("控制面板").Range("B2").Value & _ "' AND '" & Sheets("控制面板").Range("B3").Value & "' ORDER BY LogTime" Set rs = conn.Execute(sql) Sheets("参数日报").Range("A5").CopyFromRecordset rs ' 从第5行开始回填 rs.Close: conn.Close Set rs = Nothing: Set conn = Nothing

逻辑说明:连接串四段与 Intouch 一致,Data Source 换成数据库服务器名;SQL 用 BETWEEN 取时间区间,参数来自控制面板 B2、B3 单元格;CopyFromRecordset一次性把结果集灌进指定起始单元格,比逐格赋值快一个量级。参数上要注意,日期值拼进 SQL 字符串时若格式不是 yyyy-MM-dd,SQL Server 会按本地化设置解析,跨机器部署时结果可能不同,稳妥做法是在 VBA 里用 Format 函数统一格式化后再拼。

3.3 定时刷新与报表输出

报表不需要实时,常见做法是在控制面板放一个“刷新”按钮绑宏,或在工作簿打开事件里触发一次查询。若要做成定时报表,用 Application.OnTime 设定间隔,但注意查询期间关闭屏幕刷新(Application.ScreenUpdating = False),否则大数据量回填时界面会卡死。

输出环节,把“参数日报”页另存为独立工作簿或直接打印区域设好,避免把控制面板页一起打出去。模板里预留的图表区可以绑到数据区,数据一刷新图表跟着变,这是 Excel 报表相对组态报表的实用之处。

4. 数据库备份与附加恢复:mdf/ldf 两文件的搬迁

历史数据服务器迁移或灾备恢复时,最直接的办法是搬数据库文件再附加。SQL Server 一个库对应两个文件:数据文件 .mdf 和日志文件 .ldf,文档里存在 E:\DataBase 下。恢复流程是整目录拷到目标机同路径,再在 SSMS 里“附加”。

操作要点:拷贝前先在源库上做一次完整备份或脱机,直接拷正在使用的 mdf 会得到不一致的文件;目标机上“数据库→右键→附加”,在“要附加的数据库”里点“添加”,定位到 mdf 文件,SSMS 会自动带出 ldf,确认路径无误后确定。若提示“日志文件找不到”,说明 ldf 没一起拷或路径变了,可在附加界面删掉日志行让 SQL Server 重建,但会丢失未提交事务,生产库慎用。

注意:附加要求文件版本不高于目标实例版本,低版本 SQL Server 附加不了高版本文件,跨版本迁移要走备份还原或导出脚本,别硬附加。

5. 避坑排查:五个让数据“看着在、其实没进库”的现场问题

现象一:画面数据正常,库里一条记录没有。原因多半是绑定列表变量名或顺序与表列不一致,SQLInsert 静默失败。解决:在 SSMS 手工执行一条 INSERT 验证表结构,再对照绑定列表逐列核对,顺序也要一致。

现象二:同一时刻库里出现大量重复记录。原因是 WSQLS 闸门没生效或复位时机错,条件为真的每个扫描周期都插一条。解决:确认 WSQLS 在写入后立即置 1,并在非写入窗口复位为 0,同时检查多站是否都满足 NodeName 过滤条件。

现象三:连接字符串正确却登录失败。原因是改了身份验证模式没重启 SQL 服务,或账号没做用户映射。解决:重启服务,到“登录名→属性→用户映射”确认目标库已勾选并给了 db_datawriter。

现象四:Excel 报表查询报“未找到提供程序”。原因是 VBA 引用没勾 ADO 库,或 Office 位数与 Provider 不匹配。解决:补勾引用;64 位 Office 用 SQLOLEDB 一般可用,若报错改用 MSOLEDBSQL 并装对应驱动。

现象五:附加数据库提示文件被占用。原因是源库还在运行、mdf 被锁。解决:源库脱机或停服务后再拷,目标机附加前确认没有同名库存在。

6. 进阶:把一次性写入改成可追溯的班次归档

上面这套链路跑通后,多数现场会想再进一步:不再每小时插一条汇总,而是按班次归档、能追溯每条记录的来源站和时间。我的做法是在 TDays 表加两列 SourceNode 和 ShiftID,绑定列表里把 NodeName 挂到 SourceNode,脚本里按$Hour算班次写进 ShiftID。这样报表按班次筛选时不用再猜数据属于哪一班。

验证方法很直接:连续跑两个班次,用 SSMS 查SELECT SourceNode, ShiftID, COUNT(*) FROM TDays GROUP BY SourceNode, ShiftID,每个组合的记录数应等于预期写入次数,多一条少一条都说明闸门或时间窗口有问题。Excel 侧把班次作为控制面板的下拉参数,查询语句加AND ShiftID = ?,报表就能按班次出。

血泪经验是:任何改动绑定列表或表结构的操作,先在测试库上跑满一个完整班次再上生产,因为这类问题不会立刻暴露,往往第二天早上才发现昨晚的数据缺了一段。从那以后我每次动绑定列表前都强制走一遍“手工 INSERT 验证 + 单班次试跑 + 计数核对”三步,宁可慢半小时,也不留黑匣子。希望帮到你。

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询