Có thể bạn quan tâm: Phần Mềm Tính Giá Thành Sản Phẩm Bằng Excel
Giới thiệu
Trong khi làm việc với VBA (Visual Basic for Applications) trong Excel, một trong những lỗi phổ biến nhất mà lập trình viên mới và cả những người đã có kinh nghiệm đều gặp phải là Run Time Error 9 – Subscript Out Of Range. Lỗi này thường xuất hiện khi bạn cố gắng truy cập vào một phần tử trong một mảng, bộ sưu tập, workbook, worksheet, range hoặc bất kỳ đối tượng nào mà chỉ mục (index) của bạn vượt quá giới hạn hợp lệ. Dù lỗi này có vẻ đơn giản, nhưng nó có thể gây ra những rắc rối lớn trong quá trình phát triển và bảo trì mã nguồn, đặc biệt khi các lỗi không được tìm thấy ngay lập tức trong quá trình kiểm thử.
Bài viết này sẽ đi sâu vào:
– Cơ chế gây ra lỗi Subscript Out Of Range.
– Những tình huống thường gặp trong Excel VBA.
– Cách kiểm tra và khắc phục lỗi.
– Những quy tắc phòng ngừa và best practices để tránh lặp lại lỗi này.
– Một số ví dụ thực tế và giải pháp chi tiết.
Có thể bạn quan tâm: Phần Mềm Quản Lý Nhân Sự Excel Miễn Phí: Giải Pháp Tối Ưu Cho Doanh Nghiệp Vừa Và Nhỏ
1. Nguồn gốc của lỗi Subscript Out Of Range
1.1 Định nghĩa “Subscript”
Trong lập trình, “subscript” thường đề cập đến chỉ mục của một phần tử trong một mảng hoặc bộ sưu tập. Ví dụ, trong mảng arr(1 To 5), các chỉ mục hợp lệ là 1, 2, 3, 4, 5. Nếu bạn cố gắng truy cập arr(6), sẽ có lỗi Subscriptpressions.
1.2 Khi nào lỗi xảy ra?
- Mảng (Array): Truy cập chỉ mục không tồn tại hoặc mảng chưa được khởi tạo.
- Workbook/Worksheet: Truy cập tài liệu hoặc trang tính không tồn tại, đã bị xóa, hoặc tên sai chính tả.
- Rangeformula: Sử dụng
.Range("A oziroma")với tham chiếu sai. - Collection: Truy cập phần tử trong
Worksheets,ٹل,Shapes,CustomCollection. - String: Truy cập ký tự
Mid$,Left$,Right$với vị trí vượt quá độ dài chuỗi. - Chart, PivotTable: Truy cập đối tượng biểu đồ hoặc bảng pivot không tồn tại.
Có thể bạn quan tâm: Phần Mềm Quản Lý Chi Tiêu Cá Nhân Trên Excel: Cách Tối Ưu Hóa Tài Chính Cá Nhân
2. Các tình huống phổ biến trong Excel VBA
2.1 Truy cập Worksheet bằng tên hoặc chỉ mục
Set ws = ThisWorkbook.Worksheets("Data") ' Nếu sheet "Data" không tồn tại
Set ws = ThisWorkbook.Worksheets(5) ' Nếu workbook chỉ có 3 sheet
Chú ý: Khi sử dụng chỉ mục, Excel tính từ 1 tới số sheet. Không có sheet 0.
2.2 Truy cập Workbook chưa mở
Set wb = Workbooks("Report.xlsx") ' Nếu file không được mở hoặc bị rename
2.3 Mảng động chưa được khởi tạo
Dim arr() As Variant
arr(1) = "Hello" ' Lỗi vì chưa ReDim arr
2.4 Mảng đa chiều
Dim multiArr(1 To 3, 1 To 2) As Integer
Debug.Print multiArr(4, 1) ' Lỗi vì chỉ mục 4 không tồn tại
2.5 Truy cập range sai
ws.Range("A1:C3").Offset(1000, 0).Value = "Test" ' Offsetting vượt quá phạm vi sheet
2.6 Truy cập shape hoặc object
Set shp = ws.Shapes(10) ' Nếu sheet chỉ có 5 shape
3. Cách kiểm tra và khắc phục lỗi
3.1 Sử dụng Option Explicit và khai báo biến
Option Explicit
Điều này giúp tránh các lỗi do chính tả hoặc biến chưa khai báo, vốn có thể gây ra lỗi subscript khi bạn cố gắng truy cập một biến không tồn tại.
3.2 Kiểm tra tồn tại của đối tượng trước khi truy cập
3.2.1 Kiểm tra Worksheet
Function WorksheetExists(shtName As String, wb As Workbook) As Boolean On Error Resume Next WorksheetExists = Not wb.Worksheets(shtName) Is Nothing On Error GoTo 0
End Function
Sử dụng:
If WorksheetExists("Data", ThisWorkbook) Then Set ws = ThisWorkbook.Worksheets("Data")
Else MsgBox "Sheet Data không tồn tại!"
End If
3.2.2 Kiểm tra Workbook
Function WorkbookExists(wbName As String) As Boolean On Error Resume Next WorkbookExists = Not Workbooks(wbName) Is Nothing On Error GoTo 0
End Function
3.2.3 Kiểm tra mảng
If Not IsEmpty(arr) Then ' Mảng đã khởi tạo
End If
3.3 Sử dụng LBound và UBound cho mảng
Dim i As Long
For i = LBound(arr) To UBound(arr) Debug.Print arr(i)
Next i
Điều này tránh lỗi khi mảng có LBound khác 0.
3.4 Tránh On Error Resume Next mà không kiểm tra
On Error Resume Next có thể che giấu lỗi, khiến việc debug trở nên khó khăn. Nếu bạn thực sự cần nó, hãy luôn kiểm tra Err.Number ngay sau lệnh có thể gây lỗi.
On Error Resume Next
Set ws = ThisWorkbook.Worksheets("Data")
If Err.Number <> 0 Then MsgBox "Lỗi: " & Err.Description Err.Clear
End If
On Error GoTo 0
3.5 Kiểm tra độ dài chuỗi khi dùng Mid, Left, Right
Dim txt As String
txt = "Hello"
If Len(txt) >= 3 Then Debug.Print Mid(txt, 3, 2)
Else MsgBox "Chuỗi quá ngắn!"
End If
3.6 Sử dụng With để tránh lặp lại đối tượng

Có thể bạn quan tâm: Quản Lý Dự Án Trên 1 Trang Giấy Excel: Bí Quyết Tối Ưu Công Việc
With ThisWorkbook.Worksheets("Data") .Range("A1").Value = "Hello" ' ...
End With
3.7 Kiểm tra số lượng phần tử trong Collection
If Worksheets.Count >= 5 Then Set ws = Worksheets(5)
Else MsgBox "Không đủ sheet"
End If
4. Các kỹ thuật nâng cao để phòng tránh lỗi
4.1 Sử dụng Enum hoặc Constant cho tên sheet
Public Const SHEET_DATA As String = "Data"
Public Const SHEET_REPORT As String = "Report"
Bằng cách này, bạn tránh bị lỗi chính tả khi gọi tên sheet.
4.2 Tạo hàm lấy sheet an toàn
Function GetSheet(name As String, Optional wb As Workbook = Nothing) As Worksheet If wb Is Nothing Then Set wb = ThisWorkbook On Error Resume Next Set GetSheet = wb.Worksheets(name) On Error GoTo 0
End Function
Sử dụng:
Set ws = GetSheet("Data")
4.3 Dùng Set và Is presumed để kiểm tra đối tượng
Set ws = Nothing
On Error Resume Next
Set ws = ThisWorkbook.Worksheets("Data")
On Error GoTo 0 If ws Is Nothing Then MsgBox "Sheet không tồn tại!"
End If
4.4 Lập trình với Error Handling nâng cao
Sub SafeOperation() On Error GoTo ErrHandler ' Mã có thể gây lỗi Dim ws As Worksheet Set ws = ThisWorkbook.Worksheets("Data") ws.Range("A1").Value = "Test" Exit Sub
ErrHandler: MsgBox "Lỗi " & Err.Number & ": " & Err.Description Err.Clear
End Sub
4.5 Kiểm tra kích thước workbook
If ThisWorkbook.Sheets.Count > 0 Then Honda...
4.6 Sử dụng WorksheetFunction thay vì Application.WorksheetFunction khi cần
Khi gọiémie, Application.WorksheetFunction có thể gây lỗi nếu tham số không hợp lệ.
5. Ví dụ thực tế: Khắc phục lỗi trong một macro
5.1 Tình huống
Bạn có một macro để sao chép dữ liệu từ sheet “Source” sang sheet “Destination” trong workbook hiện tại. Khi sheet “Destination” chưa tồn tại, macro ném lỗi Subscript Out Of Range.
Sub CopyData() Dim src As Worksheet, dst As Worksheet Set src = ThisWorkbook.Worksheets("Source") Set dst = ThisWorkbook.Worksheets("Destination") src.Range("A1:D10").Copy Destination:=dst.Range("A1")
End Sub
5.2 Giải pháp
- Kiểm tra tồn tại sheet.
- Tạo sheet nếu chưa tồn tại.
- Sử dụng
On Errornhẹ nhàng.
Sub CopyData() Dim src As Worksheet, dst As Worksheet On Error Resume Next Set src = ThisWorkbook.Worksheets("Source") Set dst = ThisWorkbook.Worksheets("Destination") On Error GoTo 0 If src Is Nothing Then MsgBox "Sheet Source không tồn tại!" Exit Sub End If If dst Is Nothing Then Set dst = ThisWorkbook.Worksheets.Add(After:=Worksheets(Worksheets.Count)) dst.Name = "Destination" End If src.Range("A1:D10").Copy Destination:=dst.Range("A1")
End Sub
Bây giờ macro sẽ chạy mà không gây lỗi Subscript Out Of Range.
5.3 Kiểm tra mảng
Giả sử bạn muốn lấy một mảng từ một range:
Dim arr() As Variant
arr = src.Range("A1:D10").Value
Nếu src.Range("A1:D10") rỗng, arr sẽ trở thành một mảng 1D 1 phần tử Empty. Khi bạn cố gắng truy cập arr(2, 1) sẽ gây lỗi Subscript Out Of Range. Do đó, kiểm tra trước:
If Not IsEmpty(arr) Then ' Truy cập arr
Else MsgBox "Range r cried."
End If
5.4 Kiểm tra offset
Sub OffsetTest() Dim ws As Worksheet Set ws = ThisWorkbook.Worksheets("Data") ' Offset 1000 rows sẽ vượt quá giới hạn 1048576 On Error Resume Next ws.Cells(1, 1).Offset(1000, 0).Value = "Test" If Err.Number <> 0 Then MsgBox "Offset vượt quá giới hạn: " & Err.Description Err.Clear End If On Error GoTo 0
End Sub
6. Khi nào Run Time Error 9 oefeningen?
6.1 Khi bạn gọi hàm không có trong module
Call MyFunction
Nếu MyFunction không được khai báo, sẽ ném lỗi 9.
6.2 Khi bạn sử dụng Application.Run với tên macro không tồn tại
Application.Run "NonExistentMacro"
`` outputs error 9. ### 6.3 Khi bạn sử dụng `Range` với tham chiếu không hợp lệ ```vba
Range("ZZZ1")
6.4 Khi bạn dùng Shapes hoặc Pictures mà không kiểm tra
Set shp = ws.Shapes(999)
7. Lời khuyên thực tiễn (Best Practices)
| # | Kiến nghị | Mô tả |
|---|---|---|
| 1 | Sử dụng Option Explicit | Bắt buộc khai báo biến, tránh lỗi chính tả. |
| 2 | Kiểm tra tồn tại | Kiểm tra sheet, workbook, range, mảng trước khi truy cập. |
| 3 | Dùng LBound/UBound | Tránh truy cập ngoài giới hạn mảng. |
| 4 | Không dùng On Error Resume Next mà không kiểm tra | Nếu cần, kiểm tra Err.Number ngay sau lệnh. |
| 5 | Tạo hàm tiện ích | Hàm lấy sheet an toàn, kiểm tra workbook, tạo sheet động. |
| 6 | Sử dụng Constant cho tên sheet | Tránh lỗi chính tả的发展. |
| 7 | Kiểm tra độ dài chuỗi | Tránh lỗi khi dùng Mid, Left, Right. |
| 8 | Ghi log lỗi | Khi có lỗi, ghi vào log file hoặc bảng điều khiển để theo dõi. |
| 9 | Xác định giới hạn của Excel | Ví dụ, Cells(1, 1).Offset(1048576Dif, 0) will error. |
| 10 | Sử dụng With | Giảm lặp lại đối tượng, giảm khả năng nhầm lẫn. |
8. Tóm tắt
- Run Time Error 9 – Subscript Out Of Range là lỗi phổ biến trong VBA khi truy cập phần tử ngoài giới hạn hợp lệ của mảng, workbook, worksheet, range, hoặc bất kỳ đối tượng bộ sưu tập nào.
- Lỗi thường xuất hiện khi:
- Truy cập sheet/bộ sưu tập bằng tên không tồn tại hoặc chỉ mục sai.
- Mảng chưa được khởi tạo hoặc được truy cập vượt giới hạn.
- Range hoặc offset vượt quá giới hạn của worksheet.
- Chuỗi quá ngắn khi dùng
Mid,Left,Right. - Gọi hàm hoặc macro không tồn tại.
- Các biện pháp khắc phục:
- Sử dụng
Option Explicitvà khai báo biến. - Kiểm tra tồn tại của đối tượng trước khi truy cập.
- Dùng
LBound/UBoundcho mảng. - Kiểm tra
Err.Numberkhi dùngOn Error Resume Next. - Tạo hàm tiện ích để lấy sheet, workbook an toàn.
наму - Các best practice giúp phòng tránh lỗi:
- Sử dụng constant cho tên sheet.
- Kiểm tra độ dài chuỗi.
- Ghi log lỗi.
- Không lạm dụng
On Error Resume Next.
Như vậy, với việc hiểu rõ nguyên nhân, biết cách kiểm tra và khắc phục, bạn sẽ có thể xử lý lỗi Subscript Out Of Range một cách nhanh chóng và hiệu quả, đồng thời tăng tính ổn định cho các macro Excel của mình.

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ẻ.
