在实际应用中,客户对于wincc变量记录的显示需求各式各样,比如在excel或者word中显示变量记录,以特定的表格显示历史数据等等。当wincc集成的在线表格控件不能满足客户需要时,就需要通过自定义的方式来显示变量归档。主要分为两部分:
(1)从wincc中读取归档数据
(2)将归档数据以特定的格式显示出来
本文档介绍从wincc读取归档数据的通用方法,并以listview为例,介绍如何显示归档数据。对于其它控件,客户也可以参考本文档的脚本和编程思路。
1.测试环境
本文档基于wincc v7.0 asia,并通过ms windows common controls 6.0 listview 控件来显示读取的归档数据。需要的授权如下:
授权名称
个数
备注
wincc rc v7.0
1
wincc连通性软件包v7.0
1
订货号为:6av6371-1dr07-0ax0,授权通过wincc ole db访问过程值归档。
表 01
2.实现方式总体思路介绍
本文档通过调用wincc ole db数据库接口驱动(需要wincc连通性软件包的授权)来访问wincc的变量归档,并在微软的listview控件中显示归档数据。程序结构如下所示:
图1
其中,自定义函数的说明如下表所示:
函数名称
功能
winccdatasourceaccess(connobj, psql)
建立到数据库的连接。参数connobj为连接对象(adodb.connection),参数psql为要执行的sql查询语句
winccdatasourceclose(precordset, connobj)
断开与数据库的连接,释放资源。参数precordset为adodo.recordset对象,参数connobj为连接对象(adodb.connection)
addlistviewheadercolumn(precordset, plistview)
添加listview的列名。参数precordset为adodo.recordset对象,参数plistview为listview对象
filllistview (precordset, plistview)
参数precordset为adodo.recordset对象,参数plistview为listview对象。
表 02
具体代码见附件。
3.具体实现方法和代码
3.1 创建到归档数据库的连接
由于wincc的变量归档为压缩数据,所以必须通过wincc ole db来读取归档数据。对于已经安装wincc的计算机,不需要安装wincc连通性软件包。对于未安装wincc的客户端,必须安装wincc连通性软件包。该软件包含在wincc v7.0的安装光盘中。
数据库连接的脚本如下所示:
'定义数据库连接变量
dim conn
set conn = createobject(adodb.connection)
'定义数据库查询脚本(可以根据需要自定义修改)
dim ssql
ssql=tag:r,'processvaluearchive\tag1','0000-00-00 00:01:00.000','0000-00-00 00:00:00.000'
'通过调用自定义的数据库连接函数,建立与数据库的连接
dim ors
set ors= winccdatasourceaccess(conn,ssql)
其中,自定义的数据库连接函数winccdatasourceaccess(connobj,psql),参数connobj为连接对象(adodb.connection),参数psql为要执行的sql查询语句,具体代码如下所示:
function winccdatasourceaccess(connobj,psql)
'建立到数据库的连接
on error resume next
'读取本地的wincc运行数据库名称
dim datasourcenamert,dataconnectionname
set datasourcenamert = hmiruntime.tags(@datasourcenamert)
datasourcenamert.read
'定义数据库连接字符串
dim spro, sdsn,sser
spro = provider=winccoledbprovider.1;
sdsn = catalog= & datasourcenamert.value & ;
sser = data source=.\wincc
dataconnectionname = spro + sdsn + sser
' 定义查询语句字符串
dim ssql
ssql=psql
'建立连接
dim ors,ocom,conn
set conn = createobject(adodb.connection)
set conn=connobj
conn.connectionstring = dataconnectionname
conn.cursorlocation = 3
conn.open
' 创建查询的命令文本
set ors = createobject(adodb.recordset)
set ocom = createobject(adodb.command)
ocom.commandtype = 1
set ocom.activeconnection = conn
ocom.commandtext=ssql
'执行查询
set ors = ocom.execute
'返回结果
set winccdatasourceaccess=ors
if err.number <> 0 then
msgbox error code & err.number & source: & err.source & error description & err.description
err.clear
end if
on error go to 0
end function
自定义函数的创建过程为:在wincc项目管理器中右键点击全局脚本打开vbs全局脚本编辑器项目函数新建函数。具体如下图所示:
图2
3.2 注册microsoft listview control 6.0控件
打开wincc图形编辑器。在右侧的对象选项板中单击“控件”,选中“activex control”,点击右键,选择“添加移除”。在弹出菜单中,选择“microsoft listview control 6.0”,点击“ok”确认。
图3
之后,将“microsoft listview control 6.0”拖动到画面编辑器中,并将对象名称设置为control1。
注意:在脚本中,当定义listview对象时用到对象名称control1。详情请参考图1的步骤2。
3.3 添加listview 控件的列名
在listview中添加列名,步骤如图1的步骤3。自定义函数addlistviewheadercolumn(precordset, plistview)的具体代码如下所示:
function addcolumnheader(precordset, plistview)
'添加listview列名
'用于错误捕获和处理
on error resume next
dim ors,columncount
set ors=createobject(adodb.recordset)
set ors=precordset
'获取数据库中的列数
columncount=ors.fields.count
'定义操作的listview对象
dim listviewt
set listviewt=plistview
'清空listview对象的列数
listviewt.columnheaders.clear
'用查询的数据库表格列名来为listview添加列名(*2)
dim addcolumnindex
for addcolumnindex=0 to columncount-1
listviewt.columnheaders.add , , cstr(ors.fields(addcolumnindex).name)
next
'发生错误,提示消息框
if err.number <> 0 then
msgbox addcolumnheader函数报错,source: & err.source & vbcr & error description: & err.description
err.clear
end if
on error goto 0
end function
3.4 填充listview 控件
在listview中添加列名,步骤如图1的步骤4。自定义函数filllistview (precordset, plistview) 的具体代码如下所示:
function filllistview(precordset,plistview)
'用数据库查询的值填充listview
on error resume next
'获取查询记录条数
dim recordscount,ors
set ors=createobject(adodb.recordset)
set ors=precordset
recordscount=ors.recordcount
'定位到第一条记录
if (recordscount > 0) then
ors.movefirst
'定义最大的查询条目(*3)
dim maxline,n
maxline = 10
n=0
'填充数据值列
do while (not ors.eof and n < maxline)
n = n + 1
dim oitem,listviewt
set listviewt=plistview
set oitem = listviewt.listitems.add()
oitem.text = ors.fields(0).value
oitem.subitems(1) = ors.fields(1).value
oitem.subitems(2) = formatnumber(ors.fields(2).value, 4)
oitem.subitems(3) = hex(ors.fields(3).value)
oitem.subitems(4) = hex(ors.fields(4).value)
ors.movenext
loop
3.5 关闭到归档数据库的连接
关闭与数据库的连接并释放资源,步骤如图1的步骤5。自定义函数winccdatasourceclose(precordset, connobj)的具体代码如下图所示:
function winccdatasourceclose(precordset,connobj)
'关闭数据库连接,释放资源
'获取连接和查询对象
dim ors,conn
set ors=precordset
set conn=connobj
ors.close
set ors = nothing
conn.close
set conn = nothing
end function
3.6 运行结果
本文档介绍的脚本,其运行结果如下图所示:
图4
3.7 更改代码以满足更广泛的需求
对于不同客户的定制化需求,可以通过修改少量代码实现。
(1) 不同的查询需求,修改ssql变量的值。
'修改变量ssql的值
dim ssql
ssql=tag:r,'processvaluearchive\tag1','0000-00-00 00:01:00.000','0000-00-00 00:00:00.000'
比如,如果需要动态制定查询时间,可以在画面中输入查询日期,然后通过hmiruntime.tags(“变量名”)来获得查询条件,再赋值给ssql。
(2) listview需要使用不同的列名。
修改函数addlistviewheadercolumn中的如下内容:
‘用查询的数据库表格列名来为listview添加列名 (*2)
dim addcolumnindex
for addcolumnindex=0 to columncount-1
listviewt.columnheaders.add , , cstr(ors.fields(addcolumnindex).name)
next
(3) listview需要填充不一样的行数和内容。
修改函数filllistview中的如下内容:
dim maxline,n
maxline = 10 '改变此值,可以更改最大显示的条目数
n=0
'修改填充内容,请修改下面do while循环中的代码
do while (not ors.eof and n < maxline)
n = n + 1
dim oitem,listviewt
set listviewt=plistview
set oitem = listviewt.listitems.add()
oitem.text = ors.fields(0).value
oitem.subitems(1) = ors.fields(1).value
oitem.subitems(2) = formatnumber(ors.fields(2).value, 4)
oitem.subitems(3) = hex(ors.fields(3).value)
oitem.subitems(4) = hex(ors.fields(4).value)
ors.movenext
loop
本文档中提供的脚本尽量通用化,方便客户修改和复用。并加入了错误处理机制,保证脚本的正确运行,并提高了诊断的方便性。
声明:
本文所述的方法为wincc的高级用法,提供的代码程序仅供用户参考,西门子公司不提供任何调试和热线支持。敬请谅解!