ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

FactoryTalk View SE VBA实战:报表、配方与画面联动

FactoryTalk View SE VBA实战:报表、配方与画面联动 简介FactoryTalk View Site Edition 的 VBA 基本应用.doc 是一份面向工业自动化工程师、HMI 开发人员及 FANUC 机器人集成者的实用技术文档系统讲解如何在 FactoryTalk View SE 中借助 VBA 完成 PLC 标签的读取与写入、运行历史数据的记录处理以及通过 ADO 连接数据库进行数据存储与分析。文档以可操作示例贯穿始终覆盖从创建应用程序、area、HMI Server到建立仿真 PLC 通讯、配置画面组件属性、创建标签组和标签对象、编写按钮 VBA 代码的完整流程读者可据此搭建自己的测试环境并验证逻辑。包体为单个 doc 文件大小 1.27MB内部包含操作截图、属性配置表和示例代码便于对照学习目前已有 100 人学习下载。对正在学习 FactoryTalk View SE 开发、或需要提升工业 HMI 与 PLC 联动控制能力的自动化从业者这份资料能提供直接的代码思路与排错参考具有较强的工程实用性。1. FactoryTalk View SE的VBA存量项目里最常见的三种用法你接手的产线如果还在跑 FactoryTalk View Site Edition十有八九会遇到这些画面批次结束按钮背后挂着一大段 VBA把几十个过程量塞进 Excel配方画面靠几行脚本把参数一批批写进 PLC操作员点一下导航按钮画面跳转后顶部批号自动带过来。SE 从 v8.0 开始把脚本重心转到 VBA.NET但 5.0、6.x、7.x 时代的 VBA 编辑器依然活在大量存量现场文档上那句“VBA 基本应用”落到车间指的就是报表导出、配方下发和画面联动这三件事。下文按这个顺序把事件入口、Tag 读写、对象释放和部署坑位讲透新手能照着改代码熟手能避开升级迁移的大坑。2. VBA 在 SE 里的运行机制代码住进 Display事件驱动一切VBA 入门最容易被项目文档带偏的一点是拿着 VB 的语法书去猜 SE 的脚本环境。SE 里的 VBA 没有 Main 函数、没有启动线程它是一组挂在 Display 对象上的事件过程。画面在 Viewer 中打开事件被注册画面关闭代码生命周期结束。理解了这层下面的问题才有意义代码写在哪个窗口、什么时候触发、怎么够到 Tag。2.1 代码存放位置与全局代码入口打开 Studio 进入画面编辑器工具栏上的 VBA Code 按钮菜单路径 Edit → VBA Code会打开该画面的 VBA 集成环境。代码窗口的工程资源管理器里能看到当前应用下的代码工程但每个 Display 的代码只对自己可见。这个隔离设计有它的道理——每个 Display 的代码只在自己生命周期内执行不会出现一个画面的 Timer 在后台干扰另一个画面。容易被忽略的是全局代码。Application Explorer 树里 Application → Global Objects → Global Object双击打开这个对象的代码窗口就是整个客户端的全局模块。VBA 全局变量、公共函数都放这里所有 Display 的 VBA 都能直接调用。下面这段放在 Global Object 里可以让所有画面共用日志函数Public gBatchNo As String Public gRunStart As Date Public Function LogMessage(msg As String) As Boolean Dim fso As Object Dim ts As Object On Error GoTo fail Set fso CreateObject(Scripting.FileSystemObject) Set ts fso.OpenTextFile(C:\SEVBA\global_log.txt, 8, True) ts.WriteLine Format(Now, yyyy-mm-dd hh:mm:ss) msg ts.Close Set ts Nothing Set fso Nothing LogMessage True Exit Function fail: LogMessage False End Function参数说明OpenTextFile 的第二个参数 8 表示追加写入True 表示文件不存在时自动创建Format(Now,...) 统一了时间戳格式日志文件里每一行都能还原到秒。这里先不展开日志设计第 5 章会给一套带开关的完整写法。为什么要强调全局对象画面之间传变量、跨 Display 调用函数都绕不开这个位置。新手最常犯的错是把全局变量申在 Display 窗口里换一个画面就读不到了。放在 Global Object 里是 SE 的正解。VBA 交互窗体界面在 SE 里也遵循同样逻辑——画面本身承担交互全局对象承担共享状态不要试图在画面里维护一份“只属于自己”的公共数据。2.2 Tag 读取与写入的对象模型SE 给 VBA 暴露的核心对象是 Object它代表当前打开的 Display。读 Tag 用 Object.Tag(Tag路径).Read写用 .Write。路径有两种写法Tag 名全局唯一时直接写名字不唯一时必须带 Area 限定符格式是 Area::TagName。判定唯一性的唯一标准是 Tag 数据库不是画面能不能显示——画面上的文本绑定走表达式引擎对重名宽容得多VBA 的 Tag 方法严格要求找到且只找到一个 Tag否则返回 Null 或运行时报警。给一个安全读取的代码Dim v As Variant v Object.Tag(Line1_Temp).Read If IsNull(v) Then 通讯中断或Tag不存在走异常分支 Text1.Text -- Else Text1.Text CStr(v) End IfIsNull 判断很关键。SE 里 Tag 读失败返回的不是 0 而是 Null如果直接用 CStr 转换会抛类型不匹配整段脚本中断。这在通讯抖动时特别明显——重启 PLC、网线松动的瞬间画面脚本可能整片停摆操作员看到的就是“画面死了”。写入比读取更需要防御。Write 方法静默失败不抛异常所以要点写前置校验。比如现场参数限幅 100写入前先检查值域Dim setpoint As Double setpoint CDbl(TextBox1.Text) If setpoint 0 And setpoint 100 Then Object.Tag(Line1_Setpoint).Write setpoint Else Text1.Text 超出限幅范围 End If质量属性 Quality 在需要判断数据可信度时用。读值成功不代表值有效PLC 停机时保持寄存器里可能是残留值先比对 Quality 再决定要不要用——尤其是报警统计、产量累计这类需要数据可信的逻辑光判断 IsNull 不够。SE VBA 里 Tag 操作的常用 API 就是这几条参数按现场习惯贴进代码注释里操作调用说明读值Object.Tag(Area::TagName).Read返回 Variant失败为 Null写值Object.Tag(Area::TagName).Write value返回 Boolean但失败不抛异常质量Object.Tag(Area::TagName).Quality0~100100 为优0 为坏阈值自己定批量读Object.TagGroup(组名).Read一次取回整组 Tag适合轮询2.3 事件入口打开、点击与定时器Display 打开时的初始化代码写在 Display_DisplayOpen 事件里签名固定为Private Sub Display_DisplayOpen(LastDisplay As String) LastDisplay 是上一个画面名可用于返回逻辑 Text1.Text 欢迎进入 1 号线 End Sub这个事件的触发时机在画面绘制完成之后、操作员可见之前所以可以安全地在这里刷新文本、初始化下拉框、给按钮置灰。LastDisplay 参数被多数人忽略其实很适合做“返回上一画面”——把上一个画面名存到全局变量返回按钮直接 Display 回去。按钮事件在 ActiveX 控件上。从工具箱拖一个 CommandButton 到画面双击它进入 Click 事件如果用图形对象做按钮则在 Animation 的 Press/Release 动作里写命令命令可以是 ExecuteCommandVBA 里也能直接调用Private Sub CommandButton1_Click() Application.ExecuteCommand Display Line1_Overview, End Sub定时轮询有两种常见做法。一种是在 Display 上放 Microsoft Forms 2.0 Timer 控件Interval 单位是毫秒另一种是用 Global Object 里的 Timer 事件适合全客户端级别的后台任务。无论哪种都不要让它每秒循环读大量 Tag第 4 章的避坑会展开。事件入口就这几个摸清了再谈业务代码。很多“画面脚本时灵时不灵”的案子最后查出来是代码写在了错误的事件里——初始化放在 Timer 里跑、周期任务塞进 DisplayOpen这都是 VBA 入门时常见的逻辑错位。3. 三个能直接落地的 VBA 应用Excel 报表、配方下发与画面联动机制讲完落地是关键。下面的三段代码都按“复制到项目里改几个名字就能跑”的标准写每段后面标注了参数含义和失败时看哪里。3.1 一键导出 Excel 报表需求操作员按下按钮把当前产线关键参数写到 Excel文件名带日期覆盖旧文件时不弹确认框。Private Sub CommandButton1_Click() Dim xlApp As Object Dim xlBook As Object Dim xlSheet As Object Dim tagNames As Variant Dim i As Integer Dim filePath As String 文件名带日期每天一份 filePath D:\SEReports\Line1_ Format(Date, yyyymmdd) .xlsx On Error GoTo ExportFail Set xlApp CreateObject(Excel.Application) xlApp.Visible False xlApp.DisplayAlerts False Set xlBook xlApp.Workbooks.Add Set xlSheet xlBook.Worksheets(1) xlSheet.Cells(1, 1) Tag名称 xlSheet.Cells(1, 2) 当前值 xlSheet.Cells(1, 3) 读取时间 tagNames Array(Line1_Temp, Line1_Pressure, Line1_Flow) For i LBound(tagNames) To UBound(tagNames) xlSheet.Cells(i 2, 1) tagNames(i) xlSheet.Cells(i 2, 2) Object.Tag(tagNames(i)).Read xlSheet.Cells(i 2, 3) Format(Now, yyyy-mm-dd hh:mm:ss) Next i 51 是 xlsx 格式编号 xlBook.SaveAs filePath, 51 xlBook.Close False xlApp.Quit Set xlSheet Nothing Set xlBook Nothing Set xlApp Nothing Exit Sub ExportFail: If Not xlApp Is Nothing Then xlApp.Quit Set xlApp Nothing End If Text1.Text 报表生成失败 End Sub参数说明CreateObject(Excel.Application) 要求运行 Viewer 的客户端本机安装桌面版 Excel不是只装了 Office 套件里的其他组件就够DisplayAlerts False 关闭覆盖询问否则保存文件存在时会弹出对话框把操作站卡在后台SaveAs 第二个参数 51 对应 xlsx 格式需要老版 xls 就改成 56。失败分支里 If Not xlApp Is Nothing 是 VBA 释放 COM 对象的惯用写法配合 On Error 才能保证 Excel 进程不在内存里越积越多。现场还常见需要把日期范围作为条件筛选的报表那就是 Excel Formula 属性和 VBA 循环的活循环填充公式时按行写入即可。做日期范围筛选时VBA 日期比较大小直接用 Date 类型做大于小于判断别拿格式化后的字符串比字符串的排序会随格式变化而翻车。SE 没有 Office 那种状态栏 API要显示“正在生成报表”的进度用画面上的 Text 控件模拟即可。注意Excel 导出代码不要在运行时频繁调用尤其不要放进 Timer。Excel 进程启动要 1~2 秒期间操作站界面会卡顿。做成按钮触发或换班触发一个班次最多点十几次压力完全可控。3.2 配方下发VBA 字典与数组的配合配方是 HMI 里最老的需求。常见做法是配方数据存在 PLC 或数据库VBA 负责从画面输入取配方号、查找数据、批量写 Tag。用 Scripting.DictionaryVBA 字典组织配方数据比一串 If 判断好维护得多Private Sub CommandButton1_Click() Dim recipes As Object Dim tagNames As Variant Dim values As Variant Dim selRecipe As String Dim v As Double Dim i As Integer Set recipes CreateObject(Scripting.Dictionary) recipes.Add R01, 100,65,20 温度,压力,流量 recipes.Add R02, 120,70,25 selRecipe TextBox1.Text If Not recipes.Exists(selRecipe) Then TextBox2.Text 配方不存在 Exit Sub End If tagNames Array(Line1_Temp_SP, Line1_Press_SP, Line1_Flow_SP) values Split(recipes(selRecipe), ,) 批量下发前先做值域检查 For i LBound(tagNames) To UBound(tagNames) v CDbl(values(i)) If v 0 And v 500 Then Object.Tag(tagNames(i)).Write v End If Next i Set recipes Nothing End Sub逻辑说明Dictionary 的 Add 方法遇到重复键会报错所以先用 Exists 检查Split 将逗号分隔的字符串切成 VBA 数组配合 LBound/UBound 遍历是标准姿势。写入前限幅那段建议留着——Write 失败不报错是 SE 的沉默坑宁可多写三行校验不赌现场操作员的手速。配方画面做得讲究一点的会在写入前把所有目标 Tag 先读一遍把当前值陈列在界面上让操作员对比差异后再确认。这些都是在这段代码上扩展的活核心还是“字典查配方、数组做遍历、写前做校验”这三板斧。3.3 画面联动与批号传递生产管理类的画面对联动有要求从主画面进工序画面工序画面要显示同一个批次号。批次号是运行时产生的不能写死在画面得靠全局变量传递。在 Global Object 里声明Public gBatchNo As String Public gProductName As String主画面的按钮事件Private Sub CommandButton1_Click() 生成一批一码的批号 gBatchNo B- Format(Now, yyyymmdd-hhmm) Application.ExecuteCommand Display Process_1, End Sub工序画面的 DisplayOpen 里取出来Private Sub Display_DisplayOpen(LastDisplay As String) 从全局变量取批号显示在文本上 If Len(gBatchNo) 0 Then Text1.Text gBatchNo End If End SubgBatchNo 定义在 Global Object 里进程生命周期有效Viewer 重启后清空。如果要求断电保留或者多客户端共享就得把它同步到 PLC 或数据库中VBA 这块只是个中转站。Application.ExecuteCommand 的字符串参数是 SE 原生命令不同小版本的命令解析有一点差异拿不准时用画面按钮的 Animation 动作录一条命令看看格式——照抄一定不会错。传参只是联动的一种。还有一类需求是打开画面后根据上一个画面决定按钮置灰还是显示利用 DisplayOpen 里的 LastDisplay 参数就行。4. SE 跑 VBA 的避坑清单五条现场验过的血泪经验VBA 代码写错当场就红编译过了运行时才翻车这才是最磨人的。下面五条每一条都是从现场故障单里捞出来的按现象、原因、解决三个顺序写。4.1 Tag 明明存在却读不到值现象VBA 里 Object.Tag 读同一个 Tag有时返回 Null诊断窗口冒“标签不存在或不唯一”。画面上同样路径的文本显示却正常。原因画面显示用表达式引擎允许按 Area 就近解析Object.Tag 要求路径在数据字典里唯一不唯一就拒绝。最常见是两个 Area 下有同名 Tag以前写死不带 Area 的代码全部踩雷而且只在某些客户端上出现——因为客户端连接的数据服务器不同跨服务器同步时标签解析路径不一样。解决先开 Tag 诊断工具把不带 Area 的引用全部改成 Area::TagName 格式。规约一句话VBA 里一律写全限定路径别偷懒偷懒的代价是半夜被叫到现场查一个根本不存在的问题。4.2 Excel 导出偶发自动化错误现象报表第一次点导出正常第二次开始弹“自动化 (Automation) 错误”或者完全没反应任务管理器里 EXCEL.EXE 进程越堆越多。原因脚本中途 Exit 或报错xlApp.Quit 没执行Excel 进程残留另一类原因是 SE 客户端是 32 位进程调的却是 64 位 ExcelCOM 注册表对不上CreateObject 偶尔能起来偶尔起不来。解决代码里 On Error 下统一走 Quit 加释放这段写进每个导出脚本客户端装 32 位 Office Excel再不行到组件服务里检查 Excel.Application 的启动权限允许交互式启动。这条涉及系统服务配置确认微软文档里的权限步骤后再动别乱改本地策略改错了别的 COM 组件也会跟着出问题。4.3 改了代码但客户端跑的还是旧的现象Studio 里 VBA 改完本机测试新逻辑正常部署到操作站后操作站行为还是老的按钮没反应、报表还是旧格式。原因Viewer 客户端使用本地缓存Studio 保存的改动没有真正发布到客户端。SE 的部署机制是 Gfx 文件随应用发布只看 Studio 里的 Test 运行说明不了问题——本机跑的是开发环境操作站跑的是上一次部署的包。解决在 Studio 用 Application 的发布/部署功能把画面推到客户端如果被缓存坑过在客户端清理 FactoryTalk View 本地缓存目录后重新连接。具体菜单不同版本不一样认准“部署”相关入口即可。这个坑在项目交接时最典型上一任工程师明明改了现场装的是半年没部署的包双方都觉得自己没问题一查部署日志全明白了。4.4 复制画面后 VBA 代码失踪现象把做好的画面从一个应用复制到另一个应用按钮和图形都还在打开 VBA 窗口一片空白。原因复制粘贴对 Gfx 内嵌的 VBA 工程并不总是完整迁移跨应用复制、通过 XML 导入导出时丢脚本是重灾区。画面文件本身是个复合文档文本方式看不到代码丢了很难手工找回来。解决跨应用搬画面不要走复制粘贴把源应用整体打包再部署或者从备份库里用画面还原功能。团队多人改同一批画面时给 VBA 代码单独做文本导出版本定期提交等于给代码上后悔药。升级 V8 及以上版本时同理——VBA 工程不会自动转成 VBA.NET官方迁移向导能搬动画面的外观脚本要重新适配Object.Tag 这套 API 会被 TagRead、TagWrite 替代别指望原样跑通。4.5 Timer 轮询把操作站拖成幻灯片现象画面上一段 VBA 每秒循环读 30 个 Tag客户端 CPU 上到 40%开两个画面就卡。把 Timer 的频率从 1000ms 改成 3000ms 有所缓解但治标不治本。原因VBA 里的每个 Read 都是同步请求串行等待数据服务器响应。跨网关 IO 或服务器负载高时一次循环要几百毫秒再叠加 Timer 周期CPU 全耗在等待上画面刷新和鼠标响应都被拖累。解决用 Tag Group 把一批 Tag 放在组里一次 Object.TagGroup 读取整组网络往返少一个数量级或者把周期性读值的逻辑从 VBA 挪到 Animation 的表达式动作里让数据引擎自己管理刷新VBA 只在结果变化时做展示。这条对老项目改造尤其值得做——不动画面布局只换数据获取方式卡顿问题就解决大半。这五条有个共同点VBA 本身不复杂复杂的是它被夹在画面、数据引擎和操作系统之间任何一个环节没对齐就静默失败。所以 SE 的 VBA 项目调试思路永远先怀疑集成环节再怀疑代码。5. 运行时自检日志让 VBA 把问题自己说出来SE 的 VBA 没有 PLC 那样的在线监视脚本出错时大多是静默的——界面不动、值不刷新、报表没生成操作员只会在电话里说“没反应”。给 VBA 加日志是最直接的排错手段下面这个函数是每个 SE 项目我都会最先写的功能Public Sub LogTrace(msg As String) Dim fso As Object Dim ts As Object Dim path As String On Error GoTo FailOut path C:\SEVBA\vba_log.txt Set fso CreateObject(Scripting.FileSystemObject) 目录不存在时先创建避免日志静默丢失 If Not fso.FolderExists(C:\SEVBA) Then fso.CreateFolder C:\SEVBA End If Set ts fso.OpenTextFile(path, 8, True) ts.WriteLine Format(Now, yyyy-mm-dd hh:mm:ss) | msg ts.Close Set ts Nothing Set fso Nothing Exit Sub FailOut: 日志写不进去时不能挡住业务代码 End Sub用法很简单。每个事件入口第一行写一句 LogTrace 记录触发Tag 读取分支写一句值或失败原因模块间相互调用的起止各打一条。现场出问题时打开这个 txt 就能还原整个操作时序——哪个画面被打开过、按钮点了没、Tag 读到的是 Null 还是越界值全部有据可查。进阶一点的玩法是加日志级别开关用 HMI 里一个空闲内部 Tag 控制Debug 1 时才写详细日志平时只写错误和关键动作避免日志文件两天撑爆磁盘。开关的值可以从画面维护页面上设置值班工程师自己就能开不需要动代码重新部署。写 SE 项目这几年我养成的习惯是第一个代码功能永远是 LogTrace后面所有画面脚本都默认调它。省下的排错时间远超写它的那半小时。这个思路同样能平移到 VBA.NET 版本API 变日志的坑不变。希望帮到你。本文还有配套的精品资源点击获取
返回列表