今天分享几种使用脚本访问iFIX数据的方法。
使用过iFIX的朋友都知道,有时要实现某些功能,需要在脚本里处理如何读写数据库标签数值问题。大家可能常用的就是使用"="号了,或者使用"WriteValue"和"ReadValue"子程序。在这除了以上两种方式外,另外分享使用"FindObject方法"和"FixDataSystem对象"这两种方法。
1、使用Fix32对象读写数据库标签数值(也就是使用"="号)
脚本相对简单,不做详细说明,主要说些使用注意事项。
- 做好错误处理跳转的原因:
当出现iFIX与PLC通讯中断(数值为:????)、客户端与服务器通讯中断(数值为:@@@@)等此类情况时,软件会弹出错误,还有可能跳转到脚本编辑窗口,如图所示。
iFIX与PLC通讯中断(数值为:????)情况:
客户端与服务器通讯中断(数值为:@@@@)情况:
对于熟悉iFIX软件的工程师来说当然知道应该如何处理,但对于一般操作员来说任何错误弹窗(特别是跳转到脚本窗口)将会无法应对。
- 错误处理
第一种处理方式:当发生错误时直接跳出;
Private Sub CommandButton1_Click()
On Error GoTo ErrorHandler
Fix32.fix1.TAG_12.F_CV = 1
Exit Sub
ErrorHandler:
End Sub
第二种处理方式:当发生错误时跳转到自定义错误提示窗口,告知操作员,但此窗口不会跳转到脚本编辑窗口:
Private Sub CommandButton1_Click()
On Error GoTo ErrorHandler
Fix32.fix1.TAG_12.F_CV = 1
Exit Sub
ErrorHandler:
MsgBox "Error " + Str(Err.Number) + " has occurred" + Chr(10) + Chr(13) + Err.Description + Chr(10) + Chr(13) + Chr(10) + Chr(13) + "请联系工程师处理!!!", vbCritical
End Sub
2、使用"WriteValue"和"ReadValue"子程序
与第一种方法一样需要做错误处理,下面提供一个简单例子参考:
WriteValue
Private Sub CommandButton3_Click()
On Error GoTo ErrorHandler
WriteValue 1, "Fix32.Liang.TAG_12.F_CV", 1
Exit Sub
ErrorHandler:
MsgBox "Error " + Str(Err.Number) + " has occurred" + Chr(10) + Chr(13) + Err.Description + Chr(10) + Chr(13) + Chr(10) + Chr(13) + "请联系工程师处理!!!", vbCritical
End Sub
自定义错误提示窗口:
ReadValue
Private Sub CommandButton5_Click()
On Error GoTo ErrorHandler
Dim X As Single
X = ReadValue("Fix32.Liang.TAG_12.F_CV", 1)
Exit Sub
ErrorHandler:
MsgBox "Error " + Str(Err.Number) + " has occurred" + Chr(10) + Chr(13) + Err.Description + Chr(10) + Chr(13) + Chr(10) + Chr(13) + "请联系工程师处理!!!", vbCritical
End Sub
自定义错误提示窗口:
3、使用"FindObject"方法
Private Sub CommandButton7_Click()
On Error GoTo ErrorHandler
Dim AI1 As Object
Dim X As Single
Set AI1 = System.FindObject("Fix32.Liang.TAG_12.F_CV")
'读
X = AI1
'写
AI1 = 1
Exit Sub
ErrorHandler:
MsgBox "Error " + Str(Err.Number) + " has occurred" + Chr(10) + Chr(13) + Err.Description + Chr(10) + Chr(13) + Chr(10) + Chr(13) + "请联系工程师处理!!!", vbCritical
End Sub
4、使用"FixDataSystem"对象
Private Sub CommandButton8_Click()
'创建 FixDataSystems OCX 对象
Dim FDS As Object
Dim Y As Single
Dim Y1 As Single
Set FDS = CreateObject("FixDataSystems.Intellution FD Data System Control")
'添加组
FDS.groups.Add ("DataGroup1")
FDS.groups.Add ("DataGroup2")
'为各个组添加iFIX标签,每一组可多个标签
FDS.groups.Item("DataGroup1").dataitems.Add ("Fix32.Liang.TAG_12.F_CV")
FDS.groups.Item("DataGroup2").dataitems.Add ("Fix32.Liang.TAG_13.F_CV")
'读==============================================================================
'读取组内标签的数值
FDS.groups.Item("DataGroup1").Read
FDS.groups.Item("DataGroup2").Read
'将读取到的标签数值,赋值给变量
Y = FDS.groups.Item("DataGroup1").dataitems.Item(1).Value
Y1 = FDS.groups.Item("DataGroup2").dataitems.Item(1).Value
'写==============================================================================
'将变量数值传给每个组内对应的标签(在缓存中)
FDS.groups.Item("DataGroup1").dataitems.Item(1).Value = Y1
FDS.groups.Item("DataGroup2").dataitems.Item(1).Value = Y
'将传给每个组内对应的标签的数值写到标签
FDS.groups.Item("DataGroup1").Write
FDS.groups.Item("DataGroup2").Write
'释放对象
Set FDS = Nothing
End Sub
注意:如果在读写前没有判断数据通讯状态是否正常(即:与PLC通讯状态、或者客户端与服务器通讯状态),则"FixDataSystems"将默认读写到有数值将为"0",这是不正常现象。
- 添加判断与PLC通讯状态脚本处理:
Private Sub CommandButton8_Click()
'创建 FixDataSystems OCX 对象
Dim FDS As Object
Dim Y As Single
Dim Y1 As Single
'判断与PLC的通讯状态
If Fix32.liang.TAG_12.A_CUALM <> "COMM " Then
Set FDS = CreateObject("FixDataSystems.Intellution FD Data System Control")
'添加组
FDS.groups.Add ("DataGroup1")
FDS.groups.Add ("DataGroup2")
'为各个组添加iFIX标签,每一组可多个标签
FDS.groups.Item("DataGroup1").dataitems.Add ("Fix32.Liang.TAG_12.F_CV")
FDS.groups.Item("DataGroup2").dataitems.Add ("Fix32.Liang.TAG_13.F_CV")
'读==================================================================================================================
'读取组内标签的数值
FDS.groups.Item("DataGroup1").Read
FDS.groups.Item("DataGroup2").Read
'将读取到的标签数值,赋值给变量
Y = FDS.groups.Item("DataGroup1").dataitems.Item(1).Value
Y1 = FDS.groups.Item("DataGroup2").dataitems.Item(1).Value
'写==================================================================================================================
'将变量数值传给每个组内对应的标签(在缓存中)
FDS.groups.Item("DataGroup1").dataitems.Item(1).Value = Y1
FDS.groups.Item("DataGroup2").dataitems.Item(1).Value = Y
'将传给每个组内对应的标签的数值写到标签
FDS.groups.Item("DataGroup1").Write
FDS.groups.Item("DataGroup2").Write
'释放对象
Set FDS = Nothing
End If
End Sub
添加判断客户端与服务器通讯状态脚本处理:
Private Sub CommandButton8_Click()
'创建 FixDataSystems OCX 对象
Dim FDS As Object
Dim Y As Single
Dim Y1 As Single
'判断客户端与服务器的通讯状态
If Fix32.liang.NSD.A_ACONNREASON_1 <> "已建立 " Then
Set FDS = CreateObject("FixDataSystems.Intellution FD Data System Control")
'添加组
FDS.groups.Add ("DataGroup1")
FDS.groups.Add ("DataGroup2")
'为各个组添加iFIX标签,每一组可多个标签
FDS.groups.Item("DataGroup1").dataitems.Add ("Fix32.Liang.TAG_12.F_CV")
FDS.groups.Item("DataGroup2").dataitems.Add ("Fix32.Liang.TAG_13.F_CV")
'读==================================================================================================================
'读取组内标签的数值
FDS.groups.Item("DataGroup1").Read
FDS.groups.Item("DataGroup2").Read
'将读取到的标签数值,赋值给变量
Y = FDS.groups.Item("DataGroup1").dataitems.Item(1).Value
Y1 = FDS.groups.Item("DataGroup2").dataitems.Item(1).Value
'写==================================================================================================================
'将变量数值传给每个组内对应的标签(在缓存中)
FDS.groups.Item("DataGroup1").dataitems.Item(1).Value = Y1
FDS.groups.Item("DataGroup2").dataitems.Item(1).Value = Y
'将传给每个组内对应的标签的数值写到标签
FDS.groups.Item("DataGroup1").Write
FDS.groups.Item("DataGroup2").Write
'释放对象
Set FDS = Nothing
End If
End Sub
5、总结(摘自iFIX电子书)
第一:使用FIX32对象这个方法简单容易,但从性能来说它会占用较多的资源。每次执行一行使用Fix32对象的代码提取或设置数值时,iFIX工作台将做如下4步工作:
①声明一个新的数据项;
②确认该数据项;
③读/写数值;
④释放对象。
如果访问的是远程节点标签,可能会更慢。
第二:使用"FindObject"方法要比使用Fix32对象访问速度快,因为该对象只当FindObject执行和返回一个数据项时做自身验证。只要该变量没被释放或没被赋给新的对象,就能被读取和写入,而无需工作台重新验证。
第三:使用"FixDataSystem"对象,配置起来相对复杂。但这是最有效访问数据库的方法。该方法要比使用FindObject方法速度快,因为数据项都以组的形式读取和写入。换言之,当执行FixDataSystem对象组的读取方法时,它将在一次调用中读取所有添加的标签。当从数据项集内提取数据项值时,它实际上是从缓存区中读取的,而不是从数据库中请求数据。如果连续读取或写入大量标签,应该考虑使用FixDataSystem对象。
个人建议:
①标签数量只有几个时,使用"WriteValue"和"ReadValue"子程序方法;
②标签数量大时,使用"FixDataSystem"对象方法。