教程 | VBA编程中并非显而易见的常识

01

圆括号的作用

Sub 过程、内置 语句和一些方法不返回值,因此参数不包含在括号中 。例如:

MySub "stringArgument", integerArgument

Function 过程、内置函数和一些方法会返回一个值,但可以忽略该值。如果忽略返回值,则不包括括号。就像调用 Sub 过程一样调用此函数。省略括号,列出任何参数,并且不将此函数分配给变量。例如:

MsgBox "Task Completed!", 0, "Task Box"

若要使用函数的返回值,请将参数包含在括号中,如下面的示例所示。

Answer3 = MsgBox("Are you happy with your salary?", 4, "Question 3")

Sub 或 Function****过程中的 语句可以使用命名参数将值传递给 调用的过程。不管是否使用命名参数,针对使用括号的指南都适用。当使用命名参数时,可以按任意顺序列出它们,并且可以省略可选的参数。命名参数的后面总是跟有一个分号和一个等号 (:=),然后是参数值。

下面的示例使用命名参数调用 MsgBox 函数,但它将忽略返回值。

MsgBox Title:="Task Box", Prompt:="Task Completed!"

以下示例使用命名参数调用 MsgBox 函数,并将返回值分配给变量。

answer3 = MsgBox(Title:="Question 3", Prompt:="Are you happy with your salary?", Buttons:=4)


02

变量生存期

变量保留其值的时间被称为变量的生存期。变量的值在其生存期结束后可能会更改,但会保留某个值。当变量丢失范围时,它不再具有值。

在过程开始运行时,会初始化所有变量。数值变量初始化为零,可变长度字符串初始化为零长度字符串 ("") ,固定长度的字符串用 ASCII 字符代码 0 或 Chr ( 0 ) 表示的字符填充。Variant 变量初始化为空。用户定义类型变量的每个元素都像单独变量一样初始化。

声明 对象变量时,空间保留在内存中,但其值设置为 Nothing, 直到使用 Set 语句为其分配对象引用。

如果变量的值在代码运行期间未更改,它会保留其初始化的值,直到丢失范围。

用 Dim 语句声明的过程级别变量将保留一个值,直到过程完成运行。如果该过程调用其他过程,当这些过程运行时,该变量也会保留其值。

如果使用 Static 关键字声明过程级别变量,则只要代码在任何模块中运行,变量就保留 其值。当所有代码都运行完毕时,变量将丢失其范围和值。其生存期与模块级别变量相同。

模块级别变量与静态变量不同。在标准模块或类模块中,它保留其值,直到代码停止运行。在类模块中,只要类的实例存在,变量便会保留其值。模块级别变量将一直消耗内存资源,直到重置其值,因此请仅在必要时使用这些变量。

如果在 Sub 或 Function 语句之前包含 Static 关键字,则过程中所有过程级别变量的值在两次调用之间保留。

03

递归过程的运用

过程只有有限的空间量供变量使用。过程每次调用自身时,都会有更多空间被占用。调用自身的过程称为递归过程。不断调用自身的递归过程最终会导致错误。例如:

Function RunOut(Maximum)  RunOut = RunOut(Maximum) End Function

当两个过程无限期地相互调用或者永远无法满足某个用于限制递归的条件时,此错误可能不太明显。递归确实有它自己的用途。例如,以下过程使用递归函数计算因子。

Function Factorial (N)  If N <= 1 Then ' Reached end of recursive calls.  Factorial = 1 ' (N = 0) so climb back out of calls.  Else ' Call Factorial again if N > 0.  Factorial = Factorial(N - 1) * N  End If End Function

应测试递归过程以确保它不会太多次调用自身从而导致内存不足。如果出现错误,请确保过程没有无限期地调用它自身。随后,尝试通过以下方法节省内存:

  • 消除不必要的变量。

  • 使用除 Variant 之外的 数据类型。

  • 重新评估过程逻辑。通常可以用嵌套循环代替递归。

04

数组的使用

