Consulting

Page 2 of 2 FirstFirst 1 2
Results 21 to 34 of 34

Thread: vbObjectError Not Working as Expected

  1. #21
    Quote Originally Posted by Paul_Hossler View Post
    Like I said, I usually just start my errors at 1000 and forget vbObjectError
    It seems there may be native errors in the region you're using, in which case you are overlapping native numbers. See
    https://exceldevelopmentplatform.blo...criptions.html

    'Private Const ERROR_CANTOPEN As Long = 1011 ' The configuration registry key could not be opened.
    'Private Const ERROR_SERVICE_REQUEST_TIMEOUT As Long = 1053 ' The service did not respond to the start or control request in a timely fashion.'Private Const ERROR_INVALID_PIXEL_FORMAT As Long = 2000 ' The pixel format is invalid.
    'Private Const ERROR_BAD_DRIVER As Long = 2001 ' The specified driver is invalid.
    'Private Const ERROR_INVALID_WINDOW_STYLE As Long = 2002 ' The window style or class attribute is invalid for this operation.
    Update: I guess these are Windows errors, not Excel errors. So this might not affect VBA programming.

    Iac, the solution i offered above allows to use native numbers without conflict.


    Quote Originally Posted by Paul_Hossler View Post
    I've never gotten an all-purpose error handler that I liked
    Does this mean your example is a handler that you do, or don't like?

    I suggest that severity is a different kind of information than type, and shouldn't share the same enum as you have:
    Public Enum errCustomNumbers
        errUserCanceled = 1011
        errClickedPause = 1053
        errBad = 2000
        errVeryBad = 2001
        errReallyBad = 2002
    End Enum
    Last edited by johnywhy; 12-06-2021 at 01:55 PM.

  2. #22
    VBAX Sage
    Joined
    Apr 2007
    Posts
    8,098
    Location
    Does this mean your example is a handler that you do, or don't like?

    I suggest that severity is a different kind of information than type, and shouldn't share the same enum as you have:


    1. I meant that I've never been able to get something like your sub GlobalHander to be the way I wanted. If it does work for you, that's great. I just usually have the error handling inside the sub and not call another sub since IMO that decreases response flexibility

    2. I hadn't thought about a 'severity score' based on the error number (1000-1999 = mild, 2000-2999 = medium, 3000-3999 = sever) but that's not a bad idea
    ---------------------------------------------------------------------------------------------------------------------

    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

  3. #23

    Post

    Quote Originally Posted by Paul_Hossler View Post
    I hadn't thought about a 'severity score' based on the error number (1000-1999 = mild, 2000-2999 = medium, 3000-3999 = sever) but that's not a bad idea
    Heh, not what i had in mind. I wouldn't combine two distinct pieces of information, if it can be avoided. Severity may be contextual. A corrupt workbook might be fatal for some apps, but ok to ignore and skip for other apps. I would have done:

    Enum CustomErr
              UserCancel = vbObjectError
              UserPause
              ProtectedWorkbook
              CorruptWorkbook
              ShellError
    End Enum
    
    
    Enum ErrorSeverity
              Mild
              Medium
              Severe
    End Enum

    And then put Severity in Err.Description. Or maybe it could be And'ed or Or'd with error-number, and together put into Err.Number?

  4. #24
    My solution does work, but i still have to add vbObjectError to my custom errors!

    For some reason, my prior example of 11 and 53 worked ok, but passing 0 as error number fails. The raised error is lost, and a new Automation Error occurs:

    Err.Raise 0, "Custom"
    So, VB won't allow me to overlap native numbers (or certain ones, i guess), even if i specify source. Starting my numbering at vbObjectError works.

    Enum CustomError
              UserCancel = vbObjectError
              UserPause
              ProtectedWorkbook
              CorruptWorkbook
              ShellError
    End Enum
    Since vbObjectError = -2147221504 , that means my numbering will start at -2147221504 and go up from there. No, i'm wrong, it's not a negative number, it's unsigned, i'm told. Somehow, -2147221504 = 513???

    Using "Custom" as error-source to disambiguate the custom error number from native numbers maybe not even needed. Or rather, may be used to differentiate between different types of custom errors, but my custom numbers still can't overlap the native ones.

    It seems it would have been better if VB allowed every app to define it's own error numbers (even overlapping ones) with a .Source disambiguator, but what do i know.
    Last edited by johnywhy; 12-07-2021 at 10:38 AM.

  5. #25
    VBAX Sage
    Joined
    Apr 2007
    Posts
    8,098
    Location
    Debug show vbObjectErrror is a Long

    ?vartype(vbObjectError) 3

    Long (long integer) variables are stored as signed 32-bit (4-byte) numbers ranging in value from -2,147,483,648 to 2,147,483,647.
    \


    BUt, .... if you're not in a class module then you probably want to forget about vbObjectError

    Required. Long integer that identifies the nature of the error. Visual Basic errors (both Visual Basic-defined and user-defined errors) are in the range 0–65535. The range 0–512 is reserved for system errors; the range 513–65535 is available for user-defined errors.

    When setting the Number property to your own error code in a class module, you add your error code number to the vbObjectErrorconstant. For example, to generate the error number 513, assign vbObjectError + 513 to the Number property.


    You could bit map if you didn't have too many errors


    Option Explicit
    
    
    Enum CustomErr
            UserCancel = 1
            UserPause = 2
            ProtectedWorkbook = 4
            CorruptWorkbook = 8
            ShellError = 16
    End Enum
    
    
    
    
    Enum ErrorSeverity
            Mild = 2 ^ 13
            Medium = 2 ^ 14
            Severe = 2 ^ 15
    End Enum
    
    
    
    
    Sub test()
        Dim sErr As String, sLvl As String
        On Error GoTo ErrHandle
    
    
    '    Err.Raise UserCancel + Mild
    '    Err.Raise UserCancel + Medium
    '    Err.Raise UserCancel + Severe
    
    
        Err.Raise ShellError + Medium
    
    
        
        Exit Sub
    
    
    
    
    ErrHandle:
        If (Err.Number And UserCancel) <> 0 Then
            sErr = "User Cancel"
        ElseIf (Err.Number And UserPause) <> 0 Then
            sErr = "User Pause"
        ElseIf (Err.Number And ProtectedWorkbook) <> 0 Then
            sErr = "Protected Workbook"
        ElseIf (Err.Number And CorruptWorkbook) <> 0 Then
            sErr = "Corrupt Workbook"
        ElseIf (Err.Number And ShellError) <> 0 Then
            sErr = "Shell Error"
        End If
    
    
    
    
        If (Err.Number And Mild) <> 0 Then
            sLvl = "Mild"
        ElseIf (Err.Number And Medium) <> 0 Then
            sLvl = "Medium"
        ElseIf (Err.Number And Severe) <> 0 Then
            sLvl = "Severe"
         End If
    
    
        
        MsgBox "Error was " & sErr & " with severity of " & sLvl
    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

  6. #26
    Quote Originally Posted by Paul_Hossler View Post
    Debug show vbObjectErrror is a Long
    So, not unsigned?

    "The values are not signed Longs, so none of this is about "negative" anything. These values are unsigned and 32 bits long (DWORD)."
    https://www.vbforums.com/showthread....=1#post5538131
    BUt, .... if you're not in a class module then you probably want to forget about vbObjectError
    Question: Is there any drawback to using vbObjectError in a module?

    News flash: My "Custom" source method actually does work. As long as there's no harm in re-using native error numbers, i CAN disambiguate with .Source. Just have to start the Enum at 1, not 0. Which means, my custom errors seem to work fine without using vbObjectError. Am i missing anything?

    So now i have to choose:
    - i can re-use native error numbers, and disambiguate by setting .Source to "Custom"
    - or, avoid native numbers by starting my enum at vbObjectError

    You could bit map...

    ...
            Medium = 2 ^ 14
            Severe = 2 ^ 15
    ...
            CorruptWorkbook = 8
            ShellError = 16
    ...
        On Error Goto ErrHandle    ' DID YOU FORGET THIS?
    ...
        If (Err.Number And UserCancel) <> 0 Then
            sErr = "User Cancel"
    ...
        If (Err.Number And Mild) <> 0 Then
            sLvl = "Mild"
    ...
    wOW, niCE woRK!
    Stealing

    ... if you didn't have too many errors
    How many?

  7. #27

  8. #28
    VBAX Sage
    Joined
    Apr 2007
    Posts
    8,098
    Location
    I'm going by the MS documentation:


    Long (long integer) variables are stored as signed 32-bit (4-byte) numbers ranging in value from -2,147,483,648 to 2,147,483,647.



    Long
    integer that identifies the nature of the error. Visual Basic errors (both Visual Basic-defined and user-defined errors) are in the range 0–65535. The range 0–512 is reserved for system errors; the range 513–65535 is available for user-defined errors.

    When setting the Number property to your own error code in a class module, you add your error code number to the vbObjectErrorconstant.



    How many?
    65535 = 2^16-1

    I used the 3 high order bits to mark severity, so that leaves 12 or 13 error messages



    On Error Goto ErrHandle ' DID YOU FORGET THIS?
    Second line
    ---------------------------------------------------------------------------------------------------------------------

    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

  9. #29
    Quote Originally Posted by Paul_Hossler View Post
    65535 = 2^16-1
    I used the 3 high order bits to mark severity, so that leaves 12 or 13 error messages
    I would say that's not a useful solution for this application, but still useful for other things.

  10. #30
    VBAX Sage
    Joined
    Apr 2007
    Posts
    8,098
    Location
    2. I hadn't thought about a 'severity score' based on the error number (1000-1999 = mild, 2000-2999 = medium, 3000-3999 = sever) but that's not a bad idea
    I'd think about this
    ---------------------------------------------------------------------------------------------------------------------

    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

  11. #31
    If I'm using vbObjectError as recommended, how to compose a conditional which can determine if my error is native or custom?


    Enum CustomEr
              LaidEgg = vbObjectError
              UserEaten
              Paused
              Cancelled
    End Enum
    
    
    Sub GlobalHandler
              If IsCustomErr Then MsgBox "Custom"
    End Sub
    
    
    Function IsCustomErr()As Boolean
    ONE OF THESE?
              With Err
                        IsCustomErr = .Number < 0
                        IsCustomErr = .Number >= vbObjectError
                        IsCustomErr = (.Number >= vbObjectError) And (.Number < 0)
                        IsCustomErr = .Number Or vbObjectError
                        IsCustomErr = TwosComplement(.Number) Or TwosComplement(vbObjectError)
              End With
    End Function
    (also asked here)

  12. #32
    VBAX Sage
    Joined
    Apr 2007
    Posts
    8,098
    Location
    If I'm using vbObjectError as recommended, how to compose a conditional which can determine if my error is native or custom?
    Well, TBH I don't think that you are using vbObjectError as recommended since the way I read the below, you only use vbObjectError in a class module and you don't seem to be using a class module

    When setting the Number property to your own error code in a class module, you add your error code number to the vbObject Error constant.

    Since 746 (attachment) seems to be the highest system error number used, I'd just keep my errors between 1000 and 9999. Anything below is Excel's, anything between is my custom


    Visual Basic errors (both Visual Basic-defined and user-defined errors) are in the range 0–65535.

    The range 0–512 is reserved for system errors;

    the range 513–65535 is available for user-defined errors.
    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

  13. #33
    Quote Originally Posted by Paul_Hossler View Post
    you don't seem to be using a class module
    Let's assume i am.

    My reading of the spec is that vbObjectError isn't required for modules, not that it's forbidden. Do you think i may overlap native numbers if i used vbObjectError for custom errors in modules?

    Since 746 (attachment) seems to be the highest system error number used, I'd just keep my errors between 1000 and 9999. Anything below is Excel's, anything between is my custom
    maybe, but i don't feel that's reliable. Also, i think the unsigned-int nature of error numbers may be relevant.

    Hoping to find an algorithm based on vbObjectError, rather than a hardcoded range.

    thx!
    Last edited by johnywhy; 12-09-2021 at 02:10 PM.

  14. #34
    VBAX Sage
    Joined
    Apr 2007
    Posts
    8,098
    Location
    Well, you can try this


    Option Explicit
    
    
    Enum CustomErr
        LaidEgg = vbObjectError + 100
        UserEaten = vbObjectError + 200
        Paused = vbObjectError + 300
        Cancelled = vbObjectError + 400
    End Enum
    
    
    
    
    Sub drv()
    
    
        On Error GoTo ErrHandler
        
        Err.Raise UserEaten, "Sub drv", "User Eaten Error"
        
        MsgBox 1 / 0
    
    
        Exit Sub
        
    ErrHandler:
        GlobalHandler
        Resume Next
    End Sub
    
    
    
    
    Sub GlobalHandler()
        Dim E As Long
        
        E = Err.Number - vbObjectError  '   needed to avoid Overflow Error
        
        If (Err.Number < 0) Then
            MsgBox "Custom Error, 'Number' = " & E
            MsgBox Err.Description
        Else
            MsgBox Err.Description
        End If
    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

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
  •