Lỗi khi chạy code VBA

tuhocvba

Administrator
Thành viên BQT
Lỗi của một chương trình được phân loại theo nguyên nhân hoặc theo thời gian phát sinh lỗi.
Có rất nhiều cách phân loại lỗi, và cũng có nhiều cách nghĩ về lỗi. Khi chúng ta đang tạo macro bằng VBA excel thì phát sinh lỗi, chúng ta tiến hành phân loại lỗi.
  • Lỗi câu lệnh sai.
  • Lỗi biên dịch
  • Lỗi không thể thực thi
Lỗi câu lệnh sai, là lỗi chúng ta gõ câu lệnh sai. Chẳng hạn như tên đối tượng (Object) hay tên thuộc tính (Property).

Lỗi biên dịch là lỗi phát sinh trong quá trình biên dịch mã câu lệnh. Ở đây chủ yếu kiểm tra tính logic. Ví dụ như chúng ta thiết định cưỡng chế một tham số, nhưng tham số này không được chương trình hiểu là gì.

Lỗi không thể thực thi, là lỗi khi chúng ta bắt đầu thực thi macro thì xảy ra lỗi. Nó cũng tương tự như lỗi biên dịch, thường là sai logic. Ví dụ như chúng ta chỉ có 3 sheet, nhưng chúng ta lại thao tác với 4 sheet. Như vậy sheet không tồn tại sẽ phát sinh ra lỗi thực thi.

Đối với lỗi khi thực thi, thì thường có số hiệu lỗi. Khi chúng ta sử dụng đối tượng Err, khi chạy macro mà nảy sinh ra lỗi thì có thể phán đoán được đó là lỗi gì. Nếu chúng ta sử dụng On Error, chúng ta có thể giả định lỗi xảy ra ở đâu để đặt bẫy lỗi.

Khi nào thì xảy ra quá trình biên dịch code trong VBA?

Khi chúng ta tạo code trong VBE (trình soạn thảo code trong VBA), đầu tiên chúng ta gõ một dòng lệnh, ở cuối dòng chúng ta ấn Enter.
Bạn cần đăng nhập để thấy đính kèm

Tiếp theo VBA sẽ kiểm tra câu lệnh có sai hay không, nếu không có vấn đề gì thì nó sẽ tiến hành biên dịch. Ta gọi đoạn code trong dòng này là P code.
Bạn cần đăng nhập để thấy đính kèm

Tiếp theo chúng ta ấn F5 để cho macro này chạy. Đoạn code được biên dịch (P Code) sẽ tiến hành thực thi ngay lập tức.
Bạn cần đăng nhập để thấy đính kèm

Như thế, VBA sẽ tiến hành biên dịch hai giai đoạn. Ở cuối dòng lệnh, khi bạn gõ Enter, nó sẽ tiến hành biên dịch xem có lỗi hay không.
Lưu ý rằng, quá trình này chỉ kiểm tra được một dòng lệnh. Chẳng hạn như bạn dùng lênh If hay For Next, thường những lệnh này không viết trên một dòng, nếu sai, ví dụ như quên đóng lệnh If, thì quá trình này không phát hiện được lỗi.
Như vậy dù macro chưa được thực thi, bằng debug trong VBE hoặc biên dịch VBA project, thì cũng có thể biên dịch và phát hiện được lỗi. Khi biên dịch, nếu trong code có lỗi sai về logic, thì lỗi biên dịch sẽ phát sinh.

Đối với lỗi xảy ra trong quá trình thực thi Macro
Hãy xem đoạn code sau:
Mã:
Sub Sample1()
    Dim i As Long
    For i = 1 To 4
        Cells(i, 1) = Worksheets(i).Name
    Next i
End Sub
Lỗi sẽ xảy ra vì file của chúng ta không có 4 sheet.
Bạn cần đăng nhập để thấy đính kèm


Nhằm mục đích, dù cho có lỗi xảy ra thì chương trình vẫn chạy, trong trường hợp này chúng ta phải phán đoán được lỗi có thể xảy ra để đi tới quyết định này, khi đó chúng ta dùng On Error , và chúng ta có hai cách để sử dụng:
  • On Error Goto Label : Lỗi xảy ra thì chạy tới Label. Xem thêm
  • On Error Resume Next : Lỗi xảy ra thì vẫn cứ chạy tiếp.
Chúng ta đã từng đề cập tới vấn đề này, tôi đưa ra code ví dụ như sau:
Mã:
Sub Sample2()
    Dim i As Long
    On Error GoTo ErrorRoutine
    For i = 1 To 4
        Cells(i, 1) = Worksheets(i).Name
    Next i
    Exit Sub
ErrorRoutine:
    MsgBox "Da phat sinh loi"
End Sub
Như vậy, khi lỗi xảy ra nó sẽ chạy tới nhãn ErrorRoutine, tức là một thông báo sẽ được đưa ra "Da phat sinh loi".
Còn với code sau, thì nó phớt lờ hoàn toàn lỗi, cứ thế chạy cho tới hết chương trình.
Mã:
Sub Sample3()
    Dim i As Long
    On Error Resume Next
    For i = 1 To 4
        Cells(i, 1) = Worksheets(i).Name
    Next i
End Sub
Như thế này thì nó hoàn toàn phớt lờ lỗi, đúng là tiện thật, nhưng chúng ta thì lại cứ ngỡ là chương trình chẳng có lỗi gì. Vì thế, chúng ta sẽ sử dụng đối tượng Err để xem có lỗi hay không. Đối tượng Err thì có rất nhiều thuộc tính, nhưng chúng ta chỉ quan tâm tới thuộc tính Number. Nếu như thuộc tính này khác 0, thì tức là đã có lỗi gì đó xảy ra.
Mã:
Sub Sample4()
    Dim i As Long
    On Error Resume Next
    For i = 1 To 4
        Cells(i, 1) = Worksheets(i).Name
    Next i
    If Err.Number <> 0 Then
        MsgBox "Da co loi xay ra"
    End If
End Sub
Đây chỉ là một bài viết rất cơ bản về lỗi. Diễn đàn sẽ còn dịch thêm các bài viết khác. Các bạn đón xem.
Nếu có chỗ cần đính chính, hãy vào mục và thông báo cho chúng tôi biết. Cảm ơn các bạn.
Nguồn:
 
Top