夜雨聆风学习资料网

ARTICLE · 1342679

WinCC 历史数据导出 Excel 的三种做法,附完整脚本

WinCC 历史数据导出 Excel 的三种做法,附完整脚本

数据本来就在 WinCC 归档库里,导不出来多数是没找对接口。三种做法按数据量和工作量选,脚本可直接照抄。

月底给质量部交生产数据,很多同事还在翻画面手抄。其实数据都在 WinCC 归档里,缺的只是导出的办法。

01 现象:报表要历史数据,画面里没有导出按钮

现场基本都遇过这三件事:

  • 质量追溯要原始数据。审核来了要某天某小时的温度、压力记录,画面趋势能看,但把一个月的数据拿成表格,没人愿意手工抄。
  • 领导要看日报。每天早上八点要一版前一天的过程数据汇总,格式固定,最好自动生成,不要人守着。
  • 第三方系统要接数据。MES、能源管理要历史数据,接口一问三不知,最后变成"你先导个 Excel 给我"。

这个问题拖久了很贵:追溯拿不出数据,审核扣分;日报靠人手抄,抄错一次,第二天全班组对数。数据其实一直躺在归档里,只是没人给它开个口子。

这三件事对应三种做法:定时记录用全局脚本写 CSV,补历史数据用 OLE DB 直查归档库,固定格式报表交给报表模板。先选对路,再写代码。

02 三种方案怎么选:一张对比表

把三条路拉到一张表里:

做法
数据来源
开发工作量
灵活性
适用场景
全局脚本写 CSV
实时值(触发时刻的当前值)
低,十几行 VBS
只能记当下
过程流水、班次记录
OLE DB 直查归档库
变量记录的历史归档
中,需掌握查询语法
高,任意时间段、任意归档变量
历史导出、质量追溯
报表与控件导出
归档库或报表数据源
低,组态为主
格式受模板限制
固定格式日报月报

动手前先估算数据量:5 个变量按 1 分钟周期记一行,一天 1440 行、一个月四万行出头,CSV 装得下;要是 1 秒周期的十几个变量,一天就是上百万行,靠逐行追加 CSV 明显吃力,这种量级要么查归档库,要么放宽归档周期。

选型一句话:数据量小、只记当下,用方案一;要任意时间段的历史,用方案二;格式固定、要现成 Excel 版式,用方案三。三条路不互斥,很多项目是方案一在线记加方案二补查的组合。

03 方案一:全局脚本定时写 CSV,十几行 VBS 上线

思路:在 WinCC 全局脚本(VBS)里建一个周期动作,比如每 1 分钟触发一次,读当前变量值,追加到按日期切分的 CSV 文件。组态路径:打开全局脚本编辑器新建 VBS 动作,贴入代码;在动作的触发器里新建"周期"触发,周期设 1 分钟;再在计算机启动属性里确认全局脚本模块已勾选,激活运行系统即生效。

注意它记的是触发那一刻的实时值,不是从归档取数,相当于在归档之外旁路再记一份轻量流水。触发周期要与记录需求对齐:要秒级数据就别配 1 分钟;反过来说,只是为了月底对账,也没必要每秒导一行。

' WinCC 全局脚本(VBS)周期动作:每 1 分钟追加一行到 CSVOptionExplicitDim fso, logFile, logPath, nowStr' 1. 按日期切分文件,每天一个logPath = "D:\Export\ProdData_" & Year(Date) & _Right("0" & Month(Date), 2) & Right("0" & Day(Date), 2) & ".csv"Set fso = CreateObject("Scripting.FileSystemObject")IfNot fso.FolderExists("D:\Export") Then fso.CreateFolder("D:\Export")' 2. 新文件先写表头IfNot fso.FileExists(logPath) ThenSet logFile = fso.CreateTextFile(logPath, True, False)  ' False=ASCII    logFile.WriteLine "Time,Temp,Press,State"    logFile.CloseEndIf' 3. 读变量,追加一行nowStr = Year(Now) & "-" & Right("0" & Month(Now), 2) & "-" & _Right("0" & Day(Now), 2) & " " & Right("0" & Hour(Now), 2) & _":" & Right("0" & Minute(Now), 2) & ":" & Right("0" & Second(Now), 2)Set logFile = fso.OpenTextFile(logPath, 8, True)  ' 8=追加,True=不存在则创建logFile.WriteLine nowStr & "," & _    HMIRuntime.Tags("TI_101_Temp").Read & "," & _    HMIRuntime.Tags("PI_102_Press").Read & "," & _    HMIRuntime.Tags("ST_103_State").ReadlogFile.CloseSet logFile = NothingSet fso = Nothing

三个细节:

  • 文件按日期切分,月底交付直接拷当月文件,避免单文件过大打开卡死。
  • OpenTextFile 第二个参数 8 是追加模式,第三个参数 True 表示不存在就创建。
  • 正式项目建议把路径和变量名做成配置读进来,别硬编码在脚本里。

验证方法:跑满一天,用 Excel 打开核对行数是否等于预期触发行数(1 分钟周期就是 1440 行),再抽几个时间点和画面趋势对数值。断电或异常中断可能留下半行脏数据,月底交付前过一遍空行和异常值。

04 方案二:OLE DB 直查归档库,任意时间段任意变量

原理一句话:经典 WinCC 运行时把变量记录写进本机 SQL Server 实例(默认实例名 计算机名\WinCC),运行库以 CC_ 开头;西门子提供的 OLE DB Provider(WinCCOLEDBProvider.1)是这套库的只读查询接口,任何能用 ADODB 的语言都能调。

动手前先确认两件事:一是变量记录里这些变量确实开了归档,没归档的变量在库里一行都查不到;二是归档分段周期和保留时间,它们决定你能查到多久以前的数据。

连接串三要素:Provider 固定写 WinCCOLEDBProvider.1,Catalog 填运行库名,Data Source 填计算机名加实例。运行库名在项目每次重新生成后会变,用 SQL Server Management Studio 连上实例看一眼最稳妥,现场以实际库名为准。

' WinCC 全局脚本(VBS):OLE DB 直查归档库,导出两个变量一天的历史OptionExplicitDim conn, rs, sql, catalogName' 1. 运行库名形如 CC_项目名_计算机名_日期_时分秒,以现场实际为准catalogName = "CC_DemoLine_PC01_2026_11_01_08_30_00"Set conn = CreateObject("ADODB.Connection")' 2. 连接串:Provider 固定,Catalog=运行库,Data Source=计算机名\WinCCconn.Open "Provider=WinCCOLEDBProvider.1;" & _"Catalog=" & catalogName & ";" & _"Data Source=PC01\WinCC"' 3. TAG:R 查询:变量名分号分隔;时间段是 UTC(北京时间要减 8 小时);tsasc=1 升序sql = "TAG:R,'TI_101_Temp;PI_102_Press'," & _"'2026-11-09 16:00:00.000'," & _"'2026-11-10 15:59:59.000'," & _"'tsasc=1'"Set rs = conn.Execute(sql)DoWhileNot rs.EOF' 字段:ValueID、TimeStamp、RealValue、Quality 等' Quality 不好的点在这里过滤,别导进表里    rs.MoveNextLooprs.Closeconn.Close

四个关键点:

  • TAG:R 是查归档的固定语法,单引号内用分号分隔归档变量名,后接起止时间,tsasc=1 表示按时间升序。
  • 时间参数是 UTC,不是本地时间,这是这套接口最大的坑,下一节细说。
  • 返回结果集里有 ValueID、TimeStamp、RealValue、Quality 等字段,Quality 不好的点要过滤,否则表里混着坏值。
  • 这是只读接口,别拿它去写库;大批量查询别放在产线高峰期跑。

还有一个编号问题:返回里的 ValueID 是归档库内部的变量编号,项目重新生成后会变,所以脚本里尽量用变量名查询,别把 ValueID 写死在代码里。

05 方案三:报表与控件导出,低代码但有模板天花板

如果需求就是每天一张固定格式的 Excel,用经典 WinCC 自带的报表能力比写脚本划算:

  1. 报表系统:用 Excel 做模板,通过 ODBC/OLE DB 数据源连归档库,配合打印作业定时生成,适合日报月报。
  2. 归档控件导出:在线趋势、表格控件自带导出功能,操作员手动导一段数据给客户,最省事。
  3. 上位机直连:C# 或 Python 直接连 WinCC 的 SQL Server 实例读归档,灵活度最高,这是上位机专栏的话题,之后单独写一篇。

我的经验:操作员手动场景用控件导出,定时自动的日报用报表系统,要自由格式和数据再加工才上脚本或上位机。别一上来就写代码,能用组态解决的,维护成本最低。

局限也要说清楚:模板格式改一次就要重配一次,批量自动化能力有限;报表组件的授权和版本支持差异大,组态前先确认你手上这套 WinCC 版本有没有装、可不可用,现场以实际版本为准。

06 验证与踩坑:时区、编码、分段三道坎

三种做法各自的坑不一样,把最高频的四个列出来:

坑
典型现象
处理办法
时区
按本地时间查 OLE DB,查不到对应时段的数据
查询参数与返回时间都是 UTC,北京时间减 8 查、加 8 显示
编码
CSV 用 Excel 打开中文乱码、不切列
表头用英文;或用 ADODB.Stream 写 UTF-8 带 BOM
文件占用
Excel 开着导出文件,脚本追加报错
导出目录独立,脚本加错误处理并记日志
归档分段
跨月查询数据不全、报表对不上
变量记录分段存储,跨段逐段查询再合并

时区这个坑值得单独展开:OLE DB 的查询和返回时间都是 UTC。要查北京时间 11 月 10 日 0 点到 24 点,参数应写 11 月 9 日 16:00 到 11 月 10 日 15:59:59,返回的 TimeStamp 同样加回 8 小时再给人看。判断是不是时区问题很简单:数据总是差 8 小时,就是它。

编码的坑在 FSO:CreateTextFile 第三个参数 True 是 UTF-16,Excel 双击打开这种 CSV 不会按逗号切列;False 是 ASCII,中文表头必乱。简单做法表头用英文,讲究一点用 ADODB.Stream 写 UTF-8 带 BOM。

最后一条纪律:别在运行服务器上做重查询。要大批量导历史,安排在非生产时段,或者从备份段上查,别拖累画面刷新。

上线前做一轮验证:先按 OLE DB 查一天的数据,和画面趋势对几行关键值,时间戳、数值、小数位都对上,再放开跑;第一个月每周核对一次导出行数,确认没有因为异常中断丢过数据。

结语

一句话结论:在线记流水用全局脚本写 CSV,补历史数据用 OLE DB 查归档库,固定报表交给模板——先把接口找对,再纠结格式。你们车间的生产数据报表现在靠什么导出来的?评论区聊聊。

回首页,搜索你想要的文档

在首页搜索框输入关键词,快速定位资料

文库首页搜索指引 立即搜索

相关学习资料