VB.NET 陣列 (Array) 筆記(基礎篇)
VB.NET 中處理多筆同型態資料時,如果每一筆內容都用獨立變數保存,後續的統計、輸出與維護會很快失去一致性。Array 陣列的主要用途,就是把相同型別的資料集中管理,並透過索引位置讀寫指定元素。
陣列的基礎可先抓住三件事:資料型別固定、位置由索引管理、宣告時的括號數字代表「最大索引」而不是「總筆數」。只要這三點清楚,後續的一維陣列、二維陣列、ReDim 與索引邊界判斷,都會比較容易理解。
陣列原理分析
運作邏輯說明
可把陣列視為一組連續編號的儲存格,每一格都保存相同資料型別的值。只要知道索引值,就能直接找到對應元素。
- 集中管理:原本分散在多個變數中的內容,可以統一放入同一個資料結構。
- 索引定位:第一個元素的索引為 0,之後依序增加 1。
- 邊界明確:陣列可用位置有限,若讀取或寫入超出範圍的索引,會產生執行錯誤。
使用陣列前需先掌握的重點:
- 元素型別一致:一般強型別陣列只能放入指定型別,例如
Integer()只能放整數,String()只能放字串。 - 索引不等於筆數:若陣列長度為 5,最後一個索引是 4,不是 5。
- 宣告數字是最大索引:
Dim values(2)代表可用索引為 0、1、2,因此總共有 3 格。 - 適合固定結構資料:例如月份、成績、部門代號、固定欄位表格資料等。
宣告方式與基本操作
執行環境與物件配置說明
以下範例皆使用 Windows Forms。測試前請建立 Windows Forms 專案,並在 Form1 中依場景放入對應控制項。
Button1:執行範例邏輯。Label1:顯示多行輸出結果,建議將AutoSize設為False,並適度放大寬高。TextBox1:本篇未作為必要控制項;若後續加入查詢或輸入範例,可再使用。
場景一:宣告一維陣列並依索引讀取資料
一維陣列適合處理單列資料,例如班級名稱、月份、部門代號與固定數量的設定值。此類情境的重點,在於先建立陣列,再依索引讀取指定元素。
範例程式碼
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim teamNames() As String = {"開發一組", "開發二組", "測試組", "維運組"}
Dim firstTeam As String = teamNames(0)
Dim thirdTeam As String = teamNames(2)
Label1.Text = "第一個小組:" & firstTeam & vbCrLf &
"第三個小組:" & thirdTeam
End Sub
End Class
邏輯解析
Dim teamNames() As String = {...}代表建立字串型別的一維陣列,並直接放入四筆初始值。teamNames(0)取得第一筆資料,teamNames(2)取得第三筆資料。- 陣列讀取的依據不是資料內容,而是索引位置。
場景二:搭配 For 迴圈批次填入資料
當陣列內容具有明顯規律,例如流水號、等差數列、月份編號或固定計算結果時,常見做法是透過 For 迴圈依索引批次填值。
範例程式碼
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim weeklyQuota(3) As Integer
Dim result As String = "每週出貨目標:" & vbCrLf
For i As Integer = 0 To weeklyQuota.Length - 1
weeklyQuota(i) = (i + 1) * 120
Next
For i As Integer = 0 To weeklyQuota.Length - 1
result &= "第 " & (i + 1).ToString() & " 週:" &
weeklyQuota(i).ToString() & " 件" & vbCrLf
Next
Label1.Text = result
End Sub
End Class
邏輯解析
Dim weeklyQuota(3) As Integer代表建立四格整數陣列,可用索引為 0 到 3。Length代表元素總數,因此本例的weeklyQuota.Length為 4。Length - 1代表最後一個有效索引,常用於控制一維陣列的迴圈邊界。- 此類寫法適合需要「知道位置」的批次處理。
場景三:使用 ReDim 與 ReDim Preserve 調整大小
若初始筆數尚未固定,可先宣告動態陣列,再依實際需求重新配置長度。此時常見的語法是 ReDim 與 ReDim Preserve。
範例程式碼
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim taskNames() As String
ReDim taskNames(1)
taskNames(0) = "需求確認"
taskNames(1) = "版面設計"
ReDim Preserve taskNames(3)
taskNames(2) = "功能開發"
taskNames(3) = "驗收測試"
Label1.Text = String.Join(" → ", taskNames)
End Sub
End Class
邏輯解析
Dim taskNames() As String只宣告名稱與型別,尚未配置實際長度。ReDim taskNames(1)建立兩格空間,可用索引為 0、1。ReDim Preserve taskNames(3)擴充為四格,並保留原有資料。- 若使用
ReDim而未加Preserve,原有資料會在重新配置後消失。
補充提醒:ReDim Preserve 不是單純「原地加格子」,而是重新配置陣列並保留資料。資料量很大或頻繁增減時,通常更適合使用 List(Of T)。
場景四:使用二維陣列管理列欄資料
當資料同時具有列與欄的概念,例如月份 × 品項、員工 × 成績、部門 × 指標時,可使用二維陣列處理。二維陣列的第一個索引通常可視為列,第二個索引通常可視為欄。
範例程式碼
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim monthlyScore(2, 1) As Integer
Dim result As String = "門市評分紀錄:" & vbCrLf
monthlyScore(0, 0) = 86 : monthlyScore(0, 1) = 91
monthlyScore(1, 0) = 79 : monthlyScore(1, 1) = 88
monthlyScore(2, 0) = 93 : monthlyScore(2, 1) = 96
For row As Integer = 0 To monthlyScore.GetUpperBound(0)
result &= "門市 " & (row + 1).ToString() & ":"
For col As Integer = 0 To monthlyScore.GetUpperBound(1)
result &= monthlyScore(row, col).ToString() & " "
Next
result &= vbCrLf
Next
Label1.Text = result
End Sub
End Class
邏輯解析
Dim monthlyScore(2, 1) As Integer代表建立 3 列 × 2 欄的二維陣列。GetUpperBound(0)取得第一維的最後索引,GetUpperBound(1)取得第二維的最後索引。- 二維陣列通常需搭配巢狀
For迴圈,外層處理列,內層處理欄。
常用屬性與方法
陣列不只是儲存資料的容器,本身也提供一些常用成員,用來判斷長度、維度與資料位置。這些成員在寫迴圈、處理多維陣列與搜尋資料時都很常見。
| 名稱 | 用途說明 |
|---|---|
| Length | 取得陣列元素總數;一維陣列最常用來控制迴圈次數。 |
| Rank | 取得陣列維度數;一維回傳 1,二維回傳 2。 |
| GetUpperBound(dimension) | 取得指定維度的最後索引;適合多維陣列處理。 |
| GetLowerBound(dimension) | 取得指定維度的起始索引;一般 VB.NET 陣列起始索引為 0。 |
| Array.IndexOf() | 搜尋指定值在陣列中的位置;找不到時回傳 -1。 |
場景五:搜尋元素位置
若需確認某筆資料是否存在於陣列中,或想知道它位於哪一個索引位置,可使用 Array.IndexOf()。
範例程式碼
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim itemCodes() As String = {"M101", "M205", "M330", "M480"}
Dim targetCode As String = "M330"
Dim index As Integer = Array.IndexOf(itemCodes, targetCode)
If index >= 0 Then
Label1.Text = "品項代碼 " & targetCode & " 的索引位置為:" & index.ToString()
Else
Label1.Text = "查無指定代碼"
End If
End Sub
End Class
邏輯解析
Array.IndexOf(itemCodes, targetCode)會在陣列中搜尋指定值。- 若存在,回傳對應索引;若不存在,回傳
-1。 - 此方法適合查找代碼、部門名稱、身分別與固定分類資料。
使用限制與常見錯誤
陣列雖然單純、效率高,但邊界判斷必須嚴謹。初學者最常遇到的錯誤,就是把「長度」誤當成「最後索引」。
IndexOutOfRangeException
當程式試圖讀取或寫入不存在的索引位置時,系統會拋出 IndexOutOfRangeException。這代表目前要求使用的位置,已超出陣列可用範圍。
錯誤示意程式碼
Dim values(2) As Integer
values(0) = 15
values(1) = 30
values(2) = 45
' 以下寫法已超出可用索引範圍
values(3) = 60
邏輯解析
Dim values(2) As Integer建立三格陣列,可用索引只有 0、1、2。values(3)已超出邊界,因此會直接產生執行例外。- 最常見的避免方式,是以
Length - 1或GetUpperBound()控制讀寫範圍。
使用陣列時需特別注意的限制:
- 大小固定:標準陣列建立後長度固定;需要調整時,本質上是重新配置。
- 型別固定:一般強型別陣列中的元素型別不可混用。
- 邊界嚴格:任何超出索引範圍的存取都會導致例外。
- ReDim Preserve 有成本:資料量大時需留意重新配置帶來的效能負擔。
- 多維 Preserve 有限制:處理多維陣列時,
ReDim Preserve通常只能調整最後一個維度。
語法適用情境分析
| 比較項目 | 陣列 (Array) | 泛型集合 (List) |
|---|---|---|
| 結構特性 | 長度固定,位置明確,適合已知筆數資料。 | 筆數可動態增減,適合資料量經常改變的情況。 |
| 主要優勢 | 語法直接、索引清楚、存取效率高。 | 新增、刪除與擴充彈性較高。 |
| 主要限制 | 調整大小需重新配置,彈性較低。 | 使用前需理解集合方法,例如 Add、Remove、Count。 |
| 適用情境 | 資料筆數固定,且需要依索引快速定位。 | 資料量不固定,且需頻繁新增或移除資料。 |
重點整理
- VB.NET 陣列用來集中管理相同型別的多筆資料。
- 陣列索引從 0 開始;宣告中的數字是最大索引,不是總筆數。
- 一維陣列常搭配
Length - 1控制迴圈,多維陣列常搭配GetUpperBound()。 ReDim Preserve可保留原資料並重新配置陣列,但頻繁調整時應考慮List(Of T)。- 若需求重點是固定筆數與索引定位,陣列很適合;若需求重點是彈性增刪,通常使用
List(Of T)更自然。