Cách sửa lỗi 'Run-time error 9: Subscript out of range' trong Excel VBA

beginner📊 Microsoft Excel2026-04-11| Microsoft Excel (Office 365, 2021, 2019, 2016) trên Windows hoặc macOS

Error Message

Run-time error '9': Subscript out of range
#excel#vba#khắc-phục-lỗi#mẹo-lập-trình

Giải pháp nhanh

Hãy coi Run-time error '9' là cách VBA thông báo: "Tôi hiểu bạn đang yêu cầu gì, nhưng tôi không tìm thấy nó trong tập hợp (collection)." Thông thường, bạn đang cố gắng truy cập vào một worksheet, workbook hoặc phần tử mảng không tồn tại.

  • Xác minh tên Sheet: Kiểm tra xem Sheets("Data") có khớp chính xác với tên tab hay không. Chỉ cần một khoảng trắng thừa ở cuối như "Data " cũng sẽ gây ra lỗi này.
  • Kiểm tra trạng thái Workbook: Đảm bảo tệp đang mở. VBA không thể tham chiếu đến Workbooks("Report.xlsx") nếu tệp đó vẫn đang nằm trên ổ cứng và chưa được mở.
  • Kiểm tra giới hạn mảng: Nếu vòng lặp của bạn chạy từ 1 đến 10 trên một danh sách chỉ có 5 mục, mã nguồn sẽ bị lỗi ở mục thứ 6.

Tại sao lỗi này xảy ra

VBA hoạt động cực kỳ máy móc. Nó không đoán ý của bạn mà tìm kiếm sự trùng khớp chính xác. Dưới đây là ba tình huống chiếm khoảng 95% các trường hợp gặp lỗi này:

1. Bẫy khoảng trắng vô hình

Lỗi nhập liệu là nguyên nhân phổ biến nhất. Nếu mã của bạn tham chiếu đến Sheets("Invoices") nhưng người dùng vô tình đổi tên tab thành "Invoices " (có dấu cách ở cuối), macro sẽ thất bại. Điều này cũng xảy ra với các ký tự ẩn khi sao chép dữ liệu từ các phần mềm bên ngoài như SAP hoặc Oracle.

2. Tham chiếu đến Workbook đang đóng

Tập hợp Workbooks() của VBA chỉ bao gồm các tệp hiện đang mở trong phiên làm việc Excel đang hoạt động. Nếu bạn cố gắng lấy dữ liệu từ Workbooks("Q4_Results.csv") khi tệp đang đóng, bạn sẽ thấy Lỗi 9. Bạn phải mở tệp trước bằng lệnh Workbooks.Open trước khi có thể tham chiếu tệp theo tên.

3. Sai sót khi đánh chỉ số mảng

Theo mặc định, các mảng trong VBA bắt đầu từ chỉ số 0. Nếu bạn khai báo Dim MyList(5), thực tế bạn có sáu vị trí (từ 0 đến 5). Tuy nhiên, nhiều lập trình viên giả định mảng bắt đầu từ 1. Nếu bạn cố gắng truy cập MyList(10), bạn đã vượt ra ngoài vùng bộ nhớ được cấp phát cho biến đó.

Cách khắc phục

Cách 1: Sử dụng CodeName của Sheet (Được khuyến nghị)

Đừng phụ thuộc vào tên tab mà người dùng có thể thay đổi. Trong VBA Project Explorer, bạn sẽ thấy Sheet1 (Sales). Sheet1 chính là CodeName. Hãy sử dụng nó trực tiếp trong mã của bạn. Nó sẽ không bị lỗi ngay cả khi ai đó đổi tên tab từ "Sales" thành "Old Sales".

' Dễ bị lỗi: Sẽ hỏng nếu tab bị đổi tên
Sheets("Sales").Range("A1").Value = 100

' Ổn định: Hoạt động bất kể tên tab là gì
Sheet1.Range("A1").Value = 100

Cách 2: Tham chiếu Workbook an toàn

Đừng bao giờ giả định một tệp đang mở. Hãy sử dụng một bước kiểm tra đối tượng đơn giản để ngăn macro bị treo. Nếu bạn đang làm việc trong cùng một tệp nơi chứa mã nguồn, hãy sử dụng ThisWorkbook thay vì tên tệp.

Dim wb As Workbook
On Error Resume Next
Set wb = Workbooks("Data_Source.xlsx")
On Error GoTo 0

If wb Is Nothing Then
    MsgBox "Lỗi: Data_Source.xlsx chưa được mở.", vbCritical
    Exit Sub
End If

Cách 3: Giới hạn mảng động

Tránh việc cố định các con số như For i = 1 To 10. Thay vào đó, hãy sử dụng hàm LBoundUBound. Các hàm này tự động phát hiện điểm bắt đầu và kết thúc của mảng, giúp mã của bạn linh hoạt hơn.

Dim prices As Variant
prices = Range("A1:A50").Value ' Tạo một mảng 2 chiều

Dim i As Long
' Vòng lặp này tự động thích ứng với kích thước của vùng dữ liệu
For i = LBound(prices, 1) To UBound(prices, 1)
    Debug.Print prices(i, 1)
Next i

Cách xác minh việc khắc phục

Khi lỗi xảy ra, hãy nhấn nút Debug. Dòng màu vàng sẽ chỉ trực tiếp vào đối tượng mà VBA không tìm thấy. Sử dụng Immediate Window (Ctrl+G) để kiểm tra đối tượng. Nhập ?Sheets("YourName").Name và nhấn Enter. Nếu nó trả về lỗi tại đó, nghĩa là bạn đã viết sai tên hoặc sheet đó không tồn tại.

Mẹo chuyên nghiệp

Chạy dòng mã này trong Immediate Window để tìm các khoảng trắng ẩn trong tên sheet của bạn: For Each sh In Sheets: Debug.Print "'" & sh.Name & "'": Next. Các dấu nháy đơn sẽ giúp bạn dễ dàng nhận ra bất kỳ khoảng trắng nào ở đầu hoặc cuối tên.

Related Error Notes