I’ve created an excelfile with a couple of activeX-elements. So far the file is working as intended, now I’m working around “user errors” which might occur during daily business.
For later use the activeX-elements (Toggle-, Command- & SpinButtons) are quite important, so I’ve created some subs to restore each element. They are working as expected.
The issue: now what if someone deletes a button? I tried working with If-Statements (if >element< is nothing then…), but it didn’t work. The next approach was “On Error GoTo”.
So I’ve built an ErrorHandler and as a regular code it works as intended. The handler creates an SpinButton with the desired name. If I build an error into my code (a = 1/0) the handler is doing his job, but that’s just ‘in vitro’.
In vivo, if my desired >element< is not there, my code ends in an error (compiling error_ method or object not found), but my handler does nothing, despite this is its sole purpose.
Sub Cal_SpinButton_Nr() Subroutine: On Error GoTo CreateObject: With Tabelle5.SpinButton_Nr .Left = 198 .Height = 65.25 .Top = 1.5 .Width = 54.75 .Orientation = fmOrientationVertical .BackColor = &H8000000F .ForeColor = &H80000012 End With Exit Sub CreateObject: Tabelle5.OLEObjects.Add("Forms.SpinButton.1").Name = "SpinButton_Nr2" 'Resume Subroutine End Sub
Option Explicit is on and the sub contains no variables. As long as there is an object (SpinButton_Nr) it’s working. With no object I get a compiling error.
“Resume Subroutine” is silenced right now to avoid an endless loop (I learned my lesson by silencing “exit sub” first and pressing F5…), regular function is to fire the same sub again in order to put the new object in the right place.
For (‘in vitro’) testing reasons the new object is called _Nr2, later it’s just _Nr.
Now the question: Why is a compiling error not covered by the “on error”-statement? How can the code be modified in order to work properly?
Syntax should be “If >element< exists, set properties, if
<element> is not there then create it and set properties afterwards.
I suggest the following:
So you actually test if a spin button exists if not create it before you start formatting. No odd error handling and goto jumps in your procedure.
Option Explicit Sub Cal_SpinButton_Nr() Dim ws As Worksheet Set ws = ThisWorkbook.Worksheets("Tabelle5") '<-- tab name 'OR 'Set ws = Tabelle5 '<-- VBA code name Dim SpinBtn As Object On Error Resume Next 'next line errors if no spinbutton exists Set SpinBtn = ws.OLEObjects("SpinButton_Nr") On Error Goto 0 'always re-activate error reporting! 'if no spinbutton is found create it before formatting starts If SpinBtn Is Nothing Then Set SpinBtn = ws.OLEObjects.Add("Forms.SpinButton.1") SpinBtn.Name = "SpinButton_Nr" End If 'format spin button With SpinBtn .Left = 198 .Height = 65.25 .Top = 1.5 .Width = 54.75 'not that for these .Object is necessary because of using .OLEObjects("SpinButton_Nr") .Object.Orientation = fmOrientationVertical .Object.BackColor = &H8000000F .Object.ForeColor = &H80000012 End With End Sub
Compiling errors are errors, which occur in compiling time. They cannot be covered by
OnError statement. The errors, covered by
OnError are run-time errors, which appear after compiling and during run time.
“As long as there is an object (SpinButton_Nr) it’s working. With no object I get a compiling error.” – If you want to get run-time error and not compiling error, the binding of the object should be done during run-time.
Imagine the following scenario, with
Tabelle5 as a worksheet variable in Excel:
Sub CompileTimeError() With Tabelle5 Debug.Print .Cells(1, 1) End With End Sub
This would not compile, because VBE would not find the
Tabelle5 object. However, if you want a run-time error, this is a possible solution:
Sub RunTimeError() Dim nameOfWorksheet As String nameOfWorksheet = "Tabelle5" With Worksheets(nameOfWorksheet) Debug.Print .Cells(1, 1) End With End Sub