I am trying to add error handling for one of the code. I am assigning worksheet with specific name to the sheet objects, now I am trying to add OnError statements if in case user changes the names of sheets then code should gracefully exit the sub after displaying a message to correct the file names.
But the problem is as I provide the structure as below then the sub exit code always executes even if the file name is ok.
The problem is, as I provide the details in the structure as below then the sub exit code always executes even if the file name is ok.
Private Sub DoSomething()
On Error GoTo CleanFail
'...code...
CleanExit:
'cleanup code here
Exit Sub
CleanFail:
If Err.Number = 9 Then 'subscript out of range
Err.Clear
Resume Next
Else
MsgBox Err.Description
Resume CleanExit
End If
End Sub
On Error GoTo ErrorFailLoad
Set LoadSheet = Application.ActiveWorkbook.Worksheets("Load_Template")
ErrorExit:
End Sub
ErrorFailLoad:
MsgBox "Main File name must be Load_Template. Please change and re-run Macro"
Resume ErrorExit
On Error GoTo ErrorFailEquip
Set EquipSheet = Application.ActiveWorkbook.Worksheets("EQUIP")
ErrorExit:
End Sub
ErrorFailEquip:
MsgBox "Equipment File name must be EQUIP. Please change and re-run Macro"
Resume ErrorExit
I expect the code to just check if the file name is not available then just show error message and exit. Actual results is code exit even after correct file name.
Related
I put together a VBA procedure that does the following:
opens a bunch of excel files (separately not at once) from a specific folder (user indicates the folder)
excel files are password protected so it inputs the password , opens the file , then unprotects a specific sheet (as sheets are also pass protected) and does some changes to the file.
My problem is that for the changes to be applied to each excel file the sheet has to be unprotected and there is unfortunately 3 different options for pass (dont ask me why). I know the pass options so i put it in my code as per below:
However the procedure still stops if the first pass option is incorrect and I have to manually drag the execution line to the next valid pass for the procedure to continue.
Essentially my questions are: is the code set up above ok and is there a way of making VBA to attempt another password to unprotect sheet if the first pass is not the correct one (and a third attempt if the 2nd pass is also incorrect)?
Uff, hope the above makes sense and thanks for reading
This should help. I haven't used any of your code as it's a picture that I can't copy/paste, but this should give you the idea.
Note:
Option Explicit should appear at the top of every module - forces you to declare variables.
the Public Const line must be at the top of a module before any procedures/functions.
Option Explicit
Public Const ERROR_SHEETPROTECTED As Long = vbObjectError + 513
Sub Test()
'Any errors should be handled by the error handler appearing after the Exit Sub.
On Error GoTo ERROR_HANDLER
Dim wrksht As Worksheet
With ThisWorkbook
Set wrksht = .Worksheets("Sheet1")
'Use each password and exit loop when correct one is found.
Dim PWDS As Variant
PWDS = Array("123", "456", "ABCD")
Dim PWD As Variant
For Each PWD In PWDS
On Error Resume Next 'Ignore any errors and move to next line.
wrksht.Unprotect PWD
On Error GoTo ERROR_HANDLER 'Reinstate correct error handling as soon as possible.
If Not wrksht.ProtectContents Then Exit For 'We found a match!
Next PWD
'Final check that at least one of the passwords worked.
If wrksht.ProtectContents Then
Err.Raise ERROR_SHEETPROTECTED, , "Password for sheet not found"
End If
End With
Exit Sub
'Error handling appears after the main body of code (Exit Sub) and before the end of the procedure (End Sub)
ERROR_HANDLER:
Select Case Err.Number
Case ERROR_SHEETPROTECTED
MsgBox Err.Number & vbCr & Err.Description, vbOKOnly + vbCritical
'Other code to sort the problem out.
Resume Next 'If problem is solved use this to jump back into the main code.
Case Else
MsgBox Err.Number & vbCr & Err.Description, vbOKOnly + vbCritical
End Select
End Sub
Raise method
With...End With Statement
On Error GoTo -1
There are a couple of misunderstandings in your code, because even if it succeeds first time it will run into the next error handler.
But the main error is a common misunderstanding in error handling when trying to handle multiple errors in a sequenz, missing the On Error GoTo -1 :
Option Explicit
Sub BadErrorHandlingSequenz()
Dim x As Integer
On Error GoTo Errhandler1
x = 3 / 0
Exit Sub
Errhandler1:
On Error GoTo errhandler2
x = 5 / 0 ' Error is not handled
Exit Sub
errhandler2:
MsgBox "Still Error"
End Sub
Sub GoodErrorHandlingSequenz()
Dim x As Integer
On Error GoTo Errhandler1
x = 3 / 0
Exit Sub
Errhandler1:
On Error GoTo -1 ' Reset Error handling
On Error GoTo errhandler2
x = 5 / 0 ' Error is handled
Exit Sub
errhandler2:
MsgBox "Still Error"
End Sub
I use a workbook that copy information from others workbooks, using the following Code:
Sub importarbens()
On Error GoTo ErrorHandler
{...}
ErrorHandler:
Workbooks(nomearq2).Close
MsgBox "Arquivo Incompatível"
Exit Sub
End Sub
But apparently my code always get in the ErrorHandler, even when the code runs withouth erros and after the task is done. The message in message box appears
When I disable the errorhandler the code works well
You need to add Exit Sub:
Sub importarbens()
On Error GoTo ErrorHandler
{...}
Exit Sub '<< end of the "happy path" for your code....
ErrorHandler:
Workbooks(nomearq2).Close
MsgBox "Arquivo Incompatível"
Exit Sub '<< Don't really need this since you're already
' at the end of the sub
End Sub
I know my title is a bit confusing, but this is the problem I have. I basically have one sheet that functions as a wrapper of sorts. It has the ability to run a multitude of macros sequentially, which is done through a Userform. Basically, you check the box, if it's checked, it runs the macro. What I'm trying to do is, if there is an error, I want it to return either what sub it was in.
My first idea was in my if statement for the checkboxes that run the subs to put an On Error statement, but that didn't work, since the error handling goes to the sub that is called and ignores what is before it.
What should I do? Is this possible?
You could do something like this:
Sub ErrorHandler()
On Error GoTo ErrHandler
Call Proc1
Call Proc2
Call Proc3
Exit Sub
ErrHandler:
MsgBox Err.Source & vbCrLf & Err.Description
End Sub
Sub Proc1()
On Error GoTo ErrHandler
' Your code block start
' Your code block end
Exit Sub
ErrHandler:
Err.Raise 513, "Proc1", "Customer Error Message 1|" & Err.Description
End Sub
Sub Proc2()
On Error GoTo ErrHandler
' Your code block start
' Your code block end
Exit Sub
ErrHandler:
Err.Raise 513, "Proc2", "Customer Error Message 2|" & Err.Description
End Sub
Sub Proc3()
On Error GoTo ErrHandler
' Your code block start
' Your code block end
Exit Sub
ErrHandler:
Err.Raise 513, "Proc3", "Customer Error Message 3|" & Err.Description
End Sub
I am using the simple code below to handle the error. When there is no error in why does the msgbox appears? How can I make the msgbox appear only when there is an error?
Sub Test()
On Error GoTo ErrHandler
On Error GoTo 0
'rest of the code is here
ErrHandler:
MsgBox "Please make sure the file exists in the current folder."
Exit Sub
End Sub
You should add an exit before the actual error handler and restore the default error handling after having shown the dialog. (The 1st on error goto 0 is probably misplaced).
Sub Test()
On Error GoTo ErrHandler
'rest of the code is here
'Exit before error handlers
Exit Sub
ErrHandler:
MsgBox "Please make sure the file exists in the current folder."
' Reset error handler
On Error GoTo 0
Exit Sub
End Sub
This question already has answers here:
Why VBA goes to error handling code when there is no error?
(5 answers)
Closed last year.
I need to catch some VBA errors using the GoTo statement:
Sub mySub
On Error GoTo errorHandler:
Workbooks.Open("myWorkbook")
'
' Some Code
'
errorHandler:
MsgBox "ERROR"
End Sub
The problem is that when there is no error the errorHandler section is executed.
I found this discussion but the answer doesn't solve my issue.
I tried adding an Exit Sub statement as explained :
Sub mySub
On Error GoTo errorHandler:
Workbooks.Open("myWorkbook")
Exit Sub
'
' Some Code
'
errorHandler:
MsgBox "ERROR"
End Sub
In this case it exits the method when there is no error.
I also tried :
Sub mySub
On Error GoTo errorHandler:
Workbooks.Open("myWorkbook")
'
' Some Code
'
errorHandler:
MsgBox "ERROR"
Exit Sub
End Sub
But still the same issue: The errorHandler is executed even when no errors occur.
Just put Exit sub in.
Sub mySub
On Error GoTo myHandler:
Workbooks.Open("myWorkbook")
'
' Some Code
'
Exit sub
myHandler:
MsgBox "EROOR !"
err.clear
End Sub
Here's the pattern I prefer:
Sub SomeSub()
On Error GoTo ErrorLabel
'Code goes here
ExitLabel:
'Clean-up code, if any, goes here
Exit Sub
ErrorLabel:
'Error-handling code goes here
Resume ExitLabel
End Sub
Note that Resume clears the error. I like this pattern for a few reasons:
Habitually inserting the exit block before the error-handling block reduces the chance that I'll have the OP's problem of accidentally dropping into the error handler.
I use GoTo ExitLabel for any early exit from the Sub or Function. This way, I'm less likely to skip the clean-up code by accident. Example:
Sub SomeOtherSub()
Dim x As ResourceThatNeedsToBeClosed
Dim i As Long
On Error GoTo ErrorLabel
Set x = GetX
For i = 1 To 100
If x.SomeFunction(i) Then
GoTo ExitLabel
End If
Next
ExitLabel:
x.Close
ErrorLabel:
'Error-handling code goes here
Resume ExitLabel
End Sub
Public Sub MySub
On Error Goto Skip
' Some Codes
Skip:
If err.Number > 0 Then
' Run whatever codes if error occurs
err.Clear
End If
On Error Goto 0
End Su
I am having the exact same issue as you, and the solutions above did not work. They clearly didn't even see you wrote Exit Sub in already in 2 different places in your original post. No site online seems to understand that sometimes there won't be an error (if there was always going to be an error, why did you code it that way?), and when there isn't an error, you obviously don't want to Exit Sub. Nor do you want the myHandler to run when there isn't an error. DUH! This is the solution I cam up with which seems to work.
On Error GoTo ErrorHandler
'This is the thing I am trying to do...
Workbooks("SpreadSolver.xlsb").Activate
'If it works, great.
'Don't touch the error stuff and move on.
'I.e. go to the part that I know works (the rest of the macro)
GoTo ThisPartWorks
'If the thing I am trying to do doesn't work...
ErrorHandler:
MsgBox "Error: Please open Spread Solver and then run the macro."
'Only want to Exit Sub if there is an error.. duh.
Exit Sub
ThisPartWorks:
'the rest of your macro can go here...
'...
End Sub
I use an If statement, within the ErrorHandler, which will stop execution if there is no error. This is achieved by using the Err.Number (Err (object) number (e.g. Run-time error 9: Subscript out of range))
If Err.Number >= 1 Then
MsgBox ("Message")
End
Else: other code
End If
Exit Sub
This is what I have done. Works like a charm
Sub someProgram ()
On Error goto Handler:
x = 7/0
'Some code you wanna execute with or without error
Exit Sub
Handler:
'Write your handler here
Resume next 'After handling error, this line will help you resume the next line
End sub
Use below code in error handler section:
if err.number>0 the
' error handling goes here
else
' some code
end if
sub XYZ ()
on error goto label
"Write your macro"
Label:
If Err.Description <> "" Then
"your code if error occurs for eg:"
msgbox "Error Occured!"
Exit Sub
Else
"Your code when no error occurs for eg"
msgbox " Done."
End If
Exit Sub