跳转到内容

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

上一页:字符串 目录 下一页:文件
华夏公益教科书