WinCC用户归档从组态到排错:配方管理与批次追溯实战

发布时间:2026/10/10 16:17:32
WinCC用户归档从组态到排错:配方管理与批次追溯实战 简介WinCC用户归档案例资源包服务于工业自动化领域的SCADA工程师和组态技术人员围绕西门子WinCC用户归档功能演示如何借助动作与标准模块的配合实现生产数据的选择性采集、过滤、转换与压缩归档并据此设计合理的存储周期与保留策略适合需要基于历史数据进行报表分析、故障追溯和工艺优化的项目场景。压缩包共290个文件以rpl归档工程文件为主配合mdf/ldf数据库文件、pdl画面、cfg配置及cvb/h脚本等涵盖数据定义、界面操作与后台处理各环节包体大小约36.21MB。目前已有1150人学习下载。包内包含可执行的示例归档工程、模块调用逻辑及配套说明读者可对照搭建一套完整的用户归档机制理解动作触发与标准模块复用的工程实践提升WinCC数据管理的综合能力。1. 用户归档案例先从一次“配方调不进去”的现场说起现场最怕的不是 WinCC 画面卡而是配方按钮按下去了配方值却一行都没进 PLC。查历史趋势曲线数据是有的查用户归档里面还是空的。后来才发现问题出在字段映射和写权限上。WinCC 用户归档User Archive不是普通的历史数据库它专门用来存结构化业务记录——比如按批次存配方参数、按操作员存交接班记录、按产品存质量抽检结果。和变量记录不同用户归档里的每条记录有明确的字段含义可以按时间戳和业务键查询也能让画面、报表、趋势曲线共用同一套数据。这篇文章从一套完整案例讲起从建归档、写记录、显示到排错把用户归档的落地路径拆开。不管是在 TIA Portal V15.1 里做 Comfort 面板还是在 WinCC RT Advanced 里做上位只要想管配方和批次都适用。2. 把用户归档建起来从 TIA Portal 到 WinCC 运行系统的数据链路2.1 在 TIA Portal 中创建用户归档归档名、字段类型是第一步打开 TIA Portal 项目在左侧项目树里找到 WinCC RT 的组态项展开后能看到“用户归档”编辑器。对 V15.1 来说这个入口一般是“HMI → 运行系统设置 → 用户归档”。右键选择“新建用户归档”先给它一个名字。归档名我强烈建议用英文或拼音比如 RecipeArchive、TempArchive。中文名不是不能用但后面在 VBS 脚本、SQL 查询和表达式里会频繁触发编码问题尤其在 WinCC 内部把字段名拼成查询语句时一个中文空格就可能让整个脚本静默失败排查起来非常扎心。建好归档后重点在字段定义上。用户归档的字段类型有数值整数、浮点、文本和日期时间三大类。以配方场景为例我一般会建这么几个字段BatchNo文本存批次号、TempSet浮点存设定温度、Kp、Ti、TimeSlot日期时间存记录生成时间。字段名和归档名一样统一用无空格、不保留字符的英文。文本字段要指定长度批次号该 20 字符就写 20别图省事写默认值太短会导致从 PLC 侧拼接字符串时被截断太长又占用数据库存储空间。字段名类型典型用途BatchNo文本(20)批次号或配方名TempSet浮点设定温度/设定值TimeSlot日期时间记录产生时间Remark文本(100)操作备注字段类型一旦建好后期再改会很麻烦——涉及归档表的列结构变更运行系统里已有的历史记录可能读不出来。所以第一步宁可多花十分钟把字段清单和类型设计清楚也别急着下载到模拟器里试。组态完成后右键项目编译、下载到运行系统。这里你可能会碰到 V15.1 报“找不到许可证 wincc comfort”的情况后面避坑段落会细说先记住用户归档功能是否可用跟你的运行系统类型和授权版本强相关不是组态错了。2.2 用变量连接把过程值映射到归档字段省掉脚本的常规做法用户归档写入数据有两种路径变量连接和脚本。变量连接适合“周期记录”的场景比如每 5 秒归档一条温度值。配置方式不复杂在用户归档编辑器的“变量连接”区域新增一条连接左侧选源变量内部变量或 PLC 变量右侧选目标归档字段然后设置触发周期。运行后 WinCC 会按照周期自动把变量当前值写入对应字段不需要任何脚本。这里有个关键参数容易踩坑变量连接到底是“追加新记录”还是“更新当前记录”。WinCC 用户归档的变量连接默认会修改当前活动记录也就是说如果你的批次流程没有先创建一条新记录那每个周期都是往同一条记录里反复覆盖字段值归档里永远只有一行数据。很多工程师第一次用用户归档做温度趋势发现表格里就一行数据就是因为把变量连接当成了变量记录来用。常见做法是在批次开始时先用脚本创建一条新的空记录之后变量连接负责把实时过程值写进这条记录的字段里。这样脚本只管“开行”数据灌入交给系统自动执行。如果你不想写脚本也可以在变量连接属性里勾选“每个周期创建新记录”但那样每条记录只有当前周期的一个快照字段之间的业务关联会变得很松散。所以我的习惯是业务型归档用脚本开记录 变量连接填数据纯底层采样用系统变量记录两个别混。2.3 用 VBS 写一条记录最小可运行的归档写入脚本无论变量连接多方便总归有需要脚本写数据的时候——比如操作员点“确认配方”按钮才把这一行配方参数写入归档。这时候最常用的是 VBS 全局脚本或画面按钮事件。下面是一个最小可运行的例子 画面按钮事件向用户归档写入一条新的配方记录 Dim archive Set archive HMIRuntime.UserArchives.OpenArchive(RecipeArchive) 打开归档 archive.ConnectActive False 仅手动写入断开自动变量连接避免覆盖 archive.Recordset.AddNew 新建一条空记录 archive.Recordset.Fields(BatchNo).Value B20260701-001 archive.Recordset.Fields(TempSet).Value 85.5 archive.Recordset.Fields(TimeSlot).Value Now() archive.Recordset.Update 提交记录不调用则不落库 archive.CloseArchive 关闭归档释放连接这段脚本的逻辑顺序是有讲究的。OpenArchive打开归档后系统会返回一个记录集对象Recordset就是这个记录集。ConnectActive False必须先执行因为默认情况下归档可能与画面上的变量连接处于联动状态你不主动断开手动AddNew之后字段值可能被周期连接立即覆盖等于白写。AddNew只是把记录集的当前行切成“新增模式”真正的写入发生在Update调用——很多新手漏了这行脚本不报错归档里就是没数据。最后CloseArchive一定要调用不然长时间占用归档句柄会导致后续其他客户端脚本或表格控件读不到更新这是 WinCC 用户归档并发控制里的一个经典坑。如果你用的 WinCC 版本里HMIRuntime.UserArchives.OpenArchive方法不可用可以换成HMIRuntime.UserArchives(RecipeArchive)然后直接操作RecordSet对象。不同版本的 API 命名有细微差别但核心的 AddNew、Fields、Update 这套 ADO 风格接口是通用的。脚本里再加个错误处理会更稳妥捕获归档打开失败的场景别让按钮点了没反应。3. 把归档内容展示到画面表格控件、下拉选择与趋势曲线联动3.1 UserArchive 表格控件不用写代码就能看数据在 WinCC 画面编辑器里控件列表中可以找到“用户归档控件”有些版本显示为“WinCC User Archive Control”。把它拖到画面上打开控件属性对话框指定它要绑定的归档名再勾选需要在表格里显示的字段。运行后这个控件会直接把归档内容渲染成一张表格支持按列排序、选中等基本操作连脚本都不用写。这里值得注意的细节是控件的刷新模式。默认情况下用户归档控件只在画面初次打开时读一次数据之后你通过脚本或者变量连接往归档里写了新记录表格画面不会自动更新。需要在控件属性里把“刷新周期”从“不刷新”改成一个固定间隔比如 1 秒或者勾选“自动刷新”。如果你想要“操作员一点按钮立刻看到新行”可以在按钮脚本里调用控件对象的刷新方法而不是苦等周期刷新。另外控件显示的行数可以设置上限防止归档表膨胀到几十万行时画面卡死。3.2 用脚本把归档字段读到内部变量驱动历史趋势曲线用户归档和 WinCC 自带的历史趋势曲线控件之间没有直接的“字段绑定”关系。趋势曲线控件只能读取变量PLC 变量或内部变量所以如果你想用趋势曲线展示归档里的历史温度数据就必须通过脚本把归档字段的值转存到内部变量再让趋势控件绑定这个内部变量。下面这段脚本解决的是“根据当前选中批次把该批次温度字段写入趋势变量”的桥接问题 按钮事件按批次号读取归档温度值更新趋势曲线用的内部变量 Dim archive, batchNo batchNo HMIRuntime.Tags(CurBatch).Read Set archive HMIRuntime.UserArchives.OpenArchive(TempArchive) archive.Recordset.Filter BatchNo batchNo archive.Recordset.MoveFirst If Not archive.Recordset.EOF Then 把第一批匹配记录的温度值写到趋势控件绑定的变量上 HMIRuntime.Tags(TempFromArchive).Write archive.Recordset.Fields(Temp).Value End If archive.CloseArchive其中Filter是记录集的筛选属性写法类似 SQL 的 where 条件。注意字符串条件要用单引号包裹如果批次号变量本身包含中文或单引号脚本会直接报语法错误这点具体避坑放在后面。MoveFirst把指针移到筛选结果的第一行再用EOF判断是否存在匹配记录。趋势曲线控件绑定了TempFromArchive这个内部变量后数值变化就会反映到曲线上。不过要提醒一句这种读法只能展示当前筛选出的单条记录。如果你要画一条完整的历史趋势曲线最好还是用 WinCC 的变量记录归档去存采样值然后让趋势控件读变量记录。用户归档更适合做“业务事件快照”不是高频采样的主力。3.3 排序、筛选和时间戳三个显示参数决定报表好不好用做了这么多项目我发现用户归档表格控件的显示效果90% 取决于三个参数:排序字段、筛选条件、时间戳格式。排序字段如果不选默认按数据库写入顺序排列这和按时间排序结果可能完全不一样。我在批次追溯页面里通常把TimeSlot设置为默认排序字段并且选降序这样最新记录永远排在最上面不用翻页。时间戳的显示格式也是个容易翻车的地方。WinCC 用户归档的时间字段在库里不是常规的yyyy-mm-dd hh:mm:ss字符串而是浮点型日期序列。表格控件默认能显示成可读格式但你在脚本里读出来再写到别的变量时很可能会得到一串小数。这时候要用FormatDateTime转换一下再显示。至于筛选条件如果你只关心今天的批次在控件的“筛选表达式”属性里写Year(TimeSlot) Year(Now())这种表达式不一定被支持最好用 Recordset.Filter 在脚本里做或者通过下拉框联动设置归档表的显示范围。总之想让归档控件真正好用这三样必须逐项验证过别只拉一个没配置的控件糊上去。4. 配方切换与批次追溯两个最常见的用户归档业务场景4.1 一键配方切换从归档行读出参数并写入控制回路配方管理是用户归档最典型的应用。把多套配方参数存成多条记录操作员在画面上选中配方名点“下发”按钮脚本读取该行字段并写入 PLC 相关变量完成整组参数切换。这样可以避免在画面里堆几十个输入框也便于后续修改配方。 配方下发从归档读选中配方写入 PID 和温度设定变量 Dim archive, recipeName recipeName HMIRuntime.Tags(SelRecipe).Read Set archive HMIRuntime.UserArchives.OpenArchive(RecipeArchive) archive.Recordset.Filter RecipeName recipeName archive.Recordset.MoveFirst If Not archive.Recordset.EOF Then HMIRuntime.Tags(PID_Kp).Write archive.Recordset.Fields(Kp).Value HMIRuntime.Tags(PID_Ti).Write archive.Recordset.Fields(Ti).Value HMIRuntime.Tags(PID_Td).Write archive.Recordset.Fields(Td).Value HMIRuntime.Tags(TempSet).Write archive.Recordset.Fields(TempSet).Value End If archive.CloseArchive这里有个在实际项目中容易忽略的点写入多个 PLC 变量的顺序和时机。如果你用的是 S7 通信多个变量逐个Write时PLC 可能在第一个变量到位后就开始执行 PID 运算导致中间状态短暂混乱。常见做法是在脚本里先写一个“配方下发开始”的置位变量PLC 收到后暂停控制等所有参数写完再写“下发完成”信号PLC 再启动新参数。这个协调逻辑不在用户归档范围内但做配方切换时一定要配合时序不然用户归档只能帮你存参数不能帮你安全生产。4.2 按批次号追溯用时间戳和批次字段定位记录批次追溯要求的是“给定一个批号或时间段把所有关联记录调出来”。用户归档的 Filter 可以组合多个条件例如按批次号加时间范围锁记录。下面是一个倒推昨天 24 小时记录的写法 查询昨日批次记录导出到画面列表或报表 Dim archive, startTime, endTime startTime FormatDateTime(DateAdd(d, -1, Date), 0) 00:00:00 endTime FormatDateTime(Date, 0) 00:00:00 Set archive HMIRuntime.UserArchives.OpenArchive(ProdArchive) archive.Recordset.Filter TimeSlot # startTime # AND TimeSlot # endTime # archive.Recordset.MoveFirst Do While Not archive.Recordset.EOF 这里把每条记录的字段值写入报表表格或内部变量 HMIRuntime.Tags(Report_Batch).Write archive.Recordset.Fields(BatchNo).Value 业务处理逻辑比如累加产量、记录首条时间 archive.Recordset.MoveNext Loop archive.CloseArchive注意日期条件用了#包裹这是 VBS 内部 SQL 的标准写法。如果漏写#Filter 字符串会被当成纯文本比较永远匹配不到记录。时间范围也要算清楚DateAdd(d, -1, Date)返回的是日期类型再用FormatDateTime(..., 0)转成yyyy-mm-dd格式并与时间字符串拼接。这种追溯脚本跑完你还需要把结果展示出来常见做法是写到内部变量后触发报表画面刷新或者直接输出到 CSV 文件供车间存档。4.3 多客户端并发归档写锁与刷新策略WinCC 项目经常有多个操作员站同时在线。如果两块画面都打开了同一个用户归档并且其中一块通过脚本写数据另一块通过表格控件读数据你会遇到典型的“读旧写新”问题——写的那端能看到新记录读的那端表格不刷新甚至出现“文件被占用”的脚本报错。原因是用户归档在 WinCC 内部有自己的连接池和缓存多个客户端共享同一个归档数据库时锁粒度不一定是行级也可能是表级。我的处理经验是写数据的脚本必须“短连接”——打开、操作、立即关闭不要用全局变量长期保持归档对象。读取表格的控件刷新周期设到 1~2 秒而不是依赖手动刷新。如果项目里有多台操作员站同时高频写归档最好在逻辑上分时段分站写入避免同一秒内两个脚本同时 Update。对于极端的并发冲突脚本加上重试机制写失败后延时 200ms 再试一次能解决不少偶发报错。别迷信 WinCC 文档里说的“支持并发”实际项目里还是要做好锁和刷新的设计。5. 用户归档避坑手册5 个一次性学会的排查经验5.1 脚本写不进数据归档不是数据表而是被两个连接抢着占现象按钮脚本执行后没有报错归档表格里却没有新增记录。原因最常见的有三个。一是变量连接处的ConnectActive仍为 True脚本执行AddNew后周期连接立即把当前活动记录覆盖掉二是漏写了Recordset.Update数据还在内存缓冲区里三是脚本打开归档后没有CloseArchive上一次操作残留的句柄让新写入被拒绝。解决写入前先执行archive.ConnectActive False写入后立即archive.Update最后一定要archive.CloseArchive。如果你同时开了变量连接做周期填数那么脚本只负责创建空记录并设置批次号等业务键字段之后变量连接负责填充数值字段这是最不容易打架的分配方式。5.2 中文列名乱码WinCC 用户归档字段编码的取舍现象用户归档表格控件里显示的列标题是乱码或者脚本中用字段名字符串访问字段时返回 Empty。原因WinCC 归档字段的底层 SQL 语句和 VBS 脚本字符串之间的默认编码不完全一致。中文列名在组态界面里看着正常但脚本运行时拼接的 WHERE 或字段引用一旦经过系统内部转换就可能匹配不上。解决归档字段名从设计阶段就统一用英文显示标题放在画面上用多语言文本对象单独做映射。如果项目已经用中文建了字段并且数据量不大把归档删了重建是更快的方式比写脚本替换字段名靠谱。我见过有人写脚本逐条复制旧数据到新归档费时费力不如一开始按规范来。5.3 表格控件看不到新记录刷新模式与连接缓冲现象脚本成功写入归档画面上的用户归档表格控件还是显示旧数据重启画面才恢复。原因控件的刷新周期没有设置默认只在画面打开时读取一次或者刷新周期设成了 10 分钟。另外如果脚本和控件连接的不是同一个归档实例名也会出现“看着是同一个实际是两个不同连接”的情况。解决在控件属性里把刷新周期改成 1 秒或者在按钮脚本里调用控件的刷新方法。对大多数 WinCC 画面用户归档控件提供Refresh或更新连接的方法具体名称在帮助里搜 UserArchive Control。注意如果脚本把归档写完了你马上切画面再切回来表格控件会重新加载这时能看到新数据——这是验证“到底是没写进去还是没刷新”的最快方法。5.4 和 WinCC“找不到许可证”混在一起的事Comfort 与 Runtime Advanced现象TIA Portal V15.1 在编译或下载运行时提示“找不到许可证 wincc comfort”用户归档编辑器里按钮是灰的或者运行系统画面打开后控件不显示任何数据。原因WinCC 用户归档功能在 Runtime Advanced 和 Runtime Professional 中的授权逻辑不一样。你的项目组态选的是 Comfort 面板但安装的许可证是 WinCC Runtime Advanced反之亦然。这不是归档配置问题是授权的系统类型和项目类型没对齐。解决先在 TIA 项目树的“运行系统”属性里确认目标类型是 Comfort 还是 Advanced 或 Professional。再用 WinCC 的许可证管理器检查已经激活的版本。如果许可证类型与项目不匹配要么改项目运行系统类型要么按实际运行环境装对应授权。这个问题在初学者项目里出现频率极高和用户归档本身无关但一出现就会拦住你必须单独排查。5.5 停机后归档丢记录同步机制与断电保护现象生产期间归档有数据突然停电重启后最近几条记录找不到了历史趋势曲线也缺了一段。原因用户归档的写入机制带有缓冲系统每隔一定时间才把内存中的记录同步到数据库文件。断电瞬间缓存里未落盘的数据直接丢失。这和 WinCC 变量记录默认的存储周期是两回事变量记录的采集循环也可能丢数但用户归档因为是业务记录往往更让人在意。解决对关键记录比如批次结束确认不要只依赖周期变量连接应该在确认按钮脚本里同步执行一次写入并立即Update这样能缩短缓存窗口。此外可以定期把用户归档导出为 CSV 文件作为业务备份毕竟数据库文件损坏时手工恢复的成本远高于导出的成本。现场如果有条件给工控机配 UPS 是治本的办法但程序上做好同步写入和导出至少能保证记录不因断电全丢。6. 进阶技巧操作用户归档时字符串、时间和空值的三个细节用户归档的读写代码写多了你会发现真正折磨人的不是归档建得好不好而是数据类型细节。先说字符串。VBS 写入文本字段时WinCC 会把字符串按字段定义长度补满空白比如字段长度 20你存了 “B001”读出来可能是 “B001 ”。直接用If value B001比较永远不成立。我习惯在写入时做Trim读取时也做Trim双保险archive.Recordset.Fields(BatchNo).Value Trim(HMIRuntime.Tags(CurBatch).Read)时间字段的坑是脚本里返回的是浮点日期序列不是字符串。我用FormatDateTime统一格式后做比较避免“同一时刻”判断失败的玄学问题。空值处理更关键一条新记录如果没给某个字段赋值读取返回的是空字符串还是 0取决于字段类型。数值字段返回 0文本字段返回空字符串日期字段可能是 0 日期。做算术或逻辑判断前必须用IsNull或IsEmpty兜底否则一个空值直接让整个批次追溯功能崩掉。这三个细节我都是在项目现场用血泪经验换来的。用户归档本身不复杂复杂的是你永远不知道下一批数据里会出现什么样的空值和边界。写脚本时把 Trim、FormatDateTime、IsNull 养成肌肉记忆归档这条线基本就能稳稳跑住。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询