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 LBound và UBound. 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.

