Có thể bạn quan tâm: Cách Sắp Xếp Dữ Liệu Trong Excel Theo 2 Cột: Hướng Dẫn Chi Tiết Từ Cơ Bản Đến Nâng Cao
Mở đầu
Khi làm việc với Microsoft Excel, đặc biệt là khi sử dụng Visual Basic for Applications (VBA) để tự động hoá các tác vụ, bạn có thể gặp phải một trong những lỗi phổ biến và gây khó chịu nhất: “Subscript out of range”. Lỗi này thường xuất hiện dưới dạng thông báo pop‑up hoặc trong cửa sổ Immediate/Debug của VBA và làm gián đoạn quá trình chạy macro. Đối với người mới bắt đầu, việc hiểu rõ nguyên nhân và cách khắc phục lỗi này là rất quan trọng để viết mã VBA ổn định, tránh mất thời gian và giảm thiểu rủi ro khi triển khai dự án.
Bài viết dưới đây sẽ cung cấp cho bạn một hướng dẫn chi tiết, toàn diện, từ khái niệm cơ bản, các nguyên nhân phổ biến, cách phát hiện lỗi, tới các phương pháp khắc phục và phòng tránh. Nội dung được chia thành nhiều phần, mỗi phần đi sâu vào từng khía cạnh của lỗi “Subscript out of range”. Hy vọng sau khi đọc xong, bạn sẽ có khả năng:
- Nhận diện lỗi ngay khi xuất hiện.
- Xác định nguyên nhân gốc rễ của lỗi trong mã VBA.
- Áp dụng các kỹ thuật kiểm tra và bảo vệ mã để ngăn ngừa lỗi tái diễn.
- Tối ưu hoá mã VBA để tăng tính ổn định và hiệu năng.
Hãy cùng bắt đầu hành trình khám phá và chinh phục lỗi “Subscript out of range” trong Excel VBA!
Có thể bạn quan tâm: Excel Skills For Business Essentials: Nâng Cao Năng Lực Phân Tích Và Quản Lý Dữ Liệu Trong Doanh Nghiệp
1. Subscript là gì? Giải thích khái niệm cơ bản
1.1. Định nghĩa “Subscript”
Trong lập trình, subscript (hay còn gọi là index) là một chỉ số dùng để truy cập vào một phần tử cụ thể của một mảng (array), bộ sưu tập (collection), danh sách (list) hoặc đối tượng (object). Ví dụ:
Dim arr(1 To 5) As Integer
arr(3) = 10 ' 3 là subscript
Ở đây, 3 là subscript, chỉ ra vị trí thứ ba trong mảng arr. Khi subscript vượt ra ngoài phạm vi hợp lệ (ví dụ: arr(6) trong mảng trên), VBA sẽ ném ra lỗi “Subscript out of range”.
1.2. Các loại subscript trong VBA
- Mảng (Array): Được khai báo với
Dim,ReDim, hoặcArray(). Subscript là số nguyên. - Bộ sưu tập (Collection): Như
Worksheets,Workbooks,Range,Charts. Subscript có thể là số thứ tự hoặc tên (string). - Dictionary (Scripting.Dictionary): Subscript là key, có thể là chuỗi hoặc số.
- Object: Khi truy cập thuộc tính hoặc phương thức thông qua
Object(index), ví dụCells(1, 2).
Hiểu rõ cách hoạt động của subscript giúp ta biết được khi nào lỗi có thể xảy ra.
Có thể bạn quan tâm: Excel Hiển Thị Công Thức Thay Vì Kết Quả: Nguyên Nhân, Giải Pháp Và Cách Khắc Phục
2. Nguyên nhân phổ biến gây ra lỗi “Subscript out of range”
2.1. Truy cập mảng ngoài giới hạn
Dim arr(1 To 10) As Double
Debug.Print arr(11) ' Lỗi Subscript out of range
Nguyên nhân: subscript 11 vượt quá UBound(arr) (10).
2.2. Tên hoặc chỉ số sheet không tồn tại
Set ws = ThisWorkbook.Worksheets("Data2022") ' Nếu không có sheet này → lỗi
Hoặc:
Set ws = ThisWorkbook.Worksheets(5) ' Nếu workbook chỉ có 3 sheet → lỗi
2.3. Tên workbook không tồn tại trong Workbooks collection
Set wb = Workbooks("Report.xlsx") ' Nếu file chưa mở → lỗi
2.4. Sử dụng Range với chỉ số không hợp lệ
Set rng = Worksheets(1).Range("A1:Z1000").Rows(0) ' Row index phải >=1
2.5. Lỗi trong ArrayList hoặc Collection do Item không tồn tại
Dim col As New Collection
col.Add "Apple"
Debug.Print col(2) ' Không có phần tử thứ 2 → lỗi
2.6. Dùng Split trả về mảng rỗng
Dim parts() As String
parts = Split("", ",") ' Trả về mảng một phần tử (chuỗi rỗng), nhưng nếu dùng parts(1) sẽ lỗi
2.7. Đọc dữ liệu từ file hoặc database và cố gắng truy cập cột/row không tồn tại
Dim data As Variant
data = Application.Transpose(Range("A1:A5").Value)
Debug.Print data(6) ' Không có phần tử thứ 6
2.8. Khi dùng Option Base 0 hoặc Option Base 1 không đồng nhất
Nếu bạn khai báo Option Base 0 ở đầu module, các mảng mặc định sẽ bắt đầu từ 0. Khi bạn lại viết code giả định bắt đầu từ 1, lỗi sẽ xuất hiện.
3. Cách phát hiện lỗi “Subscript out of range” trong quá trình phát triển
3.1. Sử dụng Debug → Compile VBA Project
Khi biên dịch, VBA sẽ kiểm tra các lỗi cú pháp và một số lỗi logic như truy cập mảng không tồn tại. Nếu lỗi xuất hiện, thông báo sẽ chỉ ra vị trí.
3.2. Chạy macro trong Break Mode
- Đặt breakpoint (F9) tại các dòng nghi ngờ.
- Khi macro dừng, di chuột lên biến để xem giá trị
LBoundvàUBound. - Kiểm tra
Countcủa collection hoặcWorksheets.Count.
3.3. Sử dụng hàm Debug.Print
Debug.Print "LBound:", LBound(arr), "UBound:", UBound(arr)
Giúp bạn kiểm tra phạm vi mảng trước khi truy cập.
3.4. Dùng On Error Resume Next + kiểm tra Err.Number
Mặc dù không khuyến khích dùng rộng rãi, nhưng trong một khối kiểm tra ngắn, bạn có thể:
On Error Resume Next
Set ws = ThisWorkbook.Worksheets("Data")
If Err.Number <> 0 Then MsgBox "Worksheet not found!" Err.Clear
End If
On Error GoTo 0
Sau khi xử lý, luôn On Error GoTo 0 để bật lại thông báo lỗi.
3.5. Kiểm tra IsArray và IsObject
Khi nhận dữ liệu từ hàm trả về variant, dùng IsArray để xác nhận.
4. Phương pháp khắc phục lỗi “Subscript out of range”

