Cách khắc phục nhanh trong 10 giây
Có lẽ bạn đã quên từ khóa Set. Trong VBA, các kiểu dữ liệu tiêu chuẩn như Integers hay Strings được gán trực tiếp, nhưng các đối tượng như Ranges, Worksheets, và Workbooks yêu cầu Set để khởi tạo biến. Nếu không có nó, VBA không có địa chỉ bộ nhớ nào để trỏ tới.
' Sai - Lỗi này kích hoạt Error 91
Dim rng As Range
rng = Range("A1")
' Đúng - Điều này liên kết đối tượng một cách chính xác
Dim rng As Range
Set rng = Range("A1")
Nếu bạn đang sử dụng .Find, lỗi này thường có nghĩa là kết quả tìm kiếm của bạn bị trống. Luôn xác minh kết quả không phải là Nothing trước khi bạn cố gắng sử dụng nó.
Tại sao lỗi này xảy ra
Hãy coi một biến đối tượng giống như một chiếc điều khiển từ xa. Trước khi nó có thể hoạt động, bạn phải ghép nối nó với một thiết bị cụ thể. VBA đưa ra Error 91 khi bạn cố gắng nhấn một nút trên điều khiển từ xa chưa được ghép nối với bất kỳ thứ gì.
Về mặt kỹ thuật, biến đang trỏ tới Nothing. Khác với một con số mặc định là 0, một biến đối tượng chỉ là một con trỏ. Nếu con trỏ đó chưa được gán cho một địa chỉ bộ nhớ hợp lệ, VBA sẽ đi vào ngõ cụt ngay khi bạn yêu cầu một thuộc tính hoặc phương thức.
Hãy cẩn thận với những bẫy phổ biến sau:
- Bỏ qua 'Set': Cố gắng gán một đối tượng bằng một dấu bằng đơn giản.
- Tìm kiếm "ma": Giả định rằng
Cells.Findsẽ luôn tìm thấy kết quả khớp trong tập dữ liệu của bạn. - Biến bị xóa: Đặt một đối tượng thành
Nothingở giữa đoạn mã và sau đó cố gắng gọi nó sau đó. - Khối 'With' trống: Sử dụng
With MyObjectkhiMyObjectvẫn chưa được tạo.
Khắc phục các tình huống phổ biến
1. Từ khóa 'Set' thiết yếu
Đây là lỗi thường gặp nhất. Nếu biến của bạn đại diện cho một Range, Worksheet, Chart, hoặc Class tùy chỉnh, Set là bắt buộc. Hãy sử dụng nó mỗi khi bạn gán một đối tượng.
Sub FixMissingSet()
Dim ws As Worksheet
' Error 91 xảy ra tại đây nếu thiếu "Set"
Set ws = ThisWorkbook.Sheets("Annual_Report_2024")
MsgBox ws.Name
End Sub
2. Tìm kiếm an toàn với .Find
Phương thức .Find là một nguồn gây ra sự cố khét tiếng. Nếu cụm từ tìm kiếm của bạn (ví dụ: "Invoice_999") không có trong trang tính, Find sẽ trả về Nothing. Nếu bạn ngay lập tức cố gắng truy cập .Address, macro sẽ thất bại ngay lập tức.
Sub SafeFind()
Dim foundRng As Range
Dim targetValue As String
targetValue = "Missing_ID_5505"
Set foundRng = Cells.Find(What:=targetValue)
' Luôn xác thực kết quả tìm kiếm trước tiên
If Not foundRng Is Nothing Then
MsgBox "Found at: " & foundRng.Address
Else
MsgBox "Value " & targetValue & " was not found."
End If
End Sub
3. Khởi tạo các Class tùy chỉnh
Khi làm việc với các module Class tùy chỉnh, việc khai báo biến là chưa đủ. Bạn phải tạo một phiên bản mới của class đó trong bộ nhớ một cách rõ ràng.
Sub ClassExample()
Dim emp As clsEmployee
' Sử dụng từ khóa New để tránh Error 91
Set emp = New clsEmployee
emp.Name = "Jane Smith"
End Sub
Chiến lược gỡ lỗi thông minh
Nếu nguyên nhân không rõ ràng, hãy sử dụng các công cụ tích hợp sẵn sau để săn tìm biến chưa được khởi tạo:
Kiểm tra cửa sổ Locals
- Trong trình soạn thảo VBA, nhấp vào View > Locals Window.
- Nhấn F8 để chạy từng dòng mã của bạn.
- Để ý cột "Value". Tìm bất kỳ biến đối tượng nào hiển thị
Nothingngay trước khi xảy ra sự cố.
Khóa các biến với Option Explicit
Thêm Option Explicit vào ngay đầu các module mã của bạn. Nó buộc bạn phải khai báo mọi biến. Điều này ngăn chặn các lỗi đánh máy đơn giản tạo ra các biến "ma" không được khởi tạo và dẫn đến Error 91.
Cách xác minh bản sửa lỗi
Kiểm tra mã của bạn với ba tình huống sau để đảm bảo mã hoạt động ổn định:
- Kiểm tra "Không có kết quả": Chạy mã tìm kiếm của bạn với một giá trị chắc chắn không tồn tại. Nó sẽ thoát ra một cách êm đẹp.
- Kiểm tra trang tính trống: Thử chạy macro trên một trang tính mới, trống. Kiểm tra xem các tham chiếu như
UsedRangecó gây ra vấn đề hay không. - Truy vấn cửa sổ Immediate: Khi lỗi hiện lên, nhấn 'Debug'. Nhấn Ctrl+G và nhập
?VariableName Is Nothing. Nếu nó trả vềTrue, bạn đã tìm thấy thủ phạm.
Bảng tóm tắt
Tình huống
Lỗi sai
Cách sửa
Gán trực tiếp
`rng = Range("B2")`
Sử dụng `Set rng = ...`
Tìm kiếm thất bại
`Find(...).Value`
Kiểm tra `If Not ... Is Nothing`
Đặt lại thủ công
`Set x = Nothing`
Gán lại với `Set` trước khi tái sử dụng