可以声明一个数组以处理一组相同数据类型的值。 

数组是具有多个可存储值的隔离舱的单个变量,而典型的变量只有一个存储隔离舱,其中只能存储一个值。 

可以在需要引用数组中包含的所有值时将数组作为整体引用,也可以引用其中的单个元素。

例如,若要存储一年中每天的日常开支,您可以声明一个具有 365 个元素的数组变量,而不是声明 365 个变量。数组中的每个元素包含一个值。以下语句声明具有 365 个元素的数组变量。默认情况下,数组的索引从零开始,因此该数组的上限是 364 而不是 365。

Dim curExpense(364) As Currency

若要设置单个元素的值,可以指定该元素的索引。以下示例向该数组中的每个元素均分配一个初始值 20。

Sub FillArray()  Dim curExpense(364) As Currency  Dim intI As Integer  For intI = 0 to 364  curExpense(intI) = 20  Next End Sub

更改下限

可以使用模块顶部的 Option Base 语句将第一 个元素的默认索引从 0 更改为 1。在下面的示例中 ,Option Base 语句更改第一个元素的索引 ,Dim 语句声明包含 365 个元素的数组变量。

Option Base 1 Dim curExpense(365) As Currency

也可以通过使用 To 子句明确设置数组的下限,如以下示例所示。

Dim curExpense(1 To 365) As Currency Dim strWeekday(7 To 13) As String

在数组中存储 Variant 值

有两种方法可以创建 Variant 值的数组 。 

一种是声明 Variant 数据类型的数组,如以下示例所示:

Dim varData(3) As Variant varData(0) = "Claudia Bendel" varData(1) = "4242 Maple Blvd" varData(2) = 38 varData(3) = Format("06-09-1952", "General Date")

另一种方法是将 Array 函数返回的数组分配给 Variant 变量,如以下示例所示:

Dim varData As Variant varData = Array("Ron Bendel", "4242 Maple Blvd", 38, _ Format("06-09-1952", "General Date"))

无论使用哪种方法创建数组,均可通过索引识别 Variant 值的数组中的元素。例如,以下语句可添加到上述两个示例中的任意一个示例中。

MsgBox "Data for " & varData(0) & " has been recorded."

使用多维数组

在 Visual Basic 中,您可以声明最多包含 60 个维度的数组。例如,以下语句声明了一个二维、5*10 的数组。

Dim sngMulti(1 To 5, 1 To 10) As Single

如果将数组看作矩阵,则第一个参数表示行,第二个参数表示列。

使用嵌套 For...处理 多维数组的下一语句。 

以下过程使用 Single 值填充一个二维度组

Sub FillArrayMulti()  Dim intI As Integer, intJ As Integer  Dim sngMulti(1 To 5, 1 To 10) As Single  ' Fill array with values.  For intI = 1 To 5  For intJ = 1 To 10  sngMulti(intI, intJ) = intI * intJ  Debug.Print sngMulti(intI, intJ)  Next intJ  Next intI End Sub

05

Variant变体

如果数据类型常量、变量或参数时未指定数据类型变量,则会自动指定 Variant 参数。

声明为 Variant数据类型变量可以包含字符串、日期、时间、布尔值或数值,并可以自动转换它们包含的值。数值 Variant 值需要 16 字节的内存 (这仅在大型过程或复杂 模块 )中十分重要,并且访问速度比任何其他类型显式键入的变量慢。很少对常量使用 Variant 数据类型。字符串 Variant 值要求 22 个字节的内存。

以下语句创建 Variant 变量

Dim myVar Dim yourVar As Variant theVar = "This is some text."

最后一个语句不会显式声明变量,而是隐式或自动声明变量。隐式声明的变量将被指定为 Variant 数据类型。

如果为变量或参数指定数据类型,而使用了错误的数据类型,则会发生数据类型错误。若要避免数据类型错误,只使用隐式变量( Variant 数据类型)或者明确声明所有变量并指定数据类型。后一种方法是首选方法。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容