Có thể bạn quan tâm: Cách Tách Chuỗi Trong Excel Bằng Ký Tự Đặc Trưng: Hướng Dẫn Chi Tiết Từ Cơ Bản Đến Nâng Cao
4.1. Kiểm tra và điều chỉnh chỉ số mảng
If idx >= LBound(arr) And idx <= UBound(arr) Then value = arr(idx)
Else MsgBox "Index out of range!"
End If
4.2. Xác thực tồn tại của worksheet, workbook, hoặc range
Function WorksheetExists(wsName As String, Optional wb As Workbook) As Boolean Dim ws As Worksheet If wb Is Nothing Then Set wb = ThisWorkbook On Error Resume Next Set ws = wb.Worksheets(wsName) WorksheetExists = Not ws Is Nothing On Error GoTo 0
End Function
Sử dụng:
If WorksheetExists("Data") Then Set ws = ThisWorkbook.Worksheets("Data")
Else MsgBox "Worksheet 'Data' không tồn tại"
End If
4.3. Đảm bảo workbook đã mở
Function WorkbookIsOpen(wbName As String) As Boolean Dim wb As Workbook On Error Resume Next Set wb = Workbooks(wbName) WorkbookIsOpen = Not wb Is Nothing On Error GoTo 0
End Function
4.4. Sử dụng Try...Catch (VBA không có, nhưng có thể mô phỏng)
On Error GoTo ErrHandler
' Code có thể gây lỗi
Exit Sub
ErrHandler: If Err.Number = 9 Then ' Subscript out of range MsgBox "Lỗi truy cập mảng hoặc collection, kiểm tra chỉ số" Else MsgBox "Lỗi khác: " & Err.Description End If Resume Next
4.5. Thêm kiểm tra Count cho collection
If col.Count >= desiredIndex Then Debug.Print col(desiredIndex)
Else MsgBox "Collection không đủ phần tử"
End If
4.6. Khi làm việc với Split
Dim parts() As String
parts = Split(txt, ",")
If UBound(parts) >= 1 Then Debug.Print parts(1) ' An toàn
Else Debug.Print "Không có phần tử thứ 2"
End If
4.7. Đối với Range và Cells
With ws If .Rows.Count >= targetRow And .Columns.Count >= targetCol Then .Cells(targetRow, targetCol).Value = "OK" Else MsgBox "Row hoặc Column vượt quá giới hạn" End If
End With
4.8. Đồng nhất Option Base
- Nếu bạn muốn mảng bắt đầu từ 1, đặt
Option Base 1ở đầu module. - Hoặc luôn xác định chỉ số khi khai báo:
Dim arr(0 To 9) As Integer.
5. Các ví dụ thực tế và cách xử lý
5.1. Ví dụ 1: Đọc dữ liệu từ cột A và tính tổng
Sub SumColumnA() Dim ws As Worksheet Dim lastRow As Long Dim arr() As Variant Dim i As Long, total As Double Set ws = ThisWorkbook.Worksheets("Data") lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row If lastRow < 1 Then MsgBox "Không có dữ liệu" Exit Sub End If arr = ws.Range("A1:A" & lastRow).Value ' arr là 2‑dimensional array (1 to lastRow, 1 to 1) For i = 1 To UBound(arr, 1) If IsNumeric(arr(i, 1)) Then total = total + arr(i, 1) End If Next i MsgBox "Tổng: " & total
End Sub
Giải thích: Sử dụng UBound(arr, 1) để tránh lỗi khi lastRow = 0.
5.2. Ví dụ 2: Sao chép dữ liệu sang sheet mới, kiểm tra tồn tại sheet
Sub CopyToNewSheet() Dim srcWs As Worksheet, destWs As Worksheet Dim sheetName As String Set srcWs = ThisWorkbook.Worksheets("Source") sheetName = "Result_" & Format(Now, "yyyymmdd") If WorksheetExists(sheetName) Then Set destWs = ThisWorkbook.Worksheets(sheetName) Else Set destWs = ThisWorkbook.Worksheets.Add(After:=Worksheets(Worksheets.Count)) destWs.Name = sheetName End If srcWs.UsedRange.Copy Destination:=destWs.Range("A1") MsgBox "Sao chép hoàn tất!"
End Sub
Lưu ý: Hàm WorksheetExists được định nghĩa ở mục 4.2.
5.3. Ví dụ 3: Xử lý lỗi khi mở workbook không tồn tại
Sub OpenReport() Dim wb As Workbook Dim path As String path = "C:\Reports\MonthlyReport.xlsx" If Dir(path) = "" Then MsgBox "File không tồn tại: " & path Exit Sub End If On Error Resume Next Set wb = Workbooks.Open(path) If Err.Number <> 0 Then MsgBox "Không mở được file: " & Err.Description Err.Clear Exit Sub End If On Error GoTo 0 MsgBox "Mở file thành công!"
End Sub
Giải thích: Kiểm tra tồn tại file trước, sau đó bắt lỗi mở.
6. Thực hành phòng tránh lỗi “Subscript out of range”
6.1. Viết hàm tiện ích kiểm tra chỉ số
Function IsValidIndex(arr As Variant, idx As Long, Optional dimNum As Long = 1) As Boolean On Error Resume Next IsValidIndex = (idx >= LBound(arr, dimNum)) And (idx <= UBound(arr, dimNum)) On Error GoTo 0
End Function
Sử dụng:
If IsValidIndex(myArray, i) Then Debug.Print myArray(i)
End If
6.2. Sử dụng Option Explicit
Bắt buộc khai báo biến, giúp tránh lỗi typo trong tên biến, đặc biệt là khi dùng ws vs Ws.
6.3. Đặt On Error GoTo 0 ngay sau khối kiểm tra
Giúp tránh việc lỗi tiếp tục bị ẩn sau On Error Resume Next.
6.4. Kiểm tra Count cho mọi collection
If myCollection.Count > 0 Then ' Thao tác
End If
6.5. Ghi log lỗi
Ghi thông tin lỗi vào một sheet log hoặc file text để dễ dàng debug sau này.
Sub LogError(errNum As Long, errDesc As String, procName As String) Dim logWs As Worksheet Set logWs = ThisWorkbook.Worksheets("ErrorLog") With logWs .Cells(.Rows.Count, 1).End(xlUp).Offset(1, 0).Value = Now .Cells(.Rows.Count, 2).End(xlUp).Offset(1, 0).Value = procName .Cells(.Rows.Count, 3).End(xlUp).Offset(1, 0).Value = errNum .Cells(.Rows.Count, 4).End(xlUp).Offset(1, 0).Value = errDesc End With
End Sub
7. Khi nào lỗi “Subscript out of range” không phải do bạn?
- File Excel bị hỏng: Đôi khi file .xlsm/.xlsx có cấu trúc hỏng, làm cho VBA không đọc đúng tên sheet hoặc range.
- Thêm hoặc xóa sheet trong khi macro đang chạy: Nếu macro mở một workbook và người dùng thủ công thay đổi cấu trúc, chỉ số có thể thay đổi.
- Macro đang chạy trên phiên bản Excel khác: Một số tính năng như
Dynamic Arrayschỉ có trên Excel 365, gây ra lỗi khi chạy trên Excel 2026.
Giải pháp: Đóng tất cả workbook khác, tắt chế độ chỉnh sửa thủ công, và chạy macro trong môi trường kiểm soát.
8. Tổng kết
Lỗi “Subscript out of range” trong Excel VBA là một trong những lỗi “cơ bản” nhưng lại có thể gây ra những gián đoạn nghiêm trọng nếu không được xử lý đúng cách. Bằng cách:
- Hiểu rõ khái niệm subscript và các loại đối tượng có thể gây lỗi.
- Nhận diện các nguyên nhân phổ biến như truy cập mảng, sheet, workbook, collection không tồn tại.
- Kiểm tra giá trị
LBound,UBound,Count, và tồn tại của đối tượng trước khi truy cập. - Áp dụng các kỹ thuật phòng tránh như hàm tiện ích,
Option Explicit, và ghi log lỗi. - Thực hiện debug một cách có hệ thống (breakpoint, Immediate Window,
Debug.Print).
Bạn sẽ giảm thiểu đáng kể khả năng gặp lỗi và nâng cao độ tin cậy của các macro VBA trong dự án của mình. Hãy áp dụng những kiến thức này ngay vào các macro hiện có và cảm nhận sự khác biệt!
Tài liệu tham khảo & nguồn học thêm
- Microsoft Docs: VBA Language Reference – các hàm
LBound,UBound,Worksheets,Workbooks. - “Mastering VBA for Microsoft Office 365” – Richard Mansfield.
- Các diễn đàn như Stack Overflow, MrExcel, Reddit r/vba – nơi cộng đồng chia sẻ các tình huống thực tế và giải pháp.
Chúc bạn lập trình VBA hiệu quả, ít lỗi và luôn đạt được mục tiêu tự động hoá công việc trong Excel!

Tiến sĩ Lê Thống Nhất sinh năm 1955 tại Nghệ An, là nhà giáo, nhà báo và doanh nhân trong lĩnh vực giáo dục. Ông từng giảng dạy Toán học tại Trường THPT Chuyên Phan Bội Châu và đảm nhiệm nhiều vai trò trong ngành giáo dục, từ viết sách, biên soạn tài liệu đến sáng lập các dự án hỗ trợ học tập trực tuyến.
Ông là người sáng lập BigSchool – nền tảng giáo dục trực tuyến kết nối giáo viên và học sinh cả nước. Ngoài ra, ông còn nổi tiếng với vai trò tác giả, diễn giả truyền cảm hứng và khách mời trên nhiều chương trình truyền hình, trong đó có “Ai là triệu phú” trên truyền hình VTV.
Trong suốt sự nghiệp, Tiến sĩ Lê Thống Nhất đã nhận nhiều giải thưởng giáo dục và được biết đến như một người luôn đổi mới, ứng dụng công nghệ vào dạy và học, góp phần lan tỏa tri thức và niềm say mê học tập cho thế hệ trẻ.
