Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Excel VBA multiple error handling in the same procedure

I have previously used error handling in VBA successfully, but when trying to use several error handling blocks I can't figure out how to do it.

The code I've written looks like this:

...

  On Error GoTo ErrorHandler1
  shpArrow1.Left = shpLine.Left + shpLine.Width * Min(Sqr(Calculations.Range("cVolProduct").value / Calculations.Range("cVolRefIndices").value), 2) / 2 - shpArrow1.Width / 2
  shpTag1.Left = shpLine.Left + shpLine.Width * Min(Sqr(Calculations.Range("cVolProduct").value / Calculations.Range("cVolRefIndices").value), 2) / 2 - shpTag1.Width / 2
  shpArrow2.Left = shpLine.Left + shpLine.Width * Min(Sqr(Calculations.Range("cVolUnderlyings").value / Calculations.Range("cVolRefIndices").value), 2) / 2 - shpArrow2.Width / 2
  shpTag2.Left = shpLine.Left + shpLine.Width * Min(Sqr(Calculations.Range("cVolUnderlyings").value / Calculations.Range("cVolRefIndices").value), 2) / 2 - shpTag2.Width / 2
  shpIndexLine.Left = shpLine.Left + shpLine.Width / 2 - shpIndexLine.Width / 2
  GoTo NoError1
ErrorHandler1:
  shpArrow1.Left = shpLine.Left - shpArrow1.Width / 2
  shpTag1.Left = shpLine.Left - shpTag1.Width / 2
  shpArrow2.Left = shpLine.Left - shpArrow2.Width / 2
  shpTag2.Left = shpLine.Left - shpTag2.Width / 2
  shpIndexLine.Left = shpLine.Left + shpLine.Width / 2 - shpIndexLine.Width / 2
  errorRelativeRisk = 1
NoError1:
  On Error GoTo 0

  On Error GoTo ErrorHandler2
  Output.ChartObjects("ChartHistoryUnderlyings").Activate
  ActiveChart.Axes(xlValue).CrossesAt = ActiveChart.Axes(xlValue).MinimumScale
  ActiveChart.Axes(xlCategory).CrossesAt = ActiveChart.Axes(xlCategory).MinimumScale
  GoTo NoError2
ErrorHandler2:
  errorHistUnderl = 1
NoError2:
  On Error GoTo 0

...

The second error handling block does not work. I'm guessing that I don't quit the first error handling block correctly. Have tried to find an answer that works for me but without success.

Greatful for any help!

like image 226
David Avatar asked May 12 '26 17:05

David


2 Answers

Having two or more error-handling subroutines in a procedure is definitely a design smell; that's not how VBA error-handling works.

Basically you have this:

Sub Foo()
    On Error GoTo ErrHandler1
    '(code)

ErrHandler1:
    '(error handling code)

    On Error GoTo ErrHandler2
    '(code)

ErrHandler2:
    '(error handling code)

End Sub

When an error occurs in the first block, VBA jumps to ErrHandler1 and still thinks it's in an error-handling subroutine when it gets to the 2nd block.

You need to Resume somewhere, to tell VBA "I've handled everything I had to handle".

So instead of "falling-through" into the NoError1 subroutine, your ErrorHandler1 subroutine should end with a Resume jump:

Resume NoError1

And the ErrorHandler2 should also end with a Resume jump:

Resume NoError2

That way VBA knows it's out of "error handling mode" and back into "normal execution".

But I'd strongly recommend considering separate methods/procedures instead of labelled subroutines.

like image 188
Mathieu Guindon Avatar answered May 14 '26 07:05

Mathieu Guindon


The solution would be to apply On Error GoTo -1. It resets the error handling in VBA so that enables you to use multiple On Error GoTo statements.

>   Sub Asd()
    Range(Cells(7, 1), Cells(LastRow, 2)).Select
    On Error GoTo hello
    Selection.SpecialCells(xlCellTypeBlanks).Select
    Application.CutCopyMode = False
    Selection.FormulaR1C1 = "=R[-1]C"
hello: 
Cells(1, 1).Value = "Error 1"
On Error GoTo -1
 Range(Cells(7, 4), Cells(LastRow, LastColumn)).Select
On Error GoTo Hell
    Selection.SpecialCells(xlCellTypeBlanks).Select
    Application.CutCopyMode = False
    Selection.FormulaR1C1 = "0"
Hell: 
Cells(1, 1).Value = "Error 2"

End Sub
like image 38
Gabi Avatar answered May 14 '26 09:05

Gabi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!