做过工控的人都知道,对脚本语言的支持是标准组态软件应具备的一个基本功能(如iFix,组态王等)。如果我们用VB开发类似的功能,能实现吗?
想必大家都知道微软提供了Micrsoft Script Control 1.0 控件,在VB版也见到了大家对这个控件的使用(如用ExecuteStatement方法执行脚本命令 ExecuteStatement("msgbox “你好””)??? )。但最重要的一点,ActiveX脚本与宿主应用程序数据交互与传递,却没有完整的解决方案。
我也是探索了很长一段时间,才摸索出一点数据传递与交互的技巧,现在共享出来,供大家讨论研究。
示例程序介绍:
1、首先加载Micrsoft Script Control 1.0 控件。
对它基本上不用配置,默认语言VBScript,对该部分的介绍请下载VBScript命令集 (http://blog.csdn.net/yefanqiu 【叶帆资源】[03] VBScript指令集)
2、添加一个窗体(frmTest),里面添加如下代码:
**********************************************************************
'**模 块 名:frmTest
'**说 明:YFsoft 版权所有2004 - 2005(C)
'**创 建 人:叶帆
'**日 期:2004-10-15 11:00:32
'**修 改 人:
'**日 期:
'**描 述:脚本语言运用探索
'**版 本:V1.0.0
'*************************************************************************
Option Explicit
'*************************************************************************
'**函 数 名:chkRun_Click
'**输 入:无
'**输 出:无
'**功能描述:脚本运行控制
'**全局变量:
'**调用模块:
'**作 者:叶帆
'**日 期:2004-10-15 11:19:31
'**修 改 人:
'**日 期:
'**版 本:V1.0.0
'*************************************************************************
Private Sub chkRun_Click()
If chkRun.value = 1 Then
tmrRun.Interval = cmbRunTime.Text '运行间隔
tmrRun.Enabled = True '开始运行 以固定间隔循环运行
txtEdit.Enabled = False
Else
tmrRun.Enabled = False '停止运行
txtEdit.Enabled = True
End If
End Sub
'*************************************************************************
'**函 数 名:cmbType_Click
'**输 入:无
'**输 出:无
'**功能描述:操作类型切换
'**全局变量:
'**调用模块:
'**作 者:叶帆
'**日 期:2004-10-15 12:56:19
'**修 改 人:
'**日 期:
'**版 本:V1.0.0
'*************************************************************************
Private Sub cmbType_Click()
cmdSCDemo1_Click
End Sub
'*************************************************************************
'**函 数 名:cmdRun_Click
'**输 入:无
'**输 出:无
'**功能描述:单次运行脚本
'**全局变量:
'**调用模块:
'**作 者:叶帆
'**日 期:2004-10-15 11:51:29
'**修 改 人:
'**日 期:
'**版 本:V1.0.0
'*************************************************************************
Private Sub cmdRun_Click()
Call tmrRun_Timer
End Sub
'*************************************************************************
'**函 数 名:cmdSCDemo1_Click
'**输 入:无
'**输 出:无
'**功能描述:参数传递演示
'**全局变量:
'**调用模块:
'**作 者:叶帆
'**日 期:2004-10-15 11:03:29
'**修 改 人:
'**日 期:
'**版 本:V1.0.0
'*************************************************************************
Private Sub cmdSCDemo1_Click()
Dim strType As String
'内部变量定义 类似组态王中的数据字典
valMem.Clear
valMem.SetValue "Value1", txtValue(0)
valMem.SetValue "Value2", txtValue(1)
valMem.SetValue "Value3", 0
Select Case cmbType.ListIndex
Case 0:
strType = "+"
Case 1:
strType = "-"
Case 2:
strType = "*"
Case 3:
strType = "/"
End Select
txtEdit = "dim lngValue1" & vbCrLf
txtEdit = txtEdit & "dim lngValue2" & vbCrLf
txtEdit = txtEdit & "dim lngValue3" & vbCrLf
txtEdit = txtEdit & "lngValue1=vm.getvalue(" & Chr(34) & "Value1" & Chr(34) & ")" & vbCrLf
txtEdit = txtEdit & "lngValue2=vm.getvalue(" & Chr(34) & "Value2" & Chr(34) & ")" & vbCrLf
txtEdit = txtEdit & "lngValue3=CInt(lngValue1)" & strType & "CInt(lngValue2)" & vbCrLf
txtEdit = txtEdit & "vm.setvalue " & Chr(34) & "Value3" & Chr(34) & ",lngValue3 " & vbCrLf
End Sub
'*************************************************************************
'**函 数 名:cmdSCDemo2_Click
'**输 入:无
'**输 出:无
'**功能描述:对象操作演示
'**全局变量:
'**调用模块:
'**作 者:叶帆
'**日 期:2004-10-15 13:41:23
'**修 改 人:
'**日 期:
'**版 本:V1.0.0
'*************************************************************************
Private Sub cmdSCDemo2_Click()
txtEdit = "dim lngC" & vbCrLf
txtEdit = txtEdit & "lngC=clng(fm.txtdemo.text)" & vbCrLf
txtEdit = txtEdit & "lngC=lngC+10" & vbCrLf
txtEdit = txtEdit & "if lngC>255 then lngC=0" & vbCrLf
txtEdit = txtEdit & "fm.picdemo.backcolor=rgb(lngC,0,0)" & vbCrLf
txtEdit = txtEdit & "fm.txtdemo.text=cstr(lngC)" & vbCrLf
End Sub
'*************************************************************************
'**函 数 名:Form_Load
'**输 入:无
'**输 出:无
'**功能描述:初始化
'**全局变量:
'**调用模块:
'**作 者:叶帆
'**日 期:2004-10-15 11:13:03
'**修 改 人:
'**日 期:
'**版 本:V1.0.0
'*************************************************************************
Private Sub Form_Load()
'添加参数运用的 内部可使用的变名 外部实际变量名
scCommand.AddObject "vm", valMem, True
'向脚本添加外部可用的对象
'最后一个参数: True表示它的子类属性方法在脚本中可以操作 false 表示今该对象本身的方法属性可用
scCommand.AddObject "fm", Me, True
'脚本运行间隔设置
cmbRunTime.ListIndex = 0
'参数操作类型
cmbType.ListIndex = 0
End Sub
'*************************************************************************
'**函 数 名:tmrRun_Timer
'**输 入:无
'**输 出:无
'**功能描述:脚本运行
'**全局变量:
'**调用模块:
'**作 者:叶帆
'**日 期:2004-10-15 11:29:46
'**修 改 人:
'**日 期:
'**版 本:V1.0.0
'*************************************************************************
Private Sub tmrRun_Timer()
On Error GoTo ToExit '打开错误陷阱
'------------------------------------------------
Dim i As Long
'参数输入
valMem.SetValue "Value1", txtValue(0).Text
valMem.SetValue "Value2", txtValue(1).Text
valMem.SetValue "Value3", 0
'脚本运行
scCommand.ExecuteStatement txtEdit.Text
'参数输出
lstValueOut.Clear
For i = 1 To valMem.Count
lstValueOut.AddItem valMem.GetValue("", i)
Next
'------------------------------------------------
Exit Sub
'----------------
ToExit:
txtError = "错 误 号:" & Err.Number & " 时间:" & Format(Now, "YYYY-MM-DD HH:MM:SS") & vbCrLf
txtError = txtError & "错误信息:" & Err.Description & vbCrLf
txtError = txtError & "错误来源:" & Err.Source
End Sub
3、添加一个模块(mdlBase),里面添加如下代码:
**********************************************************************
'**模 块 名:mdlBase
'**说 明:YFsoft 版权所有2004 - 2005(C)
'**创 建 人:叶帆
'**日 期:2004-10-15 11:10:58
'**修 改 人:
'**日 期:
'**描 述:公共变量区
'**版 本:V1.0.0
'*************************************************************************
Option Explicit
Public valMem As New clsScriptIO '脚本语言参数交换的变量设置区
添加一个类(clsScriptIO),类名为clsScriptIO,里面添加如下代码:
**********************************************************************
'**模 块 名:clsScriptIO
'**说 明:YFsoft 版权所有2004 - 2005(C)
'**创 建 人:叶帆
'**日 期:2004-10-15 11:56:32
'**修 改 人:
'**日 期:
'**描 述:与脚本语言参数交互的类模块
'**版 本:V1.0.0
'*************************************************************************
Option Explicit
Private cltScriptMem As New Collection '变量设置区
'*************************************************************************
'**函 数 名:Count
'**输 入:无
'**输 出:(Variant) -
'**功能描述:内存变量个数
'**全局变量:
'**调用模块:
'**作 者:叶帆
'**日 期:2004-10-15 12:00:57
'**修 改 人:
'**日 期:
'**版 本:V1.0.0
'*************************************************************************
Public Property Get Count() As Variant
Count = cltScriptMem.Count
End Property
'*************************************************************************
'**函 数 名:GetValue
'**输 入:strKey(String) - 变量名称
'** :Optional lngNo(Long = 0) - 变量索引
'**输 出:(Variant) - 返回值
'**功能描述:取得制定名称的变量值
'**全局变量:
'**调用模块:
'**作 者:叶帆
'**日 期:2004-10-15 12:01:59
'**修 改 人:
'**日 期:
'**版 本:V1.0.0
'*************************************************************************
Public Function GetValue(strKey As String, Optional lngNo As Long = 0) As Variant
On Error GoTo ToExit '打开错误陷阱
'------------------------------------------------
If lngNo > 0 Then '如果输入索引号,则返回索引号指定的变量
GetValue = cltScriptMem.Item(lngNo)
Else
GetValue = cltScriptMem.Item(strKey)
End If
'------------------------------------------------
Exit Function
'----------------
ToExit:
End Function
'*************************************************************************
'**函 数 名:SetValue
'**输 入:strKey(String) - 变量名
'** :value(Variant) - 设置变量
'**输 出:无
'**功能描述:为指定的变量赋值
'**全局变量:
'**调用模块:
'**作 者:叶帆
'**日 期:2004-10-15 12:07:05
'**修 改 人:
'**日 期:
'**版 本:V1.0.0
'*************************************************************************
Public Sub SetValue(strKey As String, value As Variant)
On Error GoTo ToExit '打开错误陷阱
'------------------------------------------------
cltScriptMem.Remove (strKey)
cltScriptMem.Add value, strKey
'------------------------------------------------
Exit Sub
'----------------
ToExit:
Resume Next
End Sub
'*************************************************************************
'**函 数 名:DelValue
'**输 入:strKey(String) - 变量名
'** :Optional lngNo(Long = 0) -索引号
'**输 出:无
'**功能描述:删除制定的变量
'**全局变量:
'**调用模块:
'**作 者:叶帆
'**日 期:2004-10-15 12:08:55
'**修 改 人:
'**日 期:
'**版 本:V1.0.0
'*************************************************************************
Public Sub DelValue(strKey As String, Optional lngNo As Long = 0)
On Error GoTo ToExit '打开错误陷阱
'------------------------------------------------
If lngNo > 0 Then '如果输入索引号,则删除索引号指定的变量
cltScriptMem.Remove (lngNo)
Else
cltScriptMem.Remove (strKey)
End If
'------------------------------------------------
Exit Sub
'----------------
ToExit:
End Sub
'*************************************************************************
'**函 数 名:Clear
'**输 入:无
'**输 出:无
'**功能描述:删除变量
'**全局变量:
'**调用模块:
'**作 者:叶帆
'**日 期:2004-10-15 13:15:15
'**修 改 人:
'**日 期:
'**版 本:V1.0.0
'*************************************************************************
Public Sub Clear()
On Error GoTo ToExit '打开错误陷阱
'------------------------------------------------
While cltScriptMem.Count > 0
cltScriptMem.Remove (1)
Wend
'------------------------------------------------
Exit Sub
'----------------
ToExit:
Resume Next
End Sub
功能演示:
1、参数传递(单击【传递参数演示】按钮,自动添加相应脚本代码。可以执行加减乘除等操作。
下图演示了错误捕捉(被0除错误)
2、对象操作(单击【对象操作演示】按钮,自动添加相应脚本代码。可以执行控件的赋值和背景色变化操作。