Visual Basic/数组
数组在 Visual Basic 中非常有用,并且存在于许多其他编程语言中。数组用于将类似的数据分组在一起,以便更轻松地搜索和排序这些数据。查看数组的最佳方法是向您展示一个。假设您想为您的计算机制作一个电话簿。您无需在每次想要添加姓名时都使用新的变量名,而是可以创建一个数组。数组由变量名和下标组成,下标在计算机使用中用括号括起来。因此,如果您想制作一个大约 100 人的电话簿,而不是创建一堆名为“person1、person2、person3…person100”的变量,您可以使用数组。您只需对数组进行声明(见上文)。因此,现在这 100 个变量在一个 dim 语句中变为 person(1 到 100)。现在您可能在问,我现在该怎么办?存储在数组中的每个对象都称为元素。您所做的是创建了一个可以容纳 100 个元素的数组。如果您想打印电话簿中的第 32 个人,您只需键入
Debug.Print Person(32)
数组的用途远不止制作电话簿。但在我们深入探讨具体用途之前,让我们先看看使用数组时的一些基本技术。您可能想要做的第一件事是学习如何轻松地填充数组。用随机数填充数组是开始程序和测试其他技术的流行方法,例如排序。要填充数组,可以使用简单的 For 循环。
Option Explicit
Dim lngIndex as Long
Dim strArray(0 to 9) as String ' Create an array with 10 values
Dim intCounter as Integer
intCounter = 1
For lngIndex = LBound(strArray) to UBound(strArray)
intCounter = intCounter + 1
strArray(lngIndex) = intCounter
Next lngIndex
以上显示了对数组进行读写迭代的示例。For Each 循环可用于对数组进行只读迭代
Dim MyArray(9)
For i = 0 To 9
MyArray(i) = i
Next
For Each Item In MyArray
Debug.Print Item
Next
默认情况下,数组的索引从 0 开始,除非使用“Option Base 1”声明。如果没有使用声明,声明为“Dim MyArray(5)”的数组有 6 个元素:0、1、2、3、4、5。
数组的索引范围必须是连续的整数序列,包括负数。因此,以下操作是可能的
Dim MyArray1(-5 to 5)
Dim MyArray2(-10 to -5)
For i = LBound(MyArray1) to UBound(MyArray1)
MyArray1(i) = i + 5
Debug.Print i, MyArray1(i)
Next
For i = LBound(MyArray2) to UBound(MyArray2)
MyArray2(i) = i + 5
Debug.Print i, MyArray2(i)
Next
可以使用 LBound 和 UBound 来获取数组的大小,如下所示
Dim MyArray1(-5 to 5)
Dim MyArray2(10-1)
Size1 = UBound(MyArray1) - LBound(MyArray1) + 1
Size2 = UBound(MyArray2) + 1 'For a same array with indexing starting at zero
Debug.Print Size1, Size2
关键字:长度、项数、元素数。
在声明时指定元素数量的数组,如 Dim Names(0 to 9),是静态数组:其元素数量在运行时无法更改。相比之下,在声明时不指定元素数量的数组,如 Dim Names(),是动态数组,其元素数量可以使用 ReDim 更改。要在使用 ReDim 时保留数组的元素内容,必须在 ReDim 后使用 Preserve 关键字。
假设您正在运行一个电话簿程序,它包含一个包含您朋友姓名的数组,如下所示
Option Explicit
Dim StrNames(0 to 2) As String
StrNames(0) = "Alec"
StrNames(1) = "Jack"
StrNames(2) = "Pie"
但是假设您想在运行时例如单击按钮时向您的电话簿添加更多朋友。该怎么办?您可以定义一个动态数组而不是
Dim Names() As String
该数组最初没有元素。您可以使用 ReDim 关键字添加更多元素
ReDim Names(0 to 1) As String
这将创建两个新元素。您可以像以前一样将姓名分配给这些元素
Names(0) = "Alec"
Names(1) = "Jack"
如果您想添加更多条目,那么例如使用
ReDim Names(0 to 2) As String
但您最终会丢失所有旧记录!如果您想保留它们,您还必须使用 Preserve 关键字
ReDim Preserve Names(0 To 3) As String
Names(1) = "Eugene H / Orage" 'Whoa this person's name is too long to remember
要迭代也称为循环遍历动态数组的元素,您必须使用 LBound 和 UBound 函数或 For Each 循环,如#数组的用途中所述。
要向已初始化的动态数组添加元素,您可以按照以下步骤进行,使用 UBound 函数
ReDim Preserve Names(0 To UBound(Names) + 1) As String
Names(UBound(Names)) = "my new friend"
但是,UBound 不适用于未初始化的动态数组,因此以下操作会导致运行时错误
Dim MyArray() As String
Debug.Print UBound(MyArray)
避免此运行时错误的一种方法是保留一个标志
Dim ArrayIsEmpty As Boolean
Dim MyArray() As String
ArrayIsEmpty = True
If Not ArrayIsEmpty Then
ReDim Preserve MyArray(0 To UBound(MyArray) + 1) As String
Else
ReDim Preserve Names(0 To 0) As String
ArrayIsEmpty = False
End If
Names(UBound(Names)) = "my new friend"
避免运行时错误的另一种方法是捕获在未初始化的数组上使用“UBound”所产生的错误
Dim MyArray() As String
NumberOfElements = 0
On Error Resume Next
NumberOfElements = UBound(MyArray) + 1
On Error GoTo 0
ReDim Preserve MyArray(0 To NumberOfElements) As String
MyArray(UBound(MyArray)) = "my new friend"
最后,您可以使用以下技巧来检查动态数组是否已初始化
Dim MyArray() As String
If (Not MyArray) = -1 Then
NumberOfElements = 0 'The array is uninitialised
Else
NumberOfElements = UBound(MyArray) + 1
End If
ReDim Preserve MyArray(0 To NumberOfElements) As String
MyArray(UBound(MyArray)) = "my new friend"
变体数组是使用 Variant 类型声明的动态数组,并使用“= Array()”进行初始化。它们的优势在于,在使用“= Array()”进行初始化后,即使它们没有元素,LBound 和 UBound 函数也可以与它们一起使用,如下所示
Dim VariantArray As Variant
VariantArray = Array()
Debug.Print LBound(VariantArray) 'Prints 0
Debug.Print UBound(VariantArray) 'Prints -1
因此,添加元素很简单,无需检查 UBound 失败
ReDim Preserve VariantArray(0 To UBound(VariantArray) + 1) As Variant
VariantArray(UBound(VariantArray)) = "Jennifer"
变体数组可以初始化为一组值
Dim VariantArray As Variant
VariantArray = Array(1, 2.3, "Hey")
对于非常大的数组,使用变体数组的开销可能会有很大限制,变体数组的元素类型为 Variant 而不是 String 或其他更窄的类型,在这种情况下,应使用传统的动态数组。与变体数组相比,逐个添加项目的速度似乎快得多,例如集合.
可以通过列出每个维度的尺寸来定义具有任意数量的维度(或索引)的数组
Dim FunkyArray(2,3,1,4) As String
可以像这样引用元素
FunkyArray(1,2,0,3) = 24
动态数组也可以重新调整尺寸以具有任意数量的维度
Dim VeryFunkyArray() as String
ReDim VeryFunkyArray(2,2,2) As String
LBound 和 UBound 函数可用于查找特定维度的边界
Debug.Print UBound(FunkyArray, 4)
将返回 4。
在没有第二个参数的情况下使用 UBound 将返回第一个维度
Debug.Print UBound(FunkyArray)
' Displays 2
Debug.Print UBound(VeryFunkyArray)
' Displays 2
可以使用以下方法将任何类型的数组重置为空
Erase SomeArray
数组的真正强大之处在于定义数组的数组。这是什么意思?声明一个数组
Dim VariantArray() As Variant
VariantArray = Array()
ReDim VariantArray(1) As Variant
VariantArray(0) = Array(1,2,3)
VariantArray(1) = Array(4,5,6)
我们这里有什么?本质上是两个数组嵌套在另一个数组中。它们可以像这样被引用
Debug.Print VariantArray(0)(2)
将显示 3。
您可以将数组像这样嵌套到任何深度和任何顺序,并且它们可以是任何大小。但是,在使用 ReDim 语句时,必须注意。您不能专门重新调整数组的特定维度;相反,您需要将其暂时复制到一个变体中。
Dim vtemp As Variant
vtemp = VariantArray(0)
ReDim vtemp(1+UBound(vtemp)) As Variant
vtemp(UBound(vtemp)) = 7
VariantArray(0) = vtemp
另请参见#多维数组部分。
矩阵不如数组常用,但它们是编程的重要组成部分。矩阵可能不只包含一个维度,而是包含 2 个或更多个维度。因此,要创建一个矩阵,Dim 语句将是
Dim Matrix(0 To 9, 0 To 9) as Integer
这将创建一个 10x10 的矩阵,由整数组成。实际上,矩阵很像数组的数组。您要做的第一件事是知道如何创建循环来读取和填充矩阵。但在此之前,您甚至应该知道矩阵的结构。一个示例矩阵将是
1 2 3 4 5 6 7 8 9 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 1 1 4 1 1 1 1 1 1 1 1 1
这是一个 4x9 的矩阵。在谈论矩阵时,行始终在列之前说明。您还会注意到列号从左到右排列,而行号从上到下排列。这非常重要。当然,矩阵不必仅仅包含 1。因此,现在您想填充矩阵?它与数组非常相似。
For Row = 0 To 3
For Column = 0 To 8
Matrix(Row, Column)=1
Next
Next
这当然只会用 1 填充矩阵,但可以使用随机数(参见参考资料)。正如您可能注意到的,这涉及嵌套循环。循环从左到右,从上到下填充(我们在读取时使用的相同方向)。
有关排序变体数组的信息,请参阅 http://stackoverflow.com/questions/152319/vba-array-sort-function。
上一页:字符串 | 目录 | 下一页:文件 |