Consulting

Page 1 of 2 1 2 LastLast
Results 1 to 20 of 34

Thread: vbObjectError Not Working as Expected

  1. #1

    vbObjectError Not Working as Expected

    This page:
    https://bettersolutions.com/vba/erro...ing-errors.htm

    says:
    "If you are generating errors, then you should add your number to the vbObjectError constant. Eg Err.Raise Number = vbObjectError + 1000
    The range 513 - 65535 is available for user defined errors"
    Ok, but i did, and got a native error:

    Err.Raise vbObjectError+515
    Automation error
    A syntax error occurred trying to evaluate a query string
    This site
    https://exceldevelopmentplatform.blo...criptions.html

    says the error code for that error-message is
    EVENT_E_QUERYSYNTAX As Long = &H80040203
    The VBA immediate pane confirms this:
    ?&H80040203
    -2147220989
    If i'm supposed to add vbObjectError, and if 513-65535 is usable, then why does `Err.Raise vbObjectError+515` give me a native error!?

    bettersolutions.com also says:
    "The range 513 - 65535 is available for user defined errors"
    Ok, let's say they mean my custom codes should start at 513, and forget about vbObjectError.

    But their Codes page shows native errors of 520, 521, some 700's, and some 31000's.
    https://bettersolutions.com/vba/erro...rror-codes.htm

    also O'Reilly says:
    "we are left with numbers in the range vbObjectError + 512 to vbObjectError + 65535"
    https://www.oreilly.com/library/view...0/ch09s04.html

    So i'm totally confused.

    Thx!

    also asked here
    https://www.excelforum.com/excel-pro...ml#post5574397
    Last edited by johnywhy; 09-28-2021 at 07:55 PM.

  2. #2
    Microsoft documentation seems to give yet different advice:


    "User-defined error numbers should be greater than vbObjectError."
    https://docs.microsoft.com/en-us/dot....vbobjecterror
    So, i can start at vbObjectError + 1?

  3. #3
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,724
    Location
    Did you have any error handling specified (like in examples below)?


    Post #2 at

    https://www.vbforums.com/showthread....what-is-it-for

    has good writeup. Old but still valid as far as I know

    It seems the intent by MS was to not let things get confusing

    Because Microsoft has reserved the error numbers from 1 to 2147221504 for their use and the reason why you add 2147221504=vbObjectError to what ever error number you want to raise is because things don't get confusing. Lets say you have X number of error traps within your code and you have numbered them from 1 to X without the addition of the vbObjectError constant. Then you die for some reason or are no longer working at the place you designed this code and your customer recieves error number 11 with your description but when your customer looks this error number up on MS's web site it will come back as a division by zero error.

    Option Explicit
    
    
    'https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/number-property-visual-basic-for-applications
    
    
    Sub ForceError()
        Dim x As Long, y As Long
        Dim o As clsDivide
        
        Set o = New clsDivide
        
        x = Application.InputBox("Enter X as numerator")
        y = Application.InputBox("Enter Y as denominator")
        
        On Error GoTo ErrHandler
        
        MsgBox o.DivideXY(x, y)
        
        On Error GoTo 0
    
    
    
    
        Exit Sub
    
    
    ErrHandler:
    
        ' My error
        If (Err.Number - vbObjectError) = 515 Then
            MsgBox (Err.Number - vbObjectError) & " -- " & Err.Description, vbCritical, Err.Source
         
        'another error  
        Else
            MsgBox Err.Number & " -- " & Err.Description, vbCritical, Err.Source
        End If
    
    
    
    End Sub
    
    
    Sub ForceError1()
        Dim x As Long, y As Long
        
        x = Application.InputBox("Enter X as numerator")
        y = Application.InputBox("Enter Y as denominator")
        
        On Error GoTo ErrHandler
        
        If y = 0 Then Err.Raise 515, "Force Error 1", "Can't divide by zero"
        
        On Error GoTo 0
    
    
    
    
        Exit Sub
    
    
    ErrHandler:
        
        MsgBox (Err.Number) & " -- " & Err.Description, vbCritical, Err.Source
    
    
    End Sub


    Class clsDivideXY

    Option Explicit
    
    
    Private x As Long, y As Long
    
    
    Function DivideXY(x As Long, y As Long) As Long
    
    
        If y = 0 Then Err.Raise vbObjectError + 515, "DivideXY", "Can't divide by zero"
    
    
        DivideXY = x / y
    
    
    End Function
    My thoughts, and you can experiment with the attachment, but I don't think it really makes a lot of difference
    Attached Files Attached Files
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  4. #4
    "I don't think it really makes a lot of difference"
    WHAT doesn't make a lot of difference? It doesn't matter what err numbers i use for custom errors? And it's ok if i use native err numbers for custom errors, as you're doing in your code above?

    Why would i want to do that? Why wouldn't i want to avoid the native range, so my code knows whether it's a native or custom error? If i'm logging errors and i use native numbers for custom errors, that will create confusion for future devs looking at the thing and for me too. If i'm displaying an error message to the user, and i get a native error description instead of my custom description, that would be incorrect.

    "Microsoft has reserved the error numbers from 1 to 2147221504 for their use"
    "The range 513 - 65535 is available for user defined errors"
    Those two statements seem contradictory.


    "the reason why you add 2147221504=vbObjectError to what ever error number you want to raise is because things don't get confusing. "
    You say vbObjectError = 2147221504. VBA says vbObjectError = -2147221504


    "you should OR your own error messages with vbObjectError when generated within a class module."
    Three points of confusion: Do i add, or OR? Do i use vbObjectError ONLY when generated within a class module? What about regular modules?


    dilettante wrote:
    Basically &H80040000 through &H80040200 are reserved, don't use them. There are also case where the reserved range includes &H80040201 through &H800403FF, so &H80040400 really seems to be the base value to use for your own exceptions. I think there are even other reserved ranges in different scenarios, so I always begin at a base of &H80044700 myself.

    Ok, so dilettante agrees that Microsoft isn't clear about WHICH ranges are reserved. Unclear whether to use decimal or hex, whether the values are negative or unsigned, and whether to use OR or +. dilettante's recommendations seem to contradict the Microsoft documentation.


    For a moment, let's mentally truncate the "-21472" prefix on all numbers, so we can more easily read and compare the numbers. dilettante's "top" of range as int (&H80040200 = -----20992) is smaller than his "bottom" of range (&H80040000 = -----21504), suggesting we are talking about negative numbers. The number he recommends, &H80044700, is even lower than that, -----03328. -----03328 is seventeen-thousand numbers away from the closest known native error. Why such a vast safety-margin? And what then is the available range? -----03328 to what? to 0?


    I'm no less confused.

    Quote Originally Posted by Paul_Hossler View Post
    Did you have any error handling specified (like in examples below)?
    "Specified"? you mean example code? Same as my first post above.

    Sub TestErr()
        Err.Raise vbObjectError + 515
        ' at this point, Error = "A syntax error occurred trying to evaluate a query string", which is a native error. 
    End Sub
    Last edited by johnywhy; 09-29-2021 at 01:18 PM.

  5. #5
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,724
    Location
    "Specified"? you mean example code? Same as my first post above.

    You RAISE the error but do you HANDLE the error?

    Capture.JPG
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  6. #6
    sorry, here it is:

    Sub TestEntry()
        On Error Goto HANDLER
        TestErr
    
    HANDLER:
        MsgBox Error
    End Sub
    
    
    Sub TestErr()
        Err.Raise vbObjectError + 515
    End Sub

  7. #7
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,724
    Location
    Chip has a good overview

    http://www.cpearson.com/Excel/ErrorHandling.htm


    https://bettersolutions.com/vba/error-handling/raising-errors.htm


    has examples showing application vs automation error codes

    Like you said
    Long, identifying the type of the error. Visual Basic errors range from 0 to 65535
    The range 0 - 512 is reserved for system errors
    The range 513 - 65535 is available for user defined errors

    You add vbObjectError (probably a bad name) to your error so that they don't get tangled up

    According to

    https://docs.microsoft.com/en-us/off...r-applications

    The first example illustrates a typical use of the Number property in an error-handling routine. The second example examines the Number property of the Err object to determine whether an error returned by an Automation object was defined by the object, or whether it was mapped to an error defined by Visual Basic.Note that the constant vbObjectError is a very large negative number that an object adds to its own error code to indicate that the error is defined by the server. Therefore, subtracting it from Err.Number strips it out of the result.
    If the error is object-defined, the base number is left in MyError, which is displayed in a message box along with the original source of the error. If Err.Number represents a Visual Basic error, the Visual Basic error number is displayed in the message box.

    Here's an example that I hope will explain what I mean

    There's 2 Error 11's, one by the macro and one by the system (probably as very bad idea to overlap like that)

    There's also what I would consider a more realistic example returning error number = 1000

    Option Explicit
    
    
    Sub TestEntry()
        Dim MyErr As Long
            
        On Error GoTo HANDLER
        
        TestErr     '   Raises my error 11
        
        TestZero    '   Raises system error 11
        
        TestErr2    '   My normal way to raise error condition
    
    
        Exit Sub
    
    
    
    
    HANDLER:
        ' First, strip off the constant added by the object to indicate one of its own errors.
        MyErr = Err.Number - vbObjectError
    
    
        'If you subtract the vbObjectError constant, and the number is still
        ' in the range 0-65,535, it is an object-defined error code.
        If MyErr > 0 And MyErr < 65535 Then
            Select Case MyErr
                Case 11
                    MsgBox "You should leave system error numbers alone"
                Case 1000
                    MsgBox MyErr & " -- " & Err.Source & " -- " & Err.Description
                Case Else
                    MsgBox "Something happened"
            End Select
    
        ' Otherwise it is a Visual Basic error number.
        Else
            MsgBox Err.Number & " -- " & Err.Source & " -- " & Err.Description
        End If
        
        Resume Next
    End Sub
    
    Sub TestErr()
        Err.Raise vbObjectError + 11, "TestErr", "This is My Error"
    End Sub
    
    Sub TestZero()
        Dim x As Long
        x = 1 / 0
    End Sub
    
    Sub TestErr2()
        Err.Raise vbObjectError + 1000, "TestErr2", "You did SOMETHING wrong, so go back and fix it!!!"
    End Sub
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  8. #8
    I don't see anything on Chip's page about error number.


    On further consideration and correspondence with Russell from bettersolutions.com (same as your link), i believe the range for custom errors is -2147221504 to -1.


    Adding vbObjectError to my custom number will push my custom number down to around -2 billion.
    If my custom numbering starts counting from there, and if VB reserves 0 to 513, then the top of the custom range must be -1.


    If all that is true, then the following just confuses me again:

    "The range 513 - 65535 is available for user defined errors"
    Plus, as mentioned, bettersolutions Codes page shows native errors of 520, 521, some 700's, and some 31000's.


    Also, if i'm correct, then this isn't exactly correct (from bettersolutions):
    "For any user defined errors, these should be greater than vbObjectError"
    In fact, custom numbers should be less than 0.


    Another wrench in the works: If i'm supposed to add vbObjectError, and if 513-65535 is usable, then why does `Err.Raise vbObjectError+515` give me a native error!?
    Last edited by johnywhy; 09-30-2021 at 01:30 AM.

  9. #9
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,724
    Location
    Chip's page was just a general overview about handling errors

    IMHO VBA's error handling leaves something to be desired

    FWIW, in my test, TestErr() and TestZero() both use error = 11 (not recommended) since my error and VBA's error have the same number (i.e. 11).
    Since I have vbObjectError + 11 in TestErr() they can still be told apart by the error handler, but I think it'd be confusing to have 11 used for 2 different errors

    Sub TestErr()
        Err.Raise vbObjectError + 11, "TestErr", "This is My Error"
    End Sub
    
    Sub TestZero()
        Dim x As Long
        x = 1 / 0
    End Sub
    
    Sub TestErr2()
        Err.Raise vbObjectError + 1000, "TestErr2", "You did SOMETHING wrong, so go back and fix it!!!"
    End Sub
    Plus, as mentioned, bettersolutions Codes page shows native errors of 520, 521, some 700's, and some 31000's.
    Yes. No idea why. Maybe MS is inconsistent???

    520 Can't empty Clipboard
    521 Can't open Clipboard
    735 Can't save file to TEMP directory
    744 Search text not found
    746 Replacements too long
    31001 Out of memory
    31004 No object
    31018 Class is not set
    31027 Unable to activate object
    31032 Unable to create embedded object
    31036 Error saving to file
    31037 Error loading from file

    If i'm supposed to add vbObjectError, and if 513-65535 is usable, then why does `Err.Raise vbObjectError+515` give me a native error!?
    vbObjectError+515 = -2147220989

    and

    -2147220989 - vbObjectError = 515

    -2147220989 is a 'native' error based on the MS does things but the " - vbObjectError" gives you back the original 515 so you know it's in the user error range


    The error handling code from the MS doc can be used to determine if it was a user generated application error or a system automation error

    Like I said, the error handling process leaves a lot to be desired (another IMHO)
    However, I normally use error handling to catch the error (either VBA's or one of mine), determine what it is, and take corrective action. The actual description or type isn't that important TO ME.

    Select Case errornumber statements to branch to the appropriate correction / error message / etc. after i find out if it's an application error or an automation error (normally it's mine)

    HANDLER:
        ' First, strip off the constant added by the object to indicate one of its own errors.
        MyErr = Err.Number - vbObjectError
    
    
        'If you subtract the vbObjectError constant, and the number is still
        ' in the range 0-65,535, it is an object-defined error code.
        If MyErr > 0 And MyErr < 65535 Then
            Select Case MyErr
                Case 11
                    MsgBox "You should leave system error numbers alone"
                Case 1000
                    MsgBox MyErr & " -- " & Err.Source & " -- " & Err.Description
                Case Else
                    MsgBox "Something happened"
            End Select
    
        ' Otherwise it is a Visual Basic error number.
        Else
            MsgBox Err.Number & " -- " & Err.Source & " -- " & Err.Description
        End If
             Resume Next
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  10. #10
    will take me some time to digest your reply. Meantime, i did this:
    This proc lists every unique error in any number range you set.
    Sub ListErrs()
              Dim lRow As Long, lCol As Long, lErr As Long, sError As String
              lCol = 4
              Application.ScreenUpdating = False
              
              For lErr = -2000000 To 1000000
                        Application.StatusBar = lErr
                        On Error Resume Next
                        Err.Raise lErr
                        If (Error <> sError) Then
                                  lRow = lRow + 1
                                  If lRow > 1048576 Then
                                            lRow = 1
                                            lCol = lCol + 1
                                  End If
                                  sError = Error
                                  Cells(lRow, lCol) = lErr & " : " & sError
                                  Windows(1).ScrollRow = lRow
                        End If
                        On Error GoTo 0
                        DoEvents
              Next lErr
    
    
              Application.ScreenUpdating = True
    End Sub
    I ran it for EVERY number from -2 million to +1 million, and for many (not all) numbers between -2 billion (vbObjectErr) and -2 million. I didn't run for all numbers between -2 billion (vbObjectErr) and -2 million, because that would take about a week (maybe someone out there can make it faster).

    Here's what i found. These results seem to disagree with the info on bettersolutions. As you can see, i didn't get all the errors you listed in your last reply.

    -2147221504 Automation error
    -2147221230 ActiveX component can't create object
    -2147221229 Automation error
    -2147221164 ActiveX component can't create object
    -2147221163 Automation error
    -2147221021 ActiveX component can't create object
    -2147221020 Automation error
    -2147221018 File name or class name not found during Automation operation
    -2147221017 Automation error
    -2147221014 File name or class name not found during Automation operation
    -2147221013 Automation error
    -2147221006 Automation error
    -2147221005 ActiveX component can't create object
    -2147221004 Automation error
    -2147221003 ActiveX component can't create object
    -2147221002 Automation error
    -2147220994 ActiveX component can't create object
    -2147220993 Automation error
    -2000000 Automation error
    0 Invalid procedure call or argument
    1 Application-defined or object-defined error
    3 Return without GoSub
    4 Application-defined or object-defined error
    5 Invalid procedure call or argument
    6 Overflow
    7 Out of memory
    8 Application-defined or object-defined error
    9 Subscript out of range
    10 This array is fixed or temporarily locked
    11 Division by zero
    12 Application-defined or object-defined error
    13 Type mismatch
    14 Out of string space
    15 Application-defined or object-defined error
    16 Expression too complex
    17 Can't perform requested operation
    18 User interrupt occurred
    19 Application-defined or object-defined error
    20 Resume without error
    21 Application-defined or object-defined error
    28 Out of stack space
    29 Application-defined or object-defined error
    35 Sub or Function not defined
    36 Application-defined or object-defined error
    47 Too many DLL application clients
    48 Error in loading DLL
    49 Bad DLL calling convention
    50 Application-defined or object-defined error
    51 Internal error
    52 Bad file name or number
    53 File not found
    54 Bad file mode
    55 File already open
    56 Application-defined or object-defined error
    57 Device I/O error
    58 File already exists
    59 Bad record length
    60 Application-defined or object-defined error
    61 Disk full
    62 Input past end of file
    63 Bad record number
    64 Application-defined or object-defined error
    67 Too many files
    68 Device unavailable
    69 Application-defined or object-defined error
    70 Permission denied
    71 Disk not ready
    72 Application-defined or object-defined error
    74 Can't rename with different drive
    75 Path/File access error
    76 Path not found
    77 Application-defined or object-defined error
    91 Object variable or With block variable not set
    92 For loop not initialized
    93 Invalid pattern string
    94 Invalid use of Null
    95 Application-defined or object-defined error
    96 Unable to sink events of object because the object is already firing events to the maximum number of event receivers that it supports
    97 Can not call friend function on object which is not an instance of defining class
    98 A property or method call cannot include a reference to a private object, either as an argument or as a return value
    99 Application-defined or object-defined error
    321 Invalid file format
    322 Can't create necessary temporary file
    323 Application-defined or object-defined error
    325 Invalid format in resource file
    326 Application-defined or object-defined error
    380 Invalid property value
    381 Invalid property array index
    382 Set not supported at runtime
    383 Set not supported (read-only property)
    384 Application-defined or object-defined error
    385 Need property array index
    386 Application-defined or object-defined error
    387 Set not permitted
    388 Application-defined or object-defined error
    393 Get not supported at runtime
    394 Get not supported (write-only property)
    395 Application-defined or object-defined error
    422 Property not found
    423 Property or method not found
    424 Object required
    425 Application-defined or object-defined error
    429 ActiveX component can't create object
    430 Class does not support Automation or does not support expected interface
    431 Application-defined or object-defined error
    432 File name or class name not found during Automation operation
    433 Application-defined or object-defined error
    438 Object doesn't support this property or method
    439 Application-defined or object-defined error
    440 Automation error
    441 Application-defined or object-defined error
    442 Connection to type library or object library for remote process has been lost. Press OK for dialog to remove reference.
    443 Automation object does not have a default value
    444 Application-defined or object-defined error
    445 Object doesn't support this action
    446 Object doesn't support named arguments
    447 Object doesn't support current locale setting
    448 Named argument not found
    449 Argument not optional
    450 Wrong number of arguments or invalid property assignment
    451 Property let procedure not defined and property get procedure did not return an object
    452 Invalid ordinal
    453 Specified DLL function not found
    454 Code resource not found
    455 Code resource lock error
    456 Application-defined or object-defined error
    457 This key is already associated with an element of this collection
    458 Variable uses an Automation type not supported in Visual Basic
    459 Object or class does not support the set of events
    460 Invalid clipboard format
    461 Method or data member not found
    462 The remote server machine does not exist or is unavailable
    463 Class not registered on local machine
    464 Application-defined or object-defined error
    481 Invalid picture
    482 Printer error
    483 Application-defined or object-defined error
    735 Can't save file to TEMP
    736 Application-defined or object-defined error
    744 Search text not found
    745 Application-defined or object-defined error
    746 Replacements too long
    747 Application-defined or object-defined error
    65536 Invalid procedure call or argument

  11. #11
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,724
    Location
    I'm sure MS adds error codes whenever it feels like

    What are you trying to really do? Maybe someone can suggest a simple solution even if it doesn't follow MS's recommendations
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  12. #12
    Quote Originally Posted by Paul_Hossler View Post
    I'm sure MS adds error codes whenever it feels like
    no doubt, but no matter as long as we know which range is reserved for custom errors.

    What are you trying to really do?
    raise custom errors, with my own customer handlers, based on custom error number. Native errors will get different handling.

  13. #13
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,724
    Location
    FWIW, I usually do something like this, normally without worrying about Using vbObjectError, but I added it in my example


    Option Explicit
    
    
    Sub OneWay()
        Dim X As Long, Y As Long, Z As Double
        Dim errTemp As Long, errNum As Long
        Dim errMsg As String
        Dim A(1 To 10) As Long
        
        On Error GoTo ErrHandle
        
        X = 0
        Do While X < 5 Or X > 10
            X = InputBox("Enter X, between 5 and 10")
            If X < 5 Or X > 10 Then Err.Raise 1000, "Sub OneWay", "X must be between 5 and 10. Try again"
        Loop
    
    
        Y = 0
        Do While Y <> 0
            Y = InputBox("Enter Y")
            If Y = 0 Then Err.Raise 1001, "Sub OneWay", "Y cannot = 0. Try again"
        Loop
    
    
        
        A(1234) = 1234
    
    
        X = 10000
        Y = 0
    
    
        MsgBox X / Y
        
            
        Err.Raise vbObjectError + 515
    
    
        Exit Sub
        
    ErrHandle:
        With Err
            errTemp = Err.Number - vbObjectError
            
            'automation error
            If errTemp > 0 And errTemp < 65535 Then
            
                Call MsgBox("Automation Error Description: " & .Description & Chr(10) & Chr(10) & _
                    "Error Number: " & .Number & Chr(10) & Chr(10) & _
                    "Error Source: " & .Source, vbCritical, "Program OneWay")
            
            'application error
            Else
                Select Case .Number
                    
                    'my errors
                    Case 1000
                        Resume Next     '   the 'Loop' statement
                    Case 1001
                        Resume Next
                    Case 1003
                    
                    'built in errors
                    Case Else
                        Select Case .Number
                            Case 9  '   subscript out of range
                                Call MsgBox("Subscript out of range, continuing", vbInformation, "Program OneWay")
                                Resume Next     '   go to line after
                            
                            Case 11 '   divide by 0
                                Call MsgBox("Can't divide by 0, so I'll call Y = 10", vbInformation, "Program OneWay")
                                Y = 10
                                Resume  '   try the line again
                            
                            Case Else
                                Call MsgBox("Built in Error: " & .Description & Chr(10) & Chr(10) & _
                                    "Error Number: " & .Number & Chr(10) & Chr(10) & _
                                    "Error Source: " & .Source, vbCritical, "Program OneWay")
                        End Select
                End Select
            End If
        End With
    End Sub
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  14. #14
    Quote Originally Posted by Paul_Hossler View Post
    FWIW, I usually do something like this, normally without worrying about Using vbObjectError, but I added it in my example
    thx for example. Why did you use vbObjectError?

  15. #15
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,724
    Location
    I'm thinking about using it from now on to handle automation errors better, but I usually don't use it when I raise my own errors (1000, 1001, ...)

    Also, there's no reason to have two "Select Case .Number" in the error handler. I just did that to separate my errors from other runtime errors
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  16. #16
    [QUOTE=Paul_Hossler;411626]

            errTemp = Err.Number - vbObjectError
    If i understand your math, automation errors would fall between vbObjectError (-2147221504) and 65,535 + vbObjectError (-2147155969). Are they native? Why are automation error separate from both native and custom errors?

  17. #17
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,724
    Location
    [QUOTE=johnywhy;412428]
    Quote Originally Posted by Paul_Hossler View Post
    If i understand your math, automation errors would fall between vbObjectError (-2147221504) and 65,535 + vbObjectError (-2147155969). Are they native? Why are automation error separate from both native and custom errors?
    I just assume that the type of error generating source determines that Err.Number
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  18. #18
    [QUOTE=Paul_Hossler;412434]
    Quote Originally Posted by johnywhy View Post

    I just assume that the type of error generating source determines that Err.Number
    Why does your code separate automation errors from both native and custom errors?

  19. #19
    @Paul_Hossler, you gave me an idea.

    Here's a proposed solution, which i THINK might resolve this.

    This solution doesn't CARE if my custom error numbers overlap native error numbers. It enables me to have a custom error-numbering strategy without fear of conflicting with native errors (or errors generated by other workbooks or applications.)

    The solution exploits the .Source property of Err.

    Table on worksheet called "tblCustomErrors"
    ErrNum  ErrDescription
    11  User cancelled the process
    53  User clicked pause

    VBA:
    Sub Test_Handler()
              On Error GoTo HANDLER
              
              Debug.Print 1 / 0                   ' 11, Division-by-zero
              Kill "C:\Doesn't-Exist.txt"         ' 53, File not found
              Err.Raise 11, "Custom"              ' 11, User cancelled
              Err.Raise 53, "Custom"              ' 53, User paused
              
              Exit Sub
    HANDLER:
              GlobalHandler
              Resume Next
    End Sub
    
    
    Sub GlobalHandler()
              Dim sDesc As String
              
              Select Case Err.Source
                        Case "Custom"
                                  ' get description from worksheet
                                  sDesc = WorksheetFunction.VLookup(Err.Number, [tblCustomErrors], 2, False)
                        Case Else
                                  sDesc = Err.Description
              End Select
              
              MsgBox sDesc
    End Sub
    Who knows, this is might be how .Source was intended to be used.

  20. #20
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,724
    Location
    Like I said, I usually just start my errors at 1000 and forget vbObjectError


    I've never gotten an all-purpose error handler that I liked

    To me, that precluded the ability to

    1. automatically take corrective action (case 11 below)

    2. to customize the error message to provide needed / useful information (case 53 below)

    3. allow user choice (case errBad, errVeryBad below)


    Option Explicit
    
    
    Public Enum errCustomNumbers
        errUserCanceled = 1011
        errClickedPause = 1053
        errBad = 2000
        errVeryBad = 2001
        errReallyBad = 2002
    End Enum
    
    
    Const errDescUserCanceled As String = "User cancelled the process"
    Const errDescClickedPause As String = "User clicked Pause"
    Const errDescBad As String = "This is a bad error"
    Const errDescVeryBad As String = "This is a VERY bad error"
    Const errDescReallyBad As String = "This is a REALLY bad error"
    
    
    
    
    Const MyApp As String = "Test Errors"
    
    
    Sub Test_Handler()
        Dim N As Long, D As Long
        Dim F As String
    
    
        N = 1
        D = 0
        F = "C:\Doesn't-Exist.txt"
    
    
        On Error GoTo HANDLER
        MsgBox N / D                    ' 11, Division-by-zero
        
        Kill F                           ' 53, File not found
        
        Err.Raise errUserCanceled, MyApp, errDescUserCanceled
        Err.Raise errClickedPause, MyApp, errDescClickedPause
        
        Err.Raise errBad, MyApp, errDescBad
        Err.Raise errVeryBad, MyApp, errDescVeryBad
        Err.Raise errReallyBad, MyApp, errDescReallyBad
        
        Exit Sub
    
    
    HANDLER:
        With Err
            Select Case .Number
                Case 11
                    D = 1                       ' correct error and try again
                    Resume
                    
                Case 53
                    If MsgBox("File '" & F & "' not found" & vbCrLf & vbCrLf & "Stop Processing?", vbYesNo + vbQuestion, MyApp) = vbYes Then
                        Exit Sub
                    Else
                        Resume Next
                    End If
                    
                Case errUserCanceled, errClickedPause
                    Call MsgBox(.Description & " (#" & .Number & ")", vbOKOnly & vbInformation, MyApp)
                    Resume Next
            
                Case errBad, errVeryBad
                    If MsgBox(.Description & " (#" & .Number & ")" & vbCrLf & vbCrLf & "Stop Processing?", vbYesNo + vbQuestion, MyApp) = vbYes Then
                        Exit Sub
                        Call MsgBox(.Description & " (#" & .Number & ")", vbOKOnly & vbInformation, MyApp)
                    Else
                        Resume Next
                    End If
            
                Case errReallyBad
                    Call MsgBox(.Description & " (#" & .Number & ")", vbOKOnly & vbCritical, MyApp)
                    Exit Sub
                
                Case Else
                    Call MsgBox(.Description & " (#" & .Number & ")", vbOKOnly & vbInformation, MyApp)
                    Resume Next
            End Select
        End With
    End Sub


    Just my thoughts
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •