VBA|过程或方法内部的直接或间接调用与相对怪异的语法格式

在VBA中,有两种基本代码模块,过程(Sub Procedure)和函数(Function),有返回值的代码模块使用函数,没有返回值的代码模块使用过程。

两种代码模块都可以使用参数,也可以不使用参数,参数的传递方式有两种,传值和传址。

过程在Excel中可以通过菜单、工具栏、按钮、快捷键等方式直接调用,函数可以在工作表的公式中如同内置函数一样调用。

过程和函数在模块内可以直接调用,也可以使用OnTimeOnKey方法间接调用

1 直接调用

过程和函数在模块内的调用可以使用以下语法格式:

Sub main()
    call 过程名
    过程名
    值 = 函数名()
End Sub    

对许多内建函数、语句和方法,Visual Basic 提供了命名参数方法来快捷传递参数值。对命名参数,通过给命名参数赋值,就可按任意次序提供任意多参数。为此,键入命名参数,其后为冒号、等号和值 (MyArgument := "SomeValue") ,可以按任意次序安排这些赋值,它们之间用逗号分开。

在调过程或方法调用时,参数是否使用括号?视是否使用其参数而定:

Sub calc()
    Application.ActivateMicrosoftApp Index:=0 ' 打开windows附件中的计算器
End Sub

Sub demo(a As Integer)
    Debug.Print a
End Sub

Function foo()
    foo = 3
End Function

Function add(ByVal a As Double, ByRef b As Double, Optional c As Double)
    a = a + 11
    b = b + 22
    add = a + b + c
End Function

Sub test()
    Dim ws1 As Worksheet, str1 As String
    Dim val As Double, ref As Double, sum As Double
    Call calc '使用call调用过程
    calc      ' 不使用call调用过程
    demo (3)
    val = foo()
    ref = 4
    sum = add(val, ref) ' 调用函数
    Debug.Print val, ref, sum  '3 26 40
    'InputBox(prompt [, title] [, default] [, xpos] [, ypos] _ [, helpfile, context])
    InputBox ("please input:") '调用内置函数
    InputBox Prompt:="请输入删除的工作表名称:"  '在调用不使用返回值的函数时不使用括号
    str1 = InputBox(Prompt:="请输入删除的工作表名称:")   '在调用使用返回值的函数时才应使用括号
End Sub

如果实际上在调用Sub时确实无意中使用了括号,则VB6将按值而不是按引用传递参数。

Sub AddOne(ByRef i As Integer)
    i = i + 1
End Sub

Sub Command1_Click()
    Dim i As Integer
    i = 1
    AddOne i    'i will be passed by reference and increased by 1
    MsgBox i    'Will print"2"
    AddOne (i)  'i will be passed by value, so the return value will be lost!!
    MsgBox i    'Will still print"2"!!
End Sub

2 间接调用

2.1 OnTime 方法

使用Application 对象的OnTime 方法,可安排一个过程在某个特定的时间运行(既可以是具体指定的某个时间,也可以是指定的一段时间之后)。其语法格式如下:

表达式.OnTime(EarliestTime, Procedure, LatestTime, Schedule)

各参数的含义如下。

● EarliestTime:希望此过程运行的时间。

● Procedure:要运行的过程名。

● LatestTime:过程开始运行的最晚时间。例如,如果LatestTime 参数设置为EarliestTime+30,且当到达EarliestTime 时间时,由于其他过程处于运行状态而导致Excel 不能处于“就绪”、“复制”、“剪切”或“查找”模式,则Excel 将等待30 秒让第一个过程先完成。如果Excel 不能在30 秒内回到“就绪”模式,则不运行此过程。如果省略该参数, Excel 将一直等到可以运行该过程为止。

● Schedule:如果为True,则预定一个新的OnTime 过程。如果为False,则清除先前设置的过程。默认值为True。

(1)“打开整点报时”按钮的VBA 代码如下:

Sub starttime()
    Application.OnTime EarliestTime:=TimeSerial((Hour(Now) + 1) Mod 24, 0, 0), _
    Procedure:="starttime"
    MsgBox "现在时间是:" & Hour(Now) & " 点!"
End Sub

以上代码首先通过OnTime 方法设置整点时(小时数与24 进行模运算)调用的过程,接着显示一个对话框进行报时。

(2)“结束整点报时”按钮的VBA 代码如下:

Sub endtime()
    On Error Resume Next
    Application.OnTime EarliestTime:=TimeSerial((Hour(Now) + 1) Mod 24, 0,0), _
    Procedure:="starttime", schedule:=False
End Sub

以上代码取消OnTime 设置的过程。在执行本过程时,如果没有使用OnTime 设置调用对应的过程,则程序将出错,所以第1 条语句设置错误捕捉。

Sub otime()
    Application.OnTime Now() + TimeValue("00:01:00"), "wbSave"
End Sub

Sub wbSave()
    This Workbook.Save
    Debug.Print (Now())
    Call otime
End Sub

2.2 OnKey 方法

使用Application 对象的OnKey 方法,可在设定的特定键或组合键被按下时,运行指定的过程,其语法格式如下:

表达式.OnKey(Key, Procedure)

两个参数的含义如下。

● Key:表示要按的键的字符串,其表示方法与例138 中的SendKeys 方法相同。Key 参数可指定任何单个键或与Alt、Ctrl 或Shift 的组合键(或者这些键的组合),每个键可用一个或多个字符表示。例如,"a"表示字符a,或者"{ENTER}"表示Enter。控制键Shift、Ctrl、Alt 分别用加号(+)、插入符号(^)和百分号(%)表示。

● Procedure:表示要运行的过程名称的字符串。如果Procedure 为空文本(""),则按Key 时不发生任何操作。如果省略Procedure 参数,则Key 恢复为Excel 中的正常结果,同时清除先前使用OnKey 方法所做的特殊击键设置。

1)“设置自定义功能键”按钮的VBA 代码如下:

Sub NextPage()
    ActiveWindow.LargeScroll down:=1
End Sub

Sub PrePage()
    ActiveWindow.LargeScroll up:=1
End Sub

Sub 设置自定义功能键()
    Application.OnKey "%.", "NextPage"
    Application.OnKey "%,", "PrePage"
End Sub

(2)“禁止自定义功能键”按钮的VBA 代码如下:

Sub 禁止自定义功能键()
    Application.OnKey "%."
    Application.OnKey "%,"
End Sub

-End-