利用VB实现WinCC归档数据的复杂报表
(一)引言WinCC是目前使用最为广泛的工业组态软件之一,被广泛应用于各种工业控制系统的数据采集及监控应用系统中。它把所有的过程数据保存在其专用的Microsoft SQL Sever 2005数据库中,用户可以通过WinCC提供的OnlineTrend Control等控件对其进行访问,但不能对这些数据进行直接访问和处理。对于现场日趋复杂的数据分析统计的报表要求,显然已经不能满足。针对此问题,本文提出了通过VBS、WinCC OLE DB方法和SQL相结合的编程方法,实现对数据的重新归档及统计分析,以满足不同场合对报表的需求。(二)污水处理厂自控系统简介该污水处理厂出水量3万吨/日。全厂使用西门子PLC进行监视、控制和数据采集存储,自控系统框图如图1所示。上位机采用WinCC作为人机交互界面的软件平台。鉴于当地环保局和污水厂自身的要求,报表系统要具有日报、月报、季报、年报和按时间间隔查询的自由报表功能。Wincc本身自带的历史数据查询控件不能够满足要求,因此需要通过编程实现报表功能。https://p5.toutiaoimg.com/img/pgc-image/be6c187e3514466c8c3cdcd6cf661ba8~tplv-tt-shrink:640:0.image
图1:污水厂自控系统框图(三)报表生成过程3.1WinCC历史数据库的存储方式及常规访问方法WinCC在运行时,数据归档是以一定时间作为基准,形成数据片段。在数据片段下,与数据操作存储有关的表格主要有三个:ARCHIVE(用户归档记录);TAGPRESSED(TAGUNPRESSED)(压缩/非压缩变量归档记录) ;MSARCLONG(报警记录)这些表格不允许直接访问,ARCHIVE和TAGPRESSED(TAGUNPRESSED)也不允许修改,MSARCLONG通过控件允许插入/修改等。如果仅仅对数据进行简单的查询和报警报表的修正,我们可以通过WinCConline Talbe Control 和WinCC Alarm Control 控件实现,但控件访问格式固定,在用户对报表功能要求较高的时候显然是不适用的。3.2 利用WinCC OLE DB方法访问历史数据库从WINCC6.0开始,SIEMENS就采用SQL3000SP3做为WINCC的后台数据。SQL2000SP3采用了一些独特的技术,和常规的SQL访问的方法是有不同的。WINCC的SQL库操作是不需要表名的,他有自己定义的SQL语句,需要通过其特有的WinCCOLE DB进行访问。①定义连接字符串sPro ="Provider=WinCCOLEDBProvider.1;"sDsn ="Catalog=数据库名称;"sSer = "DataSource=.\WinCC"其中数据库名称为WinCC运行后自动生成的数据库名称,其余为固定格式。②利用连接字符串连接数据库Set conn =CreateObject("ADODB.Connection")conn.ConnectionString= sConconn.Open③数据查询oCom.CommandText="Tag:R,(A1,A2),'"+StTime.OutputValue+"','"+SpTime.OutputValue+"'"其中A1、A2为数据库中Achieve表中归档变量的ID。3.3 RecordSet记录集中的数据存储格式WinCC历史数据库中的数据通过WinCC OLE DB方法读出后存储在RecordSet记录集中。如果想要处理这些数据,首先需要知道它的存储方式,进而通过VBS编程对数据进行处理。图2为WinCC读取历史数据库数据至RecordSet并在WinCC Listview中显示。RecordSet每一条存储记录包括五列内容:①ValueID—WinCCARCHIVE表中变量的ValueID②Timestamp—变量存储时间③RealValue—变量值④Quality—质量数,表示数据的好坏⑤Flags—标志位
https://p3.toutiaoimg.com/img/pgc-image/c444040339474ef7a8b66aec113cd8bd~tplv-tt-shrink:640:0.image
图2:WinCC历史数据—RecordSet显示从图2中可以看出,第一列为变量ID,第二列为存储时间,第三列为变量值,这三列数据是我们所需要的。这些数据经过计算,就可以完成报表的各种功能了,例如计算累计值、平均值、最大最小值等。3.4 报表功能的实现利用RecordSet数据集中的数据,通过计算就能够生成日报、月报、季报和年报了。创建一个用户数据库,并建立日报表,月报表等需要的表格,并将计算后的数据存储在与其相对应的表格中,形成报表。根据用户查询的不同报表按钮连接不同的表格,获取数据,并生成用户所需要的报表。下面以月报为例进行介绍。月报实现每天生成一个平均数,根据月份不同生成30或31个数据。在SQLserver中创建一个用户数据库,命名为ReportData,在数据库中创建一个table,命名为Data-Month。在WinCC中创建一VBS全局脚本,此脚本运行时间间隔为10min,每条记录的时间格式为年—月—日00:00:00。每次日变量发生变化时,程序产生一条新的记录插入数据表中,否则程序只更新当前记录的数据内容。程序流程图如图3所示:https://p5.toutiaoimg.com/img/pgc-image/cc11827093da4d9f9c9b97e08b40be76~tplv-tt-shrink:640:0.image
图3:月报表程序流程图
下面介绍程序中各部分的具体实现。①打开WinCC历史数据库,将数据按时间要求读出,生成RecordSet对象。具体步骤在2.2中已经说明。图3为生成数据集之后,如何处理数据的程序流程图。https://p9.toutiaoimg.com/img/pgc-image/da734d06f1d5499096e2ff6658115425~tplv-tt-shrink:640:0.image
图4:计算功能程序流程图
②连接数据库WinCC中连接用户数据库与VB连接数据库的语法一致,在此不多做陈述,主要程序如下所示:sCon_1 ="Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist SecurityInfo=False;Initial Catalog=Baobiao_Month;Data Source=.\WINCC"conn_1.Open③新建数据记录新建数据记录时,Sum1、Sum2、Sum3是由步骤①中计算得到的strWork1 ="INSERT INTO ..[ Data-Month]"strWork2 ="(DateTime,temperature,press,height) "strWork3 ="VALUES('"+Date+"',"&(Sum1)&","&(Sum2)&","&(Sum3)&")"strWork = strWork1+ strWork2 + strWork3④更新数据记录当日期关键字没有改变时,程序仅更新当前记录,不会产生新的数据记录。strWork6 ="UPDATE ..[ Data-Month] "strWork7="SET temperature = "&(Sum1)&" ,press ="&(Sum2)&",height = "&(Sum3)&""strWork8 = "WHERE DateTime = '"+Date+"'"strWork5 =strWork6 + strWork7 + strWork8(四)报表查询过程经过上述步骤,报表数据库已经建立。日报表、月报表、季报表和年报表按照不同的时间间隔保存在不同的表中,接下来就可以在WinCC中利用按钮与DTPicker时间控件相结合的方法来进行数据查询了。按钮的功能是确定选择哪一张表格作为查询对象,DTPicker的功能是设置查询的起始时间和结束时间。DTPicker是微软提供的OCX控件,在WinCC中添加此控件。当用户通过该控件设置时间后,经过VB编程可以获得控件中设置的时间参数,之后按照此时间进行数据库查询。(五)运行结果报表系统已经在实际污水厂自控系统中正常运行使用,记录包括进水流量、出水流量、进水COD、出水COD、进水氨氮、出水氨氮、溶解氧、进水PH、出水PH、鼓风量以及污泥浓度十一个变量。系统中实现了日报表、月报表、季报表和年报表的查询以及累计值和平均值的计算。(六)结论本报表系统通过WinCCOLE DB方法连接WinCC历史数据库读取数据,并采用VBS和SQL相结合的编程方式,实现了数据的灵活访问,制作出满足污水厂要求的报表系统。利用此方法,我们可以制作出满足各行业要求的复杂报表系统,解决工程中关于报表的实际问题。
强烈支持楼主ing…… 楼主您的技术水准,我最服你,其他都是浮云 不请自来,就想夸一句:太顶了! 学到了学到了,这波分享太实用啦! 蹲一波同款,有没有小伙伴推荐? 原来还有这种操作,长见识了! 画面感太强了,仿佛身临其境! 来凑个热闹,为楼主增加点人气! 同款经历!我当初也这么过来的😂
页:
[1]
2