On Error GoTo bị lỗi

Liên hệ QC

cantl

!!! Giải thoát !!!
Tham gia
6/8/08
Bài viết
1,805
Được thích
1,153
Giới tính
Nam
Các bác ạ,
Em đố các bác tại sao code này sau khi tô màu đáp ứng đủ các điều kiện có cả 3 loại ô:
- chứa công thức.
- chứa hằng số.
- rỗng
vậy mà chạy xong vẫn nhảy vào đoạn LOI.
_)(#;_)(#;_)(#;
Mã:
Option Explicit
Sub CuocSongMuonMau()
    On Error GoTo LOI
    Dim rng As Range
    Set rng = Application.InputBox( _
              Title:="Range", _
              Prompt:="Select Range", _
              Default:=Selection.Address, _
              Type:=8)
    rng.SpecialCells(xlCellTypeVisible).Interior.ColorIndex = 0
    rng.SpecialCells(xlCellTypeBlanks).Interior.ColorIndex = 35
    rng.SpecialCells(xlCellTypeFormulas).Font.Color = vbRed
    MsgBox "To xong het roi"
LOI:
    MsgBox "Khong co o trong hoac o chua cong thuc"
    Exit Sub
End Sub

Sub CuocSongMauDen()
    Dim rng As Range
    Set rng = Application.InputBox( _
              Title:="Range", _
              Prompt:="Select Range", _
              Default:=Selection.Address, _
              Type:=8)
    rng.Interior.ColorIndex = 0
    rng.Font.ColorIndex = 0
End Sub
 

File đính kèm

  • 1687946883666.png
    1687946883666.png
    186.7 KB · Đọc: 6
  • CuocSongMuonMau.xlsm
    19.8 KB · Đọc: 3
Đố ngược lại là: theo bạn sau khi thực hiện lệnh MsgBox "To xong het roi" thì vba sẽ làm gì tiếp theo?
 
Upvote 0
Đố ngược lại là: theo bạn sau khi thực hiện lệnh MsgBox "To xong het roi" thì vba sẽ làm gì tiếp theo?
Chỗ nào gọi là "chạy xong", và "nhảy" là từ đâu?

Theo em hiểu là khi nào có lỗi nó mới chạy vào lỗi chứ, không lỗi thì nó chạy hết msgbox 1 thì là xong ấy. Mục đích báo lỗi em hiểu là thế. :wallbash: :wallbash: :wallbash:
 
Upvote 0
Code này thực hiện từ trên xuống dưới kể cả đoạn báo lỗi. Nếu không muốn báo lỗi ngoài mong muốn thì đặt "Exit Sub" trước đoạn
LOI: MsgBox "Khong co o trong hoac o chua cong thuc"
 
Upvote 0
Theo em hiểu là khi nào có lỗi nó mới chạy vào lỗi chứ, không lỗi thì nó chạy hết msgbox 1 thì là xong ấy. Mục đích báo lỗi em hiểu là thế. :wallbash: :wallbash: :wallbash:
Bạn không có căn bản về lập trình và ngữ pháp VBA cho nên "hiểu" sai rồi.

Theo ngữ pháp, chỗ nào có lệnh "rẽ nhánh" mới xảy ra chuyện "nhảy". Nếu không có lệnh rẽ nhánh thì VBA cứ tự nhiên đí tiếp xuống.
Các lệnh rẽ nhánh:
- Goto, Goto CaiGiDo. CaigiDo là một mốc (địa chỉ) để Goto biết chỗ mà "nhảy" vào. Sẽ giải thích mốc địa chỉ sau.
- On Error Goto NoiAy. Rẽ nhánh có điều kiện - cứ gặp Error thì tháy vì báo lỗi, nhảy tới NoiAy.
- IF-Then-Else, và Select-Case cũng là lệnh rẽ nhánh có điều kiện.
- For-Next là một vòng lặp gồm 2 lệnh rẽ nhánh. Lệnh For xét xem biến vòng lặp có thỏa điều kiện. Nếu thỏa thì chạy tiếp với câu lệnh ngay tiếp theo For; nếu không thì nhảy xuống câu lệnh sau Next. Lệnh Next bảo VBA không đi tiếp xuống câu dưới mà nhảy ngược trở về For. Lưu ý rằng chỉ có For là rẽ nhánh có điều kiện, Next là rẽ nhánh vô diều kiện - nó giản dị là nhảy về For của nó. Thực hiện câu lệnh sau Next là quyết điịnh của For.
- Do-Loop đại khái cũng gần như For-Next. Bạn tự suy luận các trường hợp.
- GoSub cũng rẽ nhánh tương tự như Goto. Chỉ khác là Goto là nhảy xong là tung tăng chạy. Gosub có mang theo một điều kiện là nếu gặp Return thì phải nhảy về cấu lệnh ngay sau Gosub. Vì vậy Return cũng là câu lệnh rẽ nhánh tương tự như Next, giiarn dị là nhảy về nơi đã ddowcj gia ước sẵn. (tôi có viết về tầm vực, phạm vi GoSub-Return và cách VBA ghi địa chỉ nơi trở về vào ngăn xếp một hai lần rồi, nếu cần biết thì tìm bài ấy)
- Exit là lệnh rẽ nhánh. VBA nhảy ra khỏi cái vùng lệnh xác định. Nếu là vòng lặp thì VBA nhảy qua câu lệnh ngay sau câu kết vòng lặp (Next, Loop, ...). Nếu là Sub/Function thì VBA thoát Sub/Function nhảy trở về nơi mà Sub/Function được gọi.
- Nhất thời tôi không nhớ mình có sót lệnh rẽ nhánh nào khác?

Giải thích về mốc/địa chỉ:
Thuở xưa, Mỗi đầu dòng Basic có một con số. Con số ấy chính là địa chỉ của dòng.
Về sau này, hầu hết các khiên bản Basic đều bỏ luật "số địa chỉ" này.
Tuy số đầu dòng cũng còn được các trình dịch coi như là cách đánh dấu địa chỉ dòng, nhưng ngày này, người ta dùng tên nhãn (label) để đánh dấu địa chỉ.
Cái LOI trong code của bạn chính là một cái nhãn. On Error Goto LOI là câu lệnh bẫy lỗi. Sau cấu lệnh này thì bất cứ gặp lỗi gì, VBA sẽ chiếu theo yêu cầu mà nhảy đến địa chỉ LOI. Nói cách khác, trên ngữ pháp, LOI không liên quan gì đến lỗi cả; nó chỉ là một địa chỉ, ai muốn nhảy đến cũng được.
Câu lệnh trước cái nhãn "LOI" không phải là lệnh rẽ nhánh cho nên sau khi chạy xong, VBA sẽ tỉnh bơ chạy tiêp các câu lệnh kế đó, tức là sẽ xâm nhập vào cái vùng mà bạn dự định chỉ có "lỗi" mới được vào.
 
Lần chỉnh sửa cuối:
Upvote 0
Rất buồn cười. Không biết thì hỏi sẽ được giải thích cặn kẽ, lại đi đố. Giả sử không ai trả lời thì có đáp án hay không, trời biết.
 
Upvote 0
Hehe, lâu lâu em dùng từ sang chảnh tí mà. Chứ cứ bảo không biết cũng ngại nhắm.
Em sử dụng kỹ thuật kết nối râu và cằm code nên thỉnh thoảng nó bị lạc đường. Em hay resume next cho tiện nhưng nguy hiểm nên phải cho goto, rồi để cho biết là xong thì cần msgbox báo, thế là mới té ra chạy kiểu gì nó cũng báo lỗi cả.

Mò kiểu này có ưu điểm nhớ lâu hơn.
Em thêm exit sub đúng là ngon hẳn.
Cảm ơn các bác nhé!
 
Upvote 0
Tình hình nó lại phát sinh lỗi các bác ạ.
Nếu range chọn mà thiếu ô xlCellTypeBlanks thì nó bỏ qua không chạy dòng tô màu ô xlCellTypeFormulas phía sau nữa. Do đó cái này em lại phải sửa thành On Error Resume Next. Quá củ chuối.

Có điều nếu range chọn mà chỉ có 1 ô thì code sẽ tự mở rộng ra usedrange rồi tô màu cả vùng rộng ấy, thế thì không đúng với mong muốn tô màu để phân biệt 3 loại dữ liệu trong vùng được quét chọn. Lại phải mò tiếp và rồi nó ra cái mã dài lê thê, và tạm thời được em chấp nhận như cách nghĩ của mình:
- tô màu 3 loại dữ liệu để phân biệt.
- nếu chọn thiếu 1 trong 3 ô thì vẫn tô bình thường.
- nếu lúc chọn range mà cancel thì thoát sub.
- nếu lỡ chọn 1 ô thì chuyển hướng xét cell chứ không xét range.
- MOD KIỂU MÒ NẢN QUÁ.

Chúc cả nhà ngủ ngon. :D :D :D

Mã:
Sub CuocSongMuonMau()
    On Error Resume Next 'GoTo LOI
    Dim rng As Range
    Set rng = Application.InputBox( _
              Title:="Range", _
              Prompt:="Select Range", _
              Default:=Selection.Address, _
              Type:=8)
    If rng.Address = "" Then Exit Sub
    If rng <> ActiveCell Then
        rng.SpecialCells(xlCellTypeVisible).Interior.ColorIndex = 0
        rng.SpecialCells(xlCellTypeBlanks).Interior.ColorIndex = 35
        rng.SpecialCells(xlCellTypeFormulas).Font.Color = vbRed
    Else
        Select Case True
        Case IsEmpty(ActiveCell)
            ActiveCell.Interior.ColorIndex = 35
        Case ActiveCell.HasFormula
            ActiveCell.Font.Color = vbRed
        Case Else
            ActiveCell.Interior.ColorIndex = 0
        End Select
    End If
    MsgBox "To xong het roi"
'    Exit Sub
'LOI:
'    MsgBox "Khong co o trong"
'    Exit Sub
End Sub
 
Upvote 0
Đặt câu hỏi thế thì bao giờ mới có câu trả lời.

Cái này gọi là cách bẫy lỗi khi chọn Range bằng Inputbox.
Có đầu mối từ khoá thần kỳ rồi, thế là ào ào tìm thấy vài tá bài nói về nó.
Rồi cuối cùng còn có cả kỹ thuật dùng Inputbox không xảy ra lỗi mà bẫy luôn. Diệu kỳ thế cơ mà.
 
Upvote 0
Đặt câu hỏi thế thì bao giờ mới có câu trả lời.

Cái này gọi là cách bẫy lỗi khi chọn Range bằng Inputbox.
Có đầu mối từ khoá thần kỳ rồi, thế là ào ào tìm thấy vài tá bài nói về nó.
Rồi cuối cùng còn có cả kỹ thuật dùng Inputbox không xảy ra lỗi mà bẫy luôn. Diệu kỳ thế cơ mà.

Khá là nhiều bài đấy bác, nhưng mà giờ lại thêm vài từ mới, lại phải tra từ điển tiếp rồi.

 
Upvote 0
Thử nghiệm đầu tiên mà mình gởi tới bạn nè:
Nếu khi chạy macro dưới đây & khi xuất hiện hộp thoại thì bạn xóa bén những gì có trong hộp thoại đi & {ENTER}
Lúc í chương trình sẽ cự nự ra sao?

PHP:
Sub ThuNghiem01()
 Dim Rng As Range:               On Error GoTo LOI
 
 Set Rng = Application.InputBox(Title:="Range", _
    Prompt:="Select Range", Default:=Selection.Address, Type:=8)
 If Rng Is Nothing Then
    MsgBox "Nothing!", , "1"
 Else
 
 End If
Err_:
    MsgBox "Xin Chào Nha!", , "GPE.COM"
    Exit Sub
LOI:
    MsgBox Error(), , "Mã Lôi: " & Err
    MsgBox "Không Có Ô Trông", , "3"
    GoTo Err_
End Sub
 
Upvote 0
Nó như thế này bác ạ. Ý đồ chiến thuật của bác là sao ạ? Em thì muốn nó như thế này với code ngắn gọn nhất có thể:
- tô màu 3 loại dữ liệu để phân biệt.
- nếu chọn thiếu 1 trong 3 loại ô thì vẫn tô bình thường những ô thỏa điều kiện xlCellType...
- nếu lúc chọn range mà cancel thì thoát sub chứ không báo lỗi.

Hiện tại code em viết đã theo như suy nghĩ của mình nhưng trong văn họ gọi là lặp từ, dài dòng và rối rắm. :wallbash: :wallbash: :wallbash:
 

File đính kèm

  • 1688005425605.png
    1688005425605.png
    168.4 KB · Đọc: 7
Upvote 0
Ý đồ của mình là: Nếu không có vùng dữ liệu thì chương trình sẽ như thế nào(?!)
→ Mã lỗi gì
→ Nghiêm trọng lắm không?
→ . . . . .
Bạn có thấy rằng chương trình nó phản ứng không như bạn mong muốn & . . . .
 
Upvote 0
Ý đồ của mình là: Nếu không có vùng dữ liệu thì chương trình sẽ như thế nào(?!)
→ Mã lỗi gì
→ Nghiêm trọng lắm không?
→ . . . . .
Bạn có thấy rằng chương trình nó phản ứng không như bạn mong muốn & . . . .
Em chưa hiểu ý bác lắm.
- Nếu không có vùng dữ liệu thì mong muốn là thoát khỏi sub, nhưng em default là selection nên luôn luôn có vùng dữ liệu range hoặc 1 cell. Lỗi chỉ khi nhấn Cancel, em đã sửa lại nhưng dài dòng.
- Hiện không có vùng dữ liệu thì thông báo của bác như ảnh trên và không có mã lỗi, mã lỗi 424 chỉ xuất hiện khi nhấn Cancel.
Cái mong muốn của em là lọc qua vùng dữ liệu (range hoặc 1 cell) và tô màu cho dễ nhìn (ô công thức, ô hằng số, ô rỗng).

Hiện em viết lại như trên thì nó chạy được, chỉ có điều em thấy nó rườm rà, lặp từ nhiều quá, em muốn có code gọn hơn ấy bác.
 
Upvote 0
. . . Em thì muốn nó như thế này với code ngắn gọn nhất có thể:
- . . .
- . . . .
- Nếu lúc chọn range mà 'Cancel' thì thoát sub chứ không báo lỗi.
Thì vầy xem sao:
PHP:
Sub CuocSongMuonMau()
 Dim Rng As Range
 On Error GoTo LOI
   
 Set Rng = Application.InputBox(Title:="Range", _
    Prompt:="Select Range", Default:=Selection.Address, Type:=8)
' . . . . '
 
Err_:
    Exit Sub
LOI:
 Select Case Err
 Case 424
    MsgBox Error(), , Err   ' Có Thể sửa lại theo ý bạn'
 Case Else
    MsgBox "GPE.COM", , Err
 End Select
 Resume Err_
End Sub
 
Upvote 0
& đây là tất cả những gì bạn có thể trãi nghiệm:

PHP:
Sub CuocSongMuonMau()
 Dim Rng As Range:                  Dim Msg_ As String
 On Error GoTo LOI
    
 Set Rng = Application.InputBox(Title:="Range", _
    Prompt:="Select Range", Default:=Selection.Address, Type:=8)
 
4 Rng.SpecialCells(xlCellTypeVisible).Interior.ColorIndex = 0
5 Rng.SpecialCells(xlCellTypeBlanks).Interior.ColorIndex = 35
6 Rng.SpecialCells(xlCellTypeFormulas).Font.Color = vbRed
 MsgBox "Tô Xong Hêt Rôi!"
Err_:
    Exit Sub
LOI:
 Select Case Err
 Case 424
    MsgBox Error(), , Err
 Case 1004
    If Erl = 5 Then
        Msg_ = " Trông."
    ElseIf Erl = 6 Then
        Msg_ = " Công Thúc."
    End If
    MsgBox "Không Có Ô " & Msg_, , Erl
    Resume Next
 Case Else
    MsgBox Err, , Erl
 End Select
 Resume Err_
End Sub
 
Upvote 0
& đây là tất cả những gì bạn có thể trãi nghiệm:

PHP:
Sub CuocSongMuonMau()
 Dim Rng As Range:                  Dim Msg_ As String
 On Error GoTo LOI
  
 Set Rng = Application.InputBox(Title:="Range", _
    Prompt:="Select Range", Default:=Selection.Address, Type:=8)
 
4 Rng.SpecialCells(xlCellTypeVisible).Interior.ColorIndex = 0
5 Rng.SpecialCells(xlCellTypeBlanks).Interior.ColorIndex = 35
6 Rng.SpecialCells(xlCellTypeFormulas).Font.Color = vbRed
 MsgBox "Tô Xong Hêt Rôi!"
Err_:
    Exit Sub
LOI:
 Select Case Err
 Case 424
    MsgBox Error(), , Err
 Case 1004
    If Erl = 5 Then
        Msg_ = " Trông."
    ElseIf Erl = 6 Then
        Msg_ = " Công Thúc."
    End If
    MsgBox "Không Có Ô " & Msg_, , Erl
    Resume Next
 Case Else
    MsgBox Err, , Erl
 End Select
 Resume Err_
End Sub
Vẫn còn 1 tí tẹo lỗi bác ạ. Đó là nếu em chỉ chọn 1 cell (F18) thì rng nó biến thành usedrange nên tô loang ra bên ngoài luôn ấy.
Bác code thêm cho em mót tí, trên em mót được cái err là lạ nó báo cụ thể lỗi luôn dễ tìm nguyên nhân gây lỗi.
 

File đính kèm

  • 1688032178985.png
    1688032178985.png
    199.1 KB · Đọc: 2
Upvote 0
Chuyện đó là của bạn & bạn cần nghiên cứu tiếp trong 24 giờ tới đây để có kết quả
Mình chỉ giúp bạn về chuyện bẩy lỗi sao cho đặng mà thôi.
 
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom