Run Time Error 9: Subscript Out Of Range In Excel

Mục lục bài viết

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.

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.

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

Run Time Error 9 Subscript Out Of Range Excel
Run Time Error 9 Subscript Out Of Range Excel
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 Error nhẹ 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ả
1Sử dụng Option ExplicitBắt buộc khai báo biến, tránh lỗi chính tả.
2Kiểm tra tồn tạiKiểm tra sheet, workbook, range, mảng trước khi truy cập.
3Dùng LBound/UBoundTránh truy cập ngoài giới hạn mảng.
4Không dùng On Error Resume Next mà không kiểm traNếu cần, kiểm tra Err.Number ngay sau lệnh.
5Tạo hàm tiện íchHàm lấy sheet an toàn, kiểm tra workbook, tạo sheet động.
6Sử dụng Constant cho tên sheetTránh lỗi chính tả的发展.
7Kiểm tra độ dài chuỗiTránh lỗi khi dùng Mid, Left, Right.
8Ghi log lỗiKhi có lỗi, ghi vào log file hoặc bảng điều khiển để theo dõi.
9Xác định giới hạn của ExcelVí dụ, Cells(1, 1).Offset(1048576Dif, 0) will error.
10Sử dụng WithGiả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 Explicit và 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/UBound cho mảng.
  • Kiểm tra Err.Number khi dùng On 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.

⚠️
LƯU Ý QUAN TRỌNG: Miễn trừ trách nhiệm: Mặc dù chúng tôi luôn nỗ lực để đảm bảo tính chính xác và cập nhật của thông tin, nhưng các quy định về giáo dục và tuyển sinh có thể thay đổi theo thời gian. BigSchool không chịu trách nhiệm về bất kỳ sai sót nào hoặc kết quả phát sinh từ việc sử dụng thông tin trên trang này. Độc giả nên liên hệ trực tiếp với nhà trường hoặc cơ quan chức năng để có thông tin mới nhất. Ngoài ra, BigSchool tuyệt đối không bán sản phẩm, khóa học hay cung cấp dịch vụ được nhắc đến trong bài.

Viết một bình luận