做过工控的人都知道,对脚本语言的支持是标准组态软件应具备的一个基本功能(如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 '脚本语言参数交换的变量设置区
4、添加一个类(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、对象操作(单击【对象操作演示】按钮,自动添加相应脚本代码。可以执行控件的赋值和背景色变化操作。
VBScript 使用 ActiveX(R)脚本与宿主应用程序对话。使用 ActiveX Script,浏览器和其他宿主应用程序不再需要每个脚本部件的特殊集成代码。ActiveX脚本使宿主可以编译 Script、获取和调用入口点及管理开发者可用的命名空间。通过 ActiveX Script,语言厂商可以建立标准脚本运行时语言。Microsoft 将提供 VBScript 的运行时支持。