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。
| 上一頁:字串 | 目錄 | 下一頁:檔案 |