It seems that the message box that VBA pops-up when an unhandled exception occurs behaves differently depending on... something? To see what I mean, create a new .xlsm, then create a standard module Module1; paste inside this code then paste inside Sheet1 Worksheet object this code:
Public Sub TestErrMsgBox()
Debug.Print "Hello!"
Call Err.Raise(Number:=vbObjectError, Source:="VBAProject.Sheet1", Description:="Lorem Ipsum")
End Sub
On my Excel 2010 Professional Plus, calling the subroutine in the VBE's "Immediate" (Ctrl+G) window:
Call Module1.TestErrMsgBox
Call Sheet1.TestErrMsgBox
will show the error message Automation Error / Invalid OLEVERB structure.
Now, if one calls directly the Raise method from in the "Immediate" window:
Call Err.Raise(Number:=vbObjectError, Source:="VBAProject.Sheet1", Description:="Lorem Ipsum")
it will show the (expected) error message Lorem Ipsum.
What exactly changes in the error handling, or in the Err object, from the first case to the last? and how it may be manipulated? I figured out that in the first case the message depends only on the Number argument in Raise call, but still it doesn't explain...
I find this a bit annoying, because I expected my messages displayed, not something else. There's always available the Pokemon approach (catching all the exceptions and showing custom MessageBoxes based on Err properties), but I'd like to understand what happens. :-)
Later edit:
The behavior described above happens when "Error Trapping" is set on "Break on Unhandled Errors." Once I put "Break on All Errors" it displays the correct message, with the "Debug" button available; however, this is not a good idea, to break execution on every error...
Also, thanks to the feedback from Alex K., roryap and Doug Glancy I figured out that this happens when the TestErrMsgBox subroutine is called from within a Worksheet object, not from a standard Module as I incorrectly reported the first time. The posting is fixed; however, the question is still there. :-)
The reason it happens when your Sub is in a Sheet module and you've set the VBE to Break on Unhandled Errors, has to do with the fact that a Sheet module is a class module. Set Error Trapping to Break in Class Modules, and it will behave correctly.
I always use this setting anyways, so I can debug inside UserForms and classes.
Searching "VBA err.raise invalid oleverb structure break in class module" seems to support the fact that it's related to class modules.
Declare sub as friend in class module instead of public
Related
Using Office365 under Windows 10.
I am trying to invoke the Save dialog programmatically and then save the open document.
Minimal testcase:
Private Sub TestSave()
If Application.FileDialog(msoFileDialogSaveAs).Show Then
Application.FileDialog(msoFileDialogSaveAs).Execute
End If
End Sub
(For the real code, I am programmatically setting the default filename and filter, but these aren't needed to show the problem.)
However, on the call to .Execute, I get an error popup:
Run-time error '-2147467259 (80004005)'
Command failed
What does this mean? How do I fix it? (The Help button in the error dialog doesn't lead to any page that explains the error.)
This seems to be happening regardless of what folder I try to save to.
I read the following:
Compile error Method or data member not found
However, I am not allowed to download anything on the work computer. Hence I'm trying to overwrite the compile error by having a Userform appear with dropdown dates for people to use when they do not have on their computer the Calendar Date picker option available.
Is there any way that I can overwrite a compile error? I have tried the following code:
Private Sub UserForm_Initialize()
On Error GoTo EnterDateManually
If IsDate(ActiveCell.Value) Then
Me.MonthView1.Value = ActiveCell.Value
End If
EnterDateManually:
Enter_Date.Show
End Sub
But it still gives me the compile error. The compile error highlights MonthView1 since on this computer I removed the missing References library since I don't have it on this computer and I'm sure other user won't have it either on their computer.
I know when you get an error with number you can overwrite it (though you should try to fix it first :-) but it seems that overwriting the Compile error is not possible? Or is it...
Thanks for you help
Me.MonthView1 doesn't exist at compile-time, thus MonthView1 isn't a member of Me - hence, Method or data member not found.
On Error statements are executable: by the time they get to run, the code has long been compiled already - you can't use that statement to handle a compile error.
A compile error means your code can't compile: there's an illegal or malformed statement somewhere, Option Explicit is specified and a variable isn't declared, ...or a referenced type library is missing.
By removing a <MISSING> type library, you're telling VBA "this project doesn't really need this library anyway" - and all would be fine if there wasn't anything in the project that did need that library.
In most cases you can late-bind a type library, and blow up at run-time instead of compile-time when that library is missing - and then yes, you can handle that with On Error statements.
However you can't late-bind a MSForms control that needs to show up on a UserForm at design-time, because VBA needs to load that control at design-time, to render the form designer.
The only way you can have a MSForms control that shows up when its library can be loaded, and doesn't when the library isn't there (I've never tried this), is by loading that library at run-time, and conditionally generating the control at run-time. Now one problem with late-binding, is that you can't bind event handlers at compile-time, and VBA doesn't let you bind event handlers at run-time, so your dynamic control can't have event handlers. But I think you'd still be able to inspect its state, so if you really want to do it, it might be feasible.
I have an Access database where I have code on the On Load event of the main form to set focus to a textbox and load a 'new' record. The code is:
Private Sub Form_Load()
'Makes it so that when frmDiversion_Review loads, it defaults to a new record
DoCmd.GoToRecord , , acNewRec
Me!FromDate.SetFocus
End Sub
FromDate is an unbound date field used in a search/filter section on the header of the form.
I've split the database, and have an .accde file ready to go, but I've noticed that when I close Access when in the .accde file it gives me the following error:
"The expression On Load you entered as the event property setting produced the following error:
****NameOfDatabase**** can't move the focus to the control FromDate."
It does not give an error number.
The code is compiled, and I only get this error using the .accde file. I'm at a loss why the On Load event is even firing when I close Access. Any ideas?
A few weird scenarios may produce this (such as something relating to other forms being closed when you close out...) having references to this form that cause it to open. Hard to say from here.
But there is an easy out... just add this line at the start of the routine
On Error Resume Next
This is safe provided you know there are no real errors in the routine ever, excepting this annoying one that doesn't actually mean anything. If real errors can occur, you will no longer see them if you add this easy-out.
Personally, I'd prefer to find the cause and address it, not least because it seems other forms are trying to open this form while you're busy closing the app, which is an unsettling thought. But... when all else fails, it's a solution.
I have a weird situation where a user is experiencing a run time error (which is expected and handled) except in this one case. From all the documentation that I've read for VBA error handling, if a sub procedure creates an error, the error is percolated up through the call stack until a procedure is found that has error handling and it is processed at that level. If no handler is found, then the run time error dialogue window is displayed. So...
Sub ProcedureA()
Try:
On Error Goto Catch
' No error handler in ProcedureB
ProcedureB
Catch:
If Err.Number <> 0 then
' Manages error from ProcedureB
End If
End Sub
This works for all users except one who had recently installed Excel 2016 (although there are other users with 2016 and no problems). In his case, the run time error dialogue window appears with the "scene of the crime" highlight pointing to a statement in ProcedureB (which has no error handler). My question then is if there is some setting in Excel or in its VBA options which would override the default VBA error handling behavior?
This isnt an issue with his Excel version. It is instead a setting within the VBE. From what I know, this isnt turned on by default, so either your user turned this setting on, or for one reason or another the default setting changed.
To fix this setting:
Open the VBE
Go to the Tools Menu (Alt-T)
Select Options (Alt-O)
Under the General Tab > Error Trapping you will want to select either 'Break in Class Module' (this allows you to see errors within class modules, if they occur. I highly recommend this setting.) or 'Break On Unhandled Errors' (nearly the same behavior, but it breaks within the calling routine and wont allow you to see the error as it happens within the class.)
Then you should be all set. What was happening was the VBE settings were overriding the error handling behavior which can be beneficial for debugging, but is not so beneficial when someone is actually running your app.
We have to handle very old code, written in VB5 that should run without user interfering.
Most of the subs and functions handles it's error using "on error goto...resume" statement, but some of it doesn't. We must avoid modal messages in any case.
Is there any way to create global error handling or avoid the message box of "runtime error..." and simply close process on unhandled error? (I can re-run it if needed when stopped, but can't click the "enter" or mouse).
Tnx, Guy.
If you just want to abort the procedure when an error is raised you can use a style like this
Begin Sub Blah()
On Error goto errplace
'procedure code here
Exit Sub
errplace:
End sub
You can use MZ tools add on to add error handling code to any sub/function in VB6 with a single click on its toolbar (not sure about vb5 though)