WinCC用户归档实战:从建表到SQL直查,解决产线追溯数据存储难题
发布时间:2026/10/1 14:43:30来源:尧图网络
简介这份资源是面向工业自动化工程师与WinCC学习者的用户归档实践案例包聚焦西门子WinCC中动作Actions与标准模块Standard Modules的协同使用帮助解决实时数据存储、历史归档与后期报表分析等实际问题。压缩包共290个文件约36.21MB以250个rpl归档数据文件为主另含mdf、ldf数据库文件、dum、sav、ini配置、pdl画面、xml、cfg及bac、bmo、cvb等脚本与模块文件覆盖归档数据、项目配置与可复用代码单元。目前已有1149人学习下载。通过案例中的示例项目与脚本读者可掌握归档触发条件设置、数据过滤与压缩模块调用、归档间隔与保留期限设计等关键环节并理解动作与标准模块配合提升项目效率的思路适合具备一定WinCC基础、希望深入数据管理的中高级用户参考模仿。1. 从一次产线追溯翻车说起WinCC 用户归档到底能干什么去年帮一家做汽车零部件的老厂做产线追溯对方工程师拍胸脯说“WinCC 记录都存着呢”结果客户要查三个月前某个批次的热处理温度曲线打开趋势控件一片空白——历史数据只留了七天报警记录倒是存了半年。这种“以为存了其实没存对地方”的翻车在工控现场太常见了。WinCC 用户归档User Archive就是专门解决这类问题的它不依赖变量记录系统的循环归档而是让你自己定义表结构、自己决定什么时候写、写多少、留多久把配方参数、批次数据、质检结果这类“业务数据”真正落到 SQL Server 里。适合谁做 MES 对接的、搞配方管理的、需要按批次追溯的自动化工程师。如果你还在用变量记录硬扛生产数据这篇拆解值得看完。2. 用户归档和变量记录到底差在哪选型前必须搞清的底层逻辑2.1 变量记录是“录像机”用户归档是“数据库表”WinCC 变量记录系统Tag Logging本质是个时序数据库它按你设定的采集周期和归档周期把变量值一条条塞进归档库。查询靠趋势控件或 OnlineTrendControl适合看曲线、做监控大屏。但它有两个硬伤第一表结构固定就是时间戳数值质量码你想存个“批次号”“操作员”“配方版本”进去没地方放第二归档周期和分段规则一旦设错要么数据被覆盖要么数据库膨胀到 SQL Server 直接罢工。用户归档User Archive走的是另一条路。你在 WinCC 里建一张“归档表”字段名、字段类型、主键、索引全由你定WinCC 在 SQL Server 里给你建对应的物理表。写入靠脚本触发读出来可以绑控件、可以导 CSV、可以用 SQL 直查。说白了变量记录是“系统帮你记”用户归档是“你自己决定怎么记”。2.2 什么时候必须上用户归档判断标准很简单数据需不需要按“业务对象”组织。比如配方管理每个配方有编号、名称、十个参数值、创建时间、修改人。变量记录存不了这种结构。批次追溯每批产品有批次号、开始时间、结束时间、关键工艺参数、质检结果。需要按批次号反查。报警确认记录谁在什么时候确认了哪条报警确认原因是什么。报警归档系统只管报警本身不管确认动作的业务属性。如果只是看温度曲线、压力趋势变量记录够用。但凡涉及“按条件筛选”“导出报表”“和 MES 交换数据”用户归档是绕不过去的。2.3 建表前先想清楚三件事第一主键怎么设。用户归档表必须有一个主键可以是自增 ID也可以是业务字段组合。我一般用“自增 ID 业务唯一键”双保险自增 ID 给 WinCC 内部用业务唯一键给外部查询用。第二字段类型怎么选。WinCC 用户归档支持的字段类型有限整型、浮点、字符串、日期时间、布尔。别想着存二进制大对象要存图片路径就存字符串。第三数据保留策略。用户归档不会自动删旧数据你得自己写脚本定时清理或者在 SQL Server 里建维护计划。我见过一个项目跑了两年用户归档表 800 万行查询一次要十几秒最后只能停机清表。提示建表时字段名不要用中文不要用 SQL 关键字如 Order、Group否则生成 SQL 语句时会报语法错误。3. 手把手建一张用户归档表从 WinCC 组态到 SQL 落库3.1 在 WinCC 里创建归档表和字段打开 WinCC 项目在“用户归档”编辑器里右键新建归档。命名规则建议用英文下划线比如UA_BatchRecord。然后逐个添加字段字段名类型长度说明BatchID字符串32批次号业务主键ProductCode字符串16产品编码TempValue浮点-关键温度值Operator字符串16操作员CreateTime日期时间-记录创建时间IsQualified布尔-是否合格建完后点击“保存”WinCC 会在 SQL Server 的CC_项目名数据库里生成一张同名表。你可以用 SSMS 连上去确认表名一般是UA_BatchRecord字段名和你在 WinCC 里定义的一致。3.2 用 C 脚本写入一条归档记录WinCC 用户归档的写入靠UAArchiveWrite函数。下面这段 C 脚本挂在“保存批次”按钮的鼠标点击事件上// 写入用户归档记录 #include apdefap.h void OnClick(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName) { // 声明归档句柄 long hArchive; // 打开归档参数为归档名称 hArchive UAArchiveOpen(UA_BatchRecord); if (hArchive 0) { // 打开失败写诊断消息 printf(打开用户归档失败错误码%d\r\n, hArchive); return; } // 设置字段值 UAArchiveSetFieldValue(hArchive, BatchID, GetTagChar(BatchNo)); UAArchiveSetFieldValue(hArchive, ProductCode, GetTagChar(ProductCode)); UAArchiveSetFieldValue(hArchive, TempValue, GetTagFloat(TempValue)); UAArchiveSetFieldValue(hArchive, Operator, GetTagChar(CurrentUser)); UAArchiveSetFieldValue(hArchive, CreateTime, GetSystemTime()); UAArchiveSetFieldValue(hArchive, IsQualified, GetTagBit(IsQualified)); // 执行写入 long ret UAArchiveWrite(hArchive); if (ret ! 0) { printf(写入用户归档失败错误码%d\r\n, ret); } // 关闭归档句柄 UAArchiveClose(hArchive); }逻辑说明UAArchiveOpen返回一个句柄后续所有操作都基于这个句柄。UAArchiveSetFieldValue逐个字段赋值注意类型要匹配——字符串字段用GetTagChar浮点用GetTagFloat布尔用GetTagBit。UAArchiveWrite执行实际写入返回 0 表示成功。最后必须UAArchiveClose否则句柄泄漏跑几百次后 WinCC 会卡死。参数说明UAArchiveOpen的参数是归档名称必须和你在用户归档编辑器里建的名字完全一致大小写敏感。UAArchiveSetFieldValue的第二个参数是字段名第三个参数是值。如果字段类型不匹配写入会失败但不报错数据静默丢失——这是最坑的地方。3.3 用 DataGrid 控件展示归档数据建完表、能写入之后下一步是把数据展示出来。WinCC 自带一个WinCC UserArchive Control但界面丑、功能弱。我一般用Microsoft DataGrid Control或者WinCC OnlineTrendControl的表格模式。绑定步骤在画面里插入 DataGrid 控件右键属性在“数据源”里选择“用户归档”然后选UA_BatchRecord。字段列会自动带出来你可以调整列宽和显示顺序。如果要加筛选条件比如只显示合格批次在 SQL 查询里加WHERE IsQualified 1。-- 在 DataGrid 的 SQL 属性里写查询语句 SELECT BatchID, ProductCode, TempValue, Operator, CreateTime FROM UA_BatchRecord WHERE IsQualified 1 ORDER BY CreateTime DESC注意WinCC 用户归档表的物理表名可能带前缀具体看 SQL Server 里的实际表名。如果查询报“表不存在”去 SSMS 里确认一下。3.4 导出 CSV 给 MES 或质检部门用户归档的数据最终要给别人用。WinCC 自带导出功能但格式固定、不能筛选。我一般写个按钮脚本用UAArchiveExport导出指定条件的数据// 导出合格批次到 CSV void OnClick(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName) { long hArchive UAArchiveOpen(UA_BatchRecord); if (hArchive 0) return; // 设置筛选条件 UAArchiveSetFilter(hArchive, IsQualified 1); // 导出到指定路径 long ret UAArchiveExport(hArchive, D:\\Export\\BatchRecord.csv, 1); if (ret ! 0) { printf(导出失败错误码%d\r\n, ret); } UAArchiveClose(hArchive); }参数说明UAArchiveExport的第三个参数 1 表示导出为 CSV0 表示导出为 XML。导出路径必须是 WinCC 运行账户有写权限的目录否则静默失败。我一般先在资源管理器里手动建好D:\Export文件夹并给 Everyone 写权限。4. 避坑指南用户归档最常见的五个翻车现场4.1 现象写入返回成功但数据库里没数据原因字段类型不匹配。比如你把一个浮点数写进了字符串字段UAArchiveWrite返回 0但 SQL Server 里那条记录的该字段是 NULL。WinCC 不做类型校验这是设计缺陷。解决写入前用UAArchiveGetFieldType检查字段类型或者在脚本里做显式转换。更稳妥的做法是建表时字段类型就选对别指望运行时转换。4.2 现象归档表越来越大查询越来越慢原因用户归档没有自动清理机制。变量记录可以设归档周期和分段大小用户归档不行数据只进不出。解决写个定时脚本每天凌晨删掉 90 天前的记录。或者在 SQL Server 里建维护计划直接对物理表执行 DELETE。注意直接删物理表数据不会影响 WinCC 运行但删之前最好停掉归档写入。-- 在 SQL Server 里建定时任务删除 90 天前的数据 DELETE FROM UA_BatchRecord WHERE CreateTime DATEADD(DAY, -90, GETDATE());4.3 现象多用户同时写入时数据错乱原因用户归档的写入不是事务安全的。两个操作员同时点“保存”可能一个写入成功另一个被覆盖或者两条记录的主键冲突。解决主键用自增 ID别用业务字段。写入前加互斥锁WinCC 里可以用SetTagBit做一个简单的信号量。更彻底的做法是把写入请求发给后台服务由服务串行化处理。4.4 现象WinCC 重启后归档句柄失效原因UAArchiveOpen返回的句柄在 WinCC 重启后全部失效但脚本里可能缓存了旧句柄。解决每次写入都重新UAArchiveOpen不要全局缓存句柄。虽然多一次打开操作但避免了句柄失效导致的静默失败。4.5 现象导出 CSV 中文乱码原因WinCC 默认用 ANSI 编码导出Excel 打开时按 UTF-8 解析就乱码。解决导出后用 PowerShell 转码或者在脚本里先写 UTF-8 BOM 头。我一般用 PowerShell 一行搞定# 把 ANSI 编码的 CSV 转成 UTF-8 Get-Content D:\Export\BatchRecord.csv | Set-Content -Encoding UTF8 D:\Export\BatchRecord_UTF8.csv5. 进阶用 SQL Server 直查用户归档表做报表和 MES 对接5.1 为什么绕开 WinCC 直接查 SQL ServerWinCC 的 DataGrid 控件做展示还行做复杂报表就力不从心了。质检部门要按产品编码分组统计合格率生产部门要按班次汇总产量这些用 SQL 语句几行就搞定用 WinCC 脚本写要命。而且 MES 系统对接时对方不可能装 WinCC直接给数据库连接字符串最省事。5.2 找到用户归档的物理表WinCC 项目对应的数据库名一般是CC_项目名_时间戳比如CC_Line1_20240101。用户归档表就在这个库里表名和你在 WinCC 里建的名字一致。用 SSMS 连上去展开“表”找到UA_BatchRecord右键“选择前 1000 行”确认数据在。如果找不到检查两个地方第一WinCC 项目是否处于运行状态用户归档表只在运行时才在 SQL Server 里可见第二SQL Server 实例名是否正确WinCC 默认用.\WINCC实例。5.3 写一个按班次汇总的 SQL 查询假设你要统计每个班次的合格率班次划分是早班 8:00-16:00中班 16:00-24:00晚班 0:00-8:00。SQL 如下-- 按班次统计合格率 SELECT CASE WHEN DATEPART(HOUR, CreateTime) 8 AND DATEPART(HOUR, CreateTime) 16 THEN 早班 WHEN DATEPART(HOUR, CreateTime) 16 THEN 中班 ELSE 晚班 END AS ShiftName, COUNT(*) AS TotalCount, SUM(CASE WHEN IsQualified 1 THEN 1 ELSE 0 END) AS QualifiedCount, CAST(SUM(CASE WHEN IsQualified 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS DECIMAL(5,2)) AS QualifiedRate FROM UA_BatchRecord WHERE CreateTime DATEADD(DAY, -7, GETDATE()) GROUP BY CASE WHEN DATEPART(HOUR, CreateTime) 8 AND DATEPART(HOUR, CreateTime) 16 THEN 早班 WHEN DATEPART(HOUR, CreateTime) 16 THEN 中班 ELSE 晚班 END ORDER BY ShiftName;这个查询可以直接丢给报表工具比如 FineReport、Power BI也可以做成存储过程让 MES 调用。注意IsQualified字段在 SQL Server 里是 bit 类型1 表示合格0 表示不合格。5.4 用视图简化 MES 对接MES 系统一般只读不写给它建个视图只暴露需要的字段避免它直接查基表-- 创建给 MES 用的视图 CREATE VIEW V_MES_BatchRecord AS SELECT BatchID, ProductCode, TempValue, Operator, CreateTime, CASE WHEN IsQualified 1 THEN 合格 ELSE 不合格 END AS QualityStatus FROM UA_BatchRecord WHERE CreateTime DATEADD(DAY, -30, GETDATE());视图的好处是MES 只能看到最近 30 天的数据减少查询压力字段名用英文避免编码问题IsQualified转成中文MES 那边不用做映射。5.5 一个我踩过的坑SQL Server 账户权限WinCC 安装时会创建一个WinCCConnect账户用户归档的读写都走这个账户。如果你用 SSMS 直查用 Windows 身份验证可能看不到数据因为权限不够。解决办法用sa账户或者给WinCCConnect授予db_datareader权限。-- 给 WinCCConnect 账户授予读权限 USE CC_Line1_20240101; CREATE USER [WinCCConnect] FOR LOGIN [WinCCConnect]; ALTER ROLE db_datareader ADD MEMBER [WinCCConnect];从那以后我每次建用户归档表都强制走一遍“建表→写脚本→导出验证→SQL 直查”四步确认数据真的落库了才继续往下做。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网