Permalink
Cannot retrieve contributors at this time
title | keywords | f1_keywords | ms.prod | ms.assetid | ms.date | ms.localizationpriority |
---|---|---|---|---|---|---|
Line isn’t an executable statement |
vblr6.chm1015670 |
vblr6.chm1015670 |
office |
f734f3d9-fd63-8024-860a-4b0c7f581f67 |
06/08/2017 |
medium |
Declarations and comments are not executable statements. This error has the following cause and solution:
- You chose the Step To Cursor command, but the cursor was not on a line containing an executable statement. Place the cursor on an executable statement near the current line.
For additional information, choose the Step To Cursor command on the Run menu and press F1 (in Windows) or HELP (on the Macintosh).
[!includeSupport and feedback]
Excel 2010 Developer Reference > Visual Basic for Applications Language Reference > Visual Basic Language Reference
Error Messages
Topics
#Else clause must be preceded by a matching #If
#Else If, #Else, or #End If must be preceded by a matching #If
#ElseIf must be preceded by a matching #If or #ElseIf and followed by an #ElseIf, #Else, or #End If
<Item> is not a valid control type (Error 720)
A compatible ActiveX component must be a Visual Basic executable or a DLL
A form can’t be moved or sized while minimized or maximized
A module is not a valid type
A procedure of that name already exists
A procedure with a ParamArray argument cannot be called with named arguments
A property or method call cannot include a reference to a private object, either as an argument or as a return value (Error 98)
ActiveX component can’t create object or return reference to this object (Error 429)
ActiveX Component did not run correctly (Error 338)
ActiveX component not correctly registered (Error 336)
ActiveX control ‘item’ not found (Error 363)
Add-in can’t reference project
Ambiguous name detected
AppleScript error
Application-defined or object-defined error
Argument not optional (Error 449)
Argument required for Property Let or Property Set
Array already dimensioned
Array argument must be ByRef
Assignment to constant not permitted
Automation error (Error 440)
Automation object doesn’t have a default value (Error 443)
Bad DLL calling convention (Error 49)
Bad file mode (Error 54)
Bad file name or number (Error 52)
Bad interface for Implements: interface contains data fields
Bad interface for Implements: interface is derived from another pure interface with non-restricted methods
Bad interface for Implements: interface is not derived from Iunknown
Bad interface for Implements: method does not return HRESULT
Bad interface for Implements: method has out-only or LCID parameter
Bad interface for Implements: method has parameter with too many levels of indirection
Bad interface for Implements: method has underscore in name
Bad interface for Implements: methods uses type that is not supported by Visual Basic
Bad record length (Error 59)
Bad record number (Error 63)
Beginning of search scope has been reached; do you want to continue from the end?
Block If without End If
Breakpoint not allowed on this line
ByRef argument type mismatch
Calling convention not supported by Visual Basic
Cannot define a KWID_tkPUBLIC user-defined type within a private object module
Cannot display specified name because it is hidden
Cannot handle events for the object specified
Cannot jump to specified type because it is in the specified library, which is not currently referenced
Can’t add a reference to the specified file
Can’t assign or coerce array of fixed-length string or user-defined type to Variant
Can’t assign to an array
Can’t call Friend procedure on an object that isn’t an instance of the defining class (Error 97)
Can’t change data types of array elements
Can’t create AutoRedraw image (Error 480)
Can’t create necessary temporary file (Error 322)
Can’t display hidden procedure
Can’t display system information
Can’t edit module
Can’t empty Clipboard (Error 520)
Can’t enter break mode at this time
Can’t execute code in break mode
Can’t execute immediate statements in design mode
Can’t exit design mode because control can’t be created
Can’t find DLL entry point in specified DLL
Can’t find project or library
Can’t find Windows Help .exe file
Can’t Get or Put user-defined type containing object reference
Can’t have paramarrays with optional arguments
Can’t load module; invalid format
Can’t load or unload this object (Error 361)
Can’t make an assignment to a read-only property
Can’t open Clipboard (Error 521)
Can’t perform operation because the project is protected
Can’t perform requested operation (Error 17)
Can’t perform requested operation since the module is hidden
Can’t place conditional breakpoint on an array
Can’t print form image to this type of printer (Error 486)
Can’t print minimized form image
Can’t quit at this time
Can’t record into running module
Can’t ReDim, Erase, or assign to Variant that contains array whose element is With object
Can’t remove control or reference; in use
Can’t remove default reference
Can’t rename with different drive (Error 74)
Can’t save file to TEMP directory (Error 735)
Can’t set the project name at this time
Can’t show non-modal form when modal form is displayed
Can’t sink this object’s events because it’s already firing events to the maximum number of supported event recipients (Error 96)
Can’t start new recording until current session is ended
Can’t use character device names in file names: ‘item’ (Error 320)
Case Else outside Select Case
Case without Select Case
Circular dependencies between modules
Class doesn’t support Automation (Error 430)
Class is not set (Error 31018)
Class not registered on local machine (Error 463)
Class not registered. ‘item 1’
Code execution has been interrupted
Code resource lock error (Error 455)
Code resource not found (Error 454)
Compile error in hidden module: <module name>
Component not correctly registered
Conflicting attributes were found in ‘item’. The defaults will be used
Conflicting names were found in ‘item1’. The name ‘item2’ will be used
Connection to type library or object library for remote process has been lost (Error 442)
Constant expression required
Constants, fixed-length strings, arrays, user-defined types, and Declare statements not allowed as Public members of an object module
Could not access system registry (Error 335)
Could not create reference: ‘item’
Could not execute specified program
Could not start Internet Explorer
Current module does not support Print method
Cyclic reference of projects not allowed
Data value named not found (Error 327)
Definitions of property procedures for the same property are inconsistent
Deftype statements must precede declarations
Destination label too far away; loop, Select Case, or block If too large
Device I/O error (Error 57)
Device unavailable (Error 68)
Disk full (Error 61)
Disk not ready (Error 71)
Display more load errors?
Division by zero (Error 11)
Do without Loop
Do you want to export specified object before removing it?
Duplicate declaration in current scope
Duplicate definition
Duplicate Deftype statement
Duplicate Option statement
Duplicate procedure name
Duplicate resources with same type and name
Edit can’t be undone—proceed anyway?
Else without If
Empty Enum type not allowed
Empty watch expression
End If without block If
End of search scope has been reached; do you want to continue from the beginning?
End Select without Select Case
End With without With
Enum types defined in standard modules or private classes cannot be used in public object modules as parameters or return types for public procedures, as public data members, or as fields of public user defined types
Error accessing the system registry
Error in loading DLL (Error 48)
Error loading from file (Error 31037)
Error loading ‘item’. A control could not be loaded due to load error. Continue?
Error loading ‘item’. An error was encountered loading a property. Continue?
Error saving to file (Error 31036)
Errors during load. Refer to ‘item’ for details
Errors occurred during load
Event handler is invalid
Event not found
Exit Do not within Do…Loop
Exit For not within For…Next
Exit Function not allowed in Sub or Property
Exit Property not allowed in Function or Sub
Exit Sub not allowed in Function or Property
Expected array
Expected End Function
Expected End Property
Expected End Sub
Expected End With
Expected Function or variable
Expected procedure, not module
Expected procedure, not project or library
Expected procedure, not user-defined type
Expected procedure, not variable
Expected Sub, Function, or Property
Expected user-defined type, not project
Expected variable or procedure, not Enum type
Expected variable or procedure, not module
Expected variable or procedure, not project
Expected: <various>
Expression too complex (Error 16)
External name not defined
Failed to activate control ‘item 1’. This control may be incompatible with your application. Make sure you are using the version of the control that was provided with your application.
Failed to load control ‘item1’ from ‘item2’. Your version of ‘item2’ may be outdated. Make sure you are using the version of the control that was provided with your application.
File already exists (Error 58)
File already open (Error 55)
File format no longer supported
File is read-only
File not found (Error 53)
File specified was not found
Filename or class name not found during Automation operation (Error 432)
Fixed or static data can’t be larger than 64K
Fixed-length strings and use of the ‘new’ qualifier are not allowed for fields in a public user defined type defined in an object module
Fixed-length strings not allowed as the type of a public member of an object module; private object modules not allowed as the type of a public member of a public object module
For control variable already in use
For Each can only iterate over a collection object or an array
For Each control variable must be Variant or Object
For Each control variable on arrays must be Variant
For Each may not be used on array of user-defined type or fixed-length strings
For loop not initialized (Error 92)
For without Next
Form already displayed; can’t show modally (Error 400)
Form not found (Error 424)
Forward reference to user-defined type
Function call on left-hand side of assignment must return Variant or Object
Function marked as restricted or uses a type not supported in Visual Basic
Identifier too long
Identifier under cursor isn’t a procedure name
Illegal parameter. Can’t write arrays (Error 328)
Illegal parameter. Can’t write object because it does not support persistence.
Illegal parameter. Can’t write user-defined type.
Incorrect DLL version
Incorrect OLE version
Input past end of file (Error 62)
Insufficient Immediate window memory to create variable
Insufficient memory to save Undo information
Insufficient project information to load project on platform or with version now being used
Interface not valid for Implements
Internal error (Error 51)
Invalid Access mode
Invalid attribute in Sub, Function, or Property
Invalid character
Invalid Clipboard format (Error 460)
Invalid Clipboard format (Error 460)
Invalid data format
Invalid data type for constant
Invalid event name
Invalid file format (Error 321)
Invalid file format (Error 321)
Invalid format in resource file (Error 325)
Invalid in Immediate window
Invalid inside Enum
Invalid inside procedure
Invalid length for fixed-length string
Invalid Next control variable reference
Invalid object use (Error 425)
Invalid optional parameter type
Invalid or unqualified reference
Invalid ordinal (Error 452)
Invalid outside Enum
Invalid outside procedure
Invalid ParamArray use
Invalid pattern string (Error 93)
Invalid picture (Error 481)
Invalid picture (Error 481)
Invalid picture type (Error 485)
Invalid procedure call or argument (Error 5)
Invalid procedure name
Invalid property name
Invalid property value (Error 380)
Invalid property value (Error 380)
Invalid property-array index (Error 381)
Invalid qualifier
Invalid ReDim
Invalid syntax for conditional compiler constant declarations
Invalid Template
Invalid type-declaration character
Invalid use of AddressOf operator
Invalid use of base class name
Invalid use of Me keyword
Invalid use of New keyword
Invalid use of Null (Error 94)
Invalid use of object
Invalid watch expression
Item’ already exists in project
‘item’ cannot be added because it is referenced but not in use by any items in the project. To correct this, uncheck ‘Remove information about unused ActiveX Controls’ in Project Options.
Item’ could not be loaded
‘Item’ could not be loaded. Remove it from the list of available add-ins?
Item’ could not be registered
‘item’ designers can only be used in DLL projects
‘item’ designers cannot be private
‘item’ designers cannot be public in ActiveX EXE projects
‘item’ designers must be public and cannot be used in Standard EXE projects
‘Item’ has an old file format. When saved, it will be saved in a newer format.
‘item’ has caused an access violation. Remove it from the list of available Add-Ins?
‘Item’ is a binary form and can’t be loaded into Visual Basic
‘Item’ is a read-only file
‘item’ is a single-threaded component and cannot be used in multi-threaded projects. Change the threading model for ‘item’ or contact the component vendor for an updated version.
‘Item’ property can’t be read at run time (Error 393)
‘Item’ property can’t be set at run time (Error 382)
‘Item’ property is read-only (Error 383)
‘Item’ property is write-only (Error 394)
‘Item’ will not be loaded. Name is already in use
‘item1’ is an invalid key. The file ‘item2’ can’t be loaded
‘item1’ is referenced by ‘item2’ project and cannot be updated.
Label not defined
Language/country setting has changed
License information for this component not found. You don’t have an appropriate license to use this functionality in the design environment (Error 429)
Line isn’t an executable statement
Line ‘item1’: All controls must precede menus; can’t load control ‘item2’.
Line ‘item1’: Can’t create embedded object in ‘item2’
Line ‘item1’: Can’t create embedded object in ‘item2’; license not found
Line ‘item1’: Can’t load control ‘item2’; containing control not a valid container.
Line ‘item1’: Can’t load control ‘item2’; license not found
Line ‘item1’: Can’t load control ‘item2’; name already in use.
Line ‘item1’: Can’t set checked property in menu ‘item2’. Parent menu can’t be checked.
Line ‘item1’: Can’t set Shortcut property in menu ‘item2’. Parent menu cannot have a shortcut key.
Line ‘item1’: Class ‘item2’ of control ‘item3’ was not a loaded control class.
Line ‘item1’: Class name too long; truncated to ‘item2’.
Line ‘item1’: Control name too long; truncated to ‘item2’.
Line ‘item1’: Could not create reference: ‘item2’
Line ‘item1’: Did not find an index property, and control ‘item2’ already exists.
Line ‘item1’: ‘item2’ has a quoted string where the property name should be.
Line ‘item1’: Maximum nesting level for controls exceeded with ‘item2’.
Line ‘item1’: Missing or invalid control class in file ‘item2 ‘.
Line ‘item1’: Missing or invalid control name in file ‘item2’.
Line ‘item1’: Parent menu ‘item2’ can’t be loaded as a separator.
Line ‘item1’: Property ‘item2’ in control ‘item3’ had an invalid property index.
Line ‘item1’: Property ‘item2’ in ‘item3’ could not be loaded.
Line ‘item1’: Property ‘item2’ in ‘item3’ could not be set.
Line ‘item1’: Property ‘item2’ in ‘item3’ had an invalid file reference.
Line ‘item1’: Property ‘item2’ in ‘item3’ had an invalid value.
Line ‘item1’: Property ‘item2’ in ‘item3’ must be a quoted string.
Line ‘item1’: Syntax error: property ‘item2’ in ‘item3’ was missing an equal sign (=).
Line ‘item1’: The CLSID ‘item2’ for ‘item3’ is invalid.
Line ‘item1’: The control name ‘item2’ is invalid.
Line ‘item1’: The file ‘item2’ could not be loaded.
Line ‘item1’: The Form or MDIForm name ‘item2’ is already in use; can’t load this form.
Line ‘item1’: The Form or MDIForm name ‘item2’ is not valid; can’t load this form.
Line ‘item1’: The property name ‘item2’ in ‘item3’ is invalid.
Line too long
Loop without Do
LSet allowed only on strings and user-defined types
LSet not allowed
Maximum number of watch expressions added
MDI forms are not allowed in multithreaded projects. Any MDI form will be removed from this project. To keep the MDI form in the project select Cancel and change threading model to Thread Pool with only 1 thread.
Member identifier already exists in object module from which this object module derives
Method not valid without suitable object
Method or data member not found (Error 461)
Missing end bracket
Module not found
Module too large
Must be first statement on the line
Must close or hide topmost modal form first (Error 402)
Must specify which item(s) to print
Name conflicts with existing module, project, or object library
Name ‘item’ conflicts with existing module, project, or object library
Named argument already specified
Named argument not found (Error 448)
Named arguments not allowed
Need property-array index (Error 385)
Next without For
No creatable public component detected. Press F1 for more information.
No Help available
No object (Error 31004)
No text selected
No watch expression selected
Not a legal object name: ‘item
Not enough memory to completely save project
Not enough memory to load file
Not enough memory to run; quitting
Object already loaded (Error 360)
Object does not have a Property Let procedure
Object does not source Automation events
Object doesn’t support current locale setting (Error 447)
Object doesn’t support named arguments (Error 446)
Object doesn’t support this action (Error 445)
Object doesn’t support this property or method (Error 438)
Object library feature not supported
Object library for Visual Basic for Applications not found
Object library invalid or contains references to object definitions that could not be found
Object library not registered
Object library’s language setting incompatible with current project
Object module must implement all procedures in interface
Object required (Error 424)
Object server not found (Error 337)
Object variable not set (Error 91)
Object was unloaded (Error 364)
One or more files in the project have changed. Do you want to save the changes now?
One or more instances of this object are running. Can’t remove it at this time.
One or more of the properties in ‘item’ was bad. Some or all of the properties might not be set correctly.
Only comments may appear after End Sub, End Function, or End Property
Only public user defined types defined in public object modules can be used as parameters or return types for public procedures of class modules or as fields of public user defined types
Only valid in object module
Operation not allowed in DLL
Option Private Module not permitted in object module
Optional argument must be Variant
Other applications are currently accessing an object in your program. Ending the program now could cause errors in those programs. End program at this time?
Out of memory (Error 31001)
Out of memory (Error 7)
Out of memory; some watches might have been deleted
Out of resources
Out of stack space (Error 28)
Out of string space (Error 14)
Overflow (Error 6)
ParamArray must be declared as an array of Variant
Path not found (Error 76)
Path/File access error (Error 75)
Permission denied (Error 70)
Permission to use object denied (Error 419)
Please see the Readme file for more information on this error
Printer driver does not support specified property (Error 483)
Printer error (Error 482)
Printer error (Error 482)
Private Enum and user-defined types cannot be used as parameters or return types for public procedures, public data members, or fields of public user-defined types
Private object modules cannot be used in public object modules as parameters or return types for public procedures, as public data members, or as fields of public user defined types
Problem getting printer information from the system; make sure the printer is set up correctly. (Error 484)
Procedure declaration does not match description of event or procedure having same name
Procedure too large
Procedure type mismatch
Project contains too many procedure, variable, and constant names
Project file is read-only
Project is unviewable.
Project not found
Property Get can’t be executed at run time (Error 393)
Property Get can’t be executed on write-only property (Error 394)
Property let procedure not defined and property get procedure did not return an object (Error 451)
Property not found (Error 422)
Property or method not found (Error 423)
Property Set can’t be executed at run time (Error 382)
Property Set can’t be used with a read-only property (Error 383)
Property Set not permitted (Error 387)
Qualified name disallowed in module scope
Qualifier must be collection
Range has no values
Replacements too long (Error 746)
Requested type library or wizard is not a VBA project
Resume without error (Error 20)
Return without GoSub (Error 3)
RSet allowed only on strings
Run-time error <number>:
Search string must be specified
Search string must be specified
Search string too long or complex
Search text isn’t found
Search text not found (Error 744)
Seek failed: can’t read/write from the disk
Select Case without End Select
Selected watch expression invalid
Set Next Statement can only apply to executable lines within current procedure.
SHARE.EXE required
Specified ActiveX component not correctly registered or not found
Specified DLL function not found (Error 453)
Specified format doesn’t match format of data (Error 461)
Specified library or project already referenced
Statement invalid inside Type block
Statement invalid outside Type block
Statement too complex
Statements or labels invalid between Select Case and first Case
String value too long to process; form load aborted
Sub, Function, or Property not defined (Error 35)
Subscript out of range (Error 9)
Syntax error
System DLL ‘dll’ could not be loaded (Error 298)
System error ‘item’
The .VBP file for this project contains an invalid or corrupt library references ID
The ActiveX Designer’s Type Information does not match what was saved. Unable to Load.
The application description can’t be more than 2000 characters long
The code in this project must be updated for use on 64-bit systems
The current project does not support files of this type
The edit may make the object module incompatible with the previously specified compatible ActiveX component
The file ‘item’ is marked as a version not supported by the current version of Visual Basic and won’t be loaded
The file ‘item’ is out of date. This program requires a later version (Error 368)
The form class contained in the specified file is not supported in Visual Basic for Applications; the file can’t be loaded.
The library containing this symbol is not referenced by the current project, so the symbol is undefined. Would you like to add a reference to the containing library now?
The project file ‘item’ is corrupt and can’t be loaded
The project file ‘item1’ contains invalid ‘item2’ key value
The project file ‘item1’ contains invalid ‘item2’ key value. Valid range is 0 to ‘item3’
The project file ‘item1’ contains invalid key ‘item2’. The project can’t be loaded
The project name is too long. Name has been truncated
The remote server machine does not exist or is unavailable (Error 462)
The selected Add-In has not been confirmed to be ‘Command Line Safe,’ and may require some user intervention (possible UI)
The specified file could not be loaded.
The specified object can’t be used as an owner form for Show() (Error 371)
The specified region has been searched
The specified region has been searched and 1 replacement was made
The specified region has been searched and the replacements were made
This action will reset your project, proceed anyway?
This array is fixed or temporarily locked (Error 10)
This command will stop the debugger.
This component doesn’t raise any events
This component doesn’t support this set of events (Error 459)
This control can only be used with ‘item’ designers
This control cannot be used with ‘item’ designers
This designer cannot be used because it uses features that are not supported in this version of Visual Basic
This document was opened with Macros Disabled
This edit requires a Reset
This feature requires Internet Explorer ‘item’ or greater. You can obtain the latest version from http://www.microsoft.com
This interaction between compiled and design environment components is not supported
This key is already associated with an element of this collection (Error 457)
This project is currently referenced by another project and cannot be closed
This VBA project was created while running VBA in a different application. You may only open it from inside the same application in which it was created.
Too many arguments
Too many dimensions
Too many DLL application clients
Too many files (Error 67)
Too many line continuations
Too many local, nonstatic variables
Too many module-level variables
Translation failed. Please check the trnslate.log file for more information.
Trappable Errors
Type mismatch (Error 13)
Type mismatch: array or user-defined type expected
Type not supported in Visual Basic
Type-declaration character does not match declared data type
Type-declaration character not allowed
Type-declaration character required
Unable to activate object (Error 31027)
Unable to create embedded object (Error 31032)
Unable to read from the disk
Unable to unload within this context (Error 365)
Unable to write Designer cache file ‘item’; will just use regular files on Load
Unable to write to the disk
Unexpected compile error
Unexpected error
Unexpected error; please contact Microsoft Technical Support
Unexpected error; quitting
Unmatched brackets in search string
Unrecognized project language
User interrupt occurred (Error 18)
User-defined type may not be passed ByVal
User-defined type not defined
User-defined type without members not allowed
Valid values are whole numbers from 1 to 32
Valid values are whole numbers from 2 to 60
Variable not defined
Variable not yet created in this context
Variable required. Can’t assign to this expression
Variable uses a type not supported in Visual Basic (Error 458)
Version number missing or invalid; Visual Basic 5.0 assumed
Visual Basic can’t load ‘item’ because it is not in the system registry. Please ensure that all add-ins have been installed correctly.
Warning: custom language settings not portable
Wend without While
While without Wend
Windowless controls can’t have menus.
With object must be user-defined type, Object, or Variant
Wizards can’t reference projects
Wrong number of arguments (Error 450)
Wrong number of dimensions
Wrong version of operating system; requires Windows NT 3.51 (build ‘item1’ or later) or Windows 95 (build ‘item2’ or later)
You must save a project before you can reference it.
You must terminate the #If block with an #End If
Component could not successfully create requested object
Component ‘item’ or one of its dependencies not correctly registered: a file is missing or invalid
Component not found in registered location
Invalid Base Address
Programmatic ID string too long ‘item’. The Programmatic ID must be 39 characters or less.
Project <name> has been modified. Do you wish to save the changes now?
The file ‘item’ was not registerable as an ActiveX Component.
The load behavior for ‘item’ could not be updated because of current registry permissions.
The project file ‘item1’ contains invalid key ‘item2’.
Unable to display Help
Unexpected error occurred in code generator or linker
Version numbers must be in the range 0 to 9999
The binary compatibility DLL or EXE contains a parameter type or return type whose definition cannot be found
The binary compatibility DLL or EXE contains an Implements type whose definition cannot be found
I have my code below, the strange thing is that the Errorhandler
procedure is still executing even though there are no errors in the code… What can be the issue?
Running the code without any errorhandlers generates no errors, but still the msgbox
under Errorhandler
shows up when I include an error handling statement!
Code
Public Sub ExportGraphs(Optional PivotExport As Boolean)
' Exports only graphs on the "Mainwindow" sheet to a new worksheet
Dim wsh As Worksheet: Set wsh = Sheets.Add
Dim source_sht As Worksheet: Set source_sht = Sheets("Mainwindow")
ActiveWindow.Zoom = 70
On Error GoTo Errorhandler
With wsh
If source_sht.OLEObjects("Btn_CurrentTime").Object.Value = True Then
.Name = source_sht.OLEObjects("CombBox_Instruments").Object.Value & " " & source_sht.OLEObjects("DTPicker_FROM").Object.Value _
& "-" & source_sht.OLEObjects("DTPicker_TO").Object.Value
Else
.Name = source_sht.OLEObjects("CombBox_Instruments").Object.Value & " " & "Max_Possible_To" _
& "-" & source_sht.OLEObjects("DTPicker_TO").Object.Value
End If
End With
Dim source_chart As ChartObject
Dim target_rng As Range: Set target_rng = wsh.Range("A1")
For Each source_chart In source_sht.ChartObjects
source_chart.CopyPicture xlScreen, xlBitmap
target_rng.PasteSpecial
Set target_rng = target_rng.Offset(20, 0)
Next
If PivotExport = True Then
Debug.Print "se"
End If
Errorhandler:
MsgBox "An export sheet for this ticker and timeline already exists"
End Sub
Chrismas007
6,0754 gold badges24 silver badges47 bronze badges
asked Dec 30, 2014 at 15:35
1
@dee provided the correct answer.
The Errorhandler:
is just a place holder. It does NOT operate like you think. You are using it like an If... Then...
statement:
If Error Then
Show MsgBox
Else
Skip MsgBox
End If
As the Errorhandler is just a placeholder and NOT an If... Then...
, the code after the placeholder will run regardless of error or no error. To rectify this issue, add an Exit Sub
above the Errorhandler:
line:
Exit Sub
Errorhandler:
MsgBox "An export sheet for this ticker and timeline already exists"
End Sub
answered Dec 30, 2014 at 16:14
Chrismas007Chrismas007
6,0754 gold badges24 silver badges47 bronze badges
In this piece of code, ErrorHandler:
is what is known as a line label.
Errorhandler:
MsgBox "An export sheet for this ticker and timeline already exists"
End Sub
Line labels are not executable code, but rather just a marker that can tell other code where to jump to via any GoTo Statement. Armed with this knowledge, they are obviously not exclusive to error handlers.
The solution here is to use the Exit Statement to return from the Sub
«early».
Exit Sub
Errorhandler:
MsgBox "An export sheet for this ticker and timeline already exists"
End Sub
Others may disagree with me, but I like to build my error handling so that the code always stops execution on Exit Sub
. If the code ends its execution on End Sub
, something has gone wrong.
answered Dec 30, 2014 at 16:35
RubberDuckRubberDuck
11.8k4 gold badges50 silver badges95 bronze badges
No matter how experienced you’re with VBA coding, errors are always going to be a part of it.
The difference between a novice and an expert VBA programmer is that the expert programmers know how to effectively handle and use errors.
In this tutorial, I will show you various ways you can use to handle errors effectively in Excel VBA.
Before we get into VBA error handling, let’s first understand the different types of errors you are likely to encounter when programming in Excel VBA.
Types of VBA Errors in Excel
There are four types of errors in Excel VBA:
- Syntax errors
- Compilation errors
- Runtime errors
- Logical Errors
Let’s quickly understand what these errors are and when you’re likely to encounter these.
Syntax Error
A syntax error, as the name suggests, occurs when VBA finds something wrong with the syntax in the code.
For example, if you forget a part of the statement/syntax that is needed, then you will see the compile error.
In the below code, as soon as I hit enter after the second line, I see a compile error. This is because the IF statement needs to have the ‘Then‘ command, which is missing in the below code.
Note: When you are typing a code in Excel VBA, it checks for each sentence as soon as you hit enter. If VBA finds something missing in the syntax, it instantly shows a message with some text that can help you understand the missing part.
To make sure you see the syntax error whenever there is something missing, you need to make sure Autosyntax check is enabled. To do this, click on ‘Tools’ and then click on ‘Options’. In the options dialog box, make sure that the ‘Auto Syntax Check’ option is enabled.
If the ‘Auto Syntax Check’ option is disabled, VBA will still highlight the line with the syntax error in red, but it will not show the error dialog box.
Compile Error
Compile errors occur when something is missing that is needed for the code to run.
For example, in the below code, as soon as I try to run the code, it will show the following error. This happens as I have used the IF Then statement without closing it with the mandatory ‘End If’.
A syntax error is also a type of compile error. A syntax error occurs as soon as you hit enter and VBA identifies that something is missing. A compilation error can also occur when VBA doesn’t find anything missing while typing the code, but it does when the code is compiled or executed.
VBA checks each line as you’re typing the code and highlights the syntax error as soon as the line is incorrect and you hit enter. Compile errors, on the other hand, are only identified when the entire code is analyzed by VBA.
Below are some scenarios where you’ll encounter the compile error:
- Using an IF Statement without the End IF
- Using For statement with the Next
- Using Select statement without using the End Select
- Not declaring the variable (this works only when Option Explicit is enabled)
- Calling a Sub/Function that does not exist (or with wrong parameters)
Note about ‘Option Explicit’: When you add ‘Option Explicit’, you will be required to declare all the variables before running the code. If there is any variable that has not been declared, VBA would show an error. This is a good practice as it shows an error in case you have a misspelled variable. You can read more about Option Explicit here.
Run Time Errors
Runtime errors are those that occur when the code is running.
Run time errors will occur only when all the syntax and compile errors are being taken care of.
For example, if you run code that is supposed to open an Excel workbook, but that workbook is unavailable (either deleted or name changed), your code would give you a runtime error.
When a runtime error occurs, it will stop the code and show you the error dialog box.
The message in the Run-time error dialog box is a little more helpful. It tries to explain the problem that can help you correct it.
If you click on the Debug button, it will highlight the part of the code that is leading to the error.
If you have corrected the error, you can click on the Run button in the toolbar (or press F5) to continue running the code from where it left.
Or you can also click on the End button to come out of the code.
Important: In case you click the End button in the dialog box, it will stop the code at the line at which is encountered. However, all the lines of code before that would have been executed.
Logical Errors
Logical errors would not make your code stop but can lead to wrong results. These could also be the most difficult types of errors to troubleshoot.
These errors are not highlighted by the compiler and need to be manually tackled.
One example of logical error (that I often find myself stuck with) is running into an endless loop.
Another example could be when it gives a result which is wrong. For example, you may end up using a wrong variable in the code or add two variables where one is incorrect.
There are a few ways I use to tackle logical errors:
- Insert Message Box at some place in the code and highlight values/data that can help understand if eberything is going as expected.
- Instead of running the code at one go, go through each line one by one. To do this, click anywhere in the code and press F8. you would notice that each time you press F8, one line gets executed. This allows you to go through the code one line at a time and identify the logical errors.
Using Debug to Find Compile/Syntax Errors
Once you’re done with the code, it’s a good practice to first compile it before running.
To compile a code, click on the Debug option in the toolbar and click on Compile VBAProject.
When you compile a VBA project, it goes through the code and identifies errors (if any).
In case it finds an error, it will show you a dialog box with the error. It finds errors one by one. So if it finds an error and you have corrected it, you need to run compile again to find other errors (if there are).
When you’re code is free of errors, the Compile VBAProject option will be greyed out.
Note that Compiling will only find ‘Syntax’ errors and ‘Compile’ errors. It will NOT find the run-time errors.
When you’re writing VBA code, you don’t want the errors to crop up. To avoid this, there are many error-handling methods you can use.
In the next few sections of this article, I will be covering the methods you can use for VBA error handling in Excel.
Configure Error Settings (Handled Vs Unhandled Errors)
Before you start working with your code, you need to check for one setting in Excel VBA.
Go to the VBA toolbar and click on Tools and then click on Options.
In the Options dialog box, click on the General tab and make sure that within the ‘Error Trapping’ group, ‘Break on Unhandled Errors’ is checked.
Let me explain the three options:
- Break on All Errors: This will stop your code on all types of errors, even when you have used the techniques to handle these errors.
- Break in Class Module: This will stop your code on all unhandled errors, and at the same time, if you’re using objects such as Userforms, it will also break within those objects and highlight the exact line causing the error.
- Break on Unhandled Errors: This will stop your code only for those errors that are not handled. This is the default setting as it ensures any unhandled errors are brought to your notice. If you’re using objects such as Userforms, this will not highlight the line causing the error in the object, but will only highlight the line that’s referring to that object.
Note: If you work with objects such as Userforms, you can change this setting to ‘Break on Class Modules’. The difference between #2 and #3 is that when you use Break in Class Module, it will take you to the specific line in the object that is causing the error. You can also choose to go with this instead of ‘Break on Unhandled Errors’.
So in a nutshell – if you’re just starting with Excel VBA, ensure ‘Break on Unhandled Errors’ is checked.
VBA Error Handling with ‘On Error’ Statements
When your code encounters an error, there are a few things you can do:
- Ignore the error and let the code continue
- Have an error handling code in place and run it when an error occurs
Both of these error handling methods ensures that the end user will not get to see an error.
There are a few ‘On Error’ statements that you can use to get these done.
On Error Resume Next
When you use ‘On Error Resume Next’ in your code, any encountered error will be ignored and the code will continue to run.
This error handling method is used quite often, but you need to be cautious when using it. Since it completely ignores any error that may occur, you may not be able to identify the errors that need to be corrected.
For example, if the below code is run, it will return an error.
Sub AssignValues() x = 20 / 4 y = 30 / 0 End Sub
This happens because you can not divide a number by zero.
But if I use the ‘On Error Resume Next’ statement in this code (as shown below), it will ignore the error and I will not know that there is an issue that needs to be corrected.
Sub AssignValues() On Error Resume Next x = 20 / 4 y = 30 / 0 End Sub
On Error Resume Next should be used only when you clearly know the kind of errors your VBA code is expected to throw and it’s alright to ignore it.
For example, below is the VBA event code that would instantly add the date and time value in cell A1 of a newly inserted sheet (this code is added in the worksheet and not in a module).
Private Sub Workbook_NewSheet(ByVal Sh As Object) Sh.Range("A1") = Format(Now, "dd-mmm-yyyy hh:mm:ss") End Sub
While this works great in most cases, it would show an error if I add a chart sheet instead of a worksheet. Since a chart sheet does not have cells, the code would throw an error.
So, if I use the ‘On Error Resume Next’ statement in this code, it will work as expected with worksheets and do nothing with chart sheets.
Private Sub Workbook_NewSheet(ByVal Sh As Object) On Error Resume Next Sh.Range("A1") = Format(Now, "dd-mmm-yyyy hh:mm:ss") End Sub
Note: On Error Resume Next Statement is best used when you know what kind of errors you’re likely to encounter. And then if you think it’s safe to ignore these errors, you can use it.
You can take this code to the next level by analyzing if there was an error, and displaying a relevant message for it.
The below code would show a message box that would inform the user that a worksheet has not been inserted.
Private Sub Workbook_NewSheet(ByVal Sh As Object) On Error Resume Next Sh.Range("A1") = Format(Now, "dd-mmm-yyyy hh:mm:ss") If Err.Number <> 0 Then MsgBox "Looks like you inserted a chart sheet" & vbCrLf & "Error - " & Err.Description End If End Sub
‘Err.Number’ is used to get the error number and ‘Err.Description’ is used to get the error description. These will be covered later in this tutorial.
On Error GoTo 0
‘On Error GoTo 0’ will stop the code on the line that causes the error and shows a message box that describes the error.
In simple terms, it enables the default error checking behavior and shows the default error message.
Then why even use it?
Normally, you don’t need to use ‘On Error Goto 0’, but it can be useful when you use it in conjunction with ‘On Error Resume Next’
Let me explain!
The below code would select all the blank cells in the selection.
Sub SelectFormulaCells() Selection.SpecialCells(xlCellTypeBlanks).Select End Sub
But it would show an error when there are no blank cells in the selected cells.
So to avoid showing the error, you can use On Error Resume next’
Now, it will also show any error when you run the below code:
Sub SelectFormulaCells() On Error Resume Next Selection.SpecialCells(xlCellTypeBlanks).Select End Sub
So far, so good!
The problem arises when there is a part of the code where error can occur, and since you’re using ‘On Error Resume Next’, the code would simply ignore it and move to the next line.
For example, in the below code, there would no error prompt:
Sub SelectFormulaCells() On Error Resume Next Selection.SpecialCells(xlCellTypeBlanks).Select ' .. more code that can contain error End Sub
In the above code, there are two places where an error can occur. The first place is where we are selecting all blank cells (using Selection.SpecialCells) and the second is in the remaining code.
While the first error is expected, any error after that is not.
This is where On Error Goto 0 comes to rescue.
When you use it, you reset the error setting to default, where it will start showing errors when it encounters it.
For example, in the below code, there would be no error in case there are no blank cells, but there would be an error prompt because of ’10/0′
Sub SelectFormulaCells() On Error Resume Next Selection.SpecialCells(xlCellTypeBlanks).Select On Error GoTo 0 ' .. more code that can contain error End Sub
On Error Goto [Label]
The above two methods – ‘On Error Resume Next’ and ‘On Error Goto 0’ – doesn’t allow us to truly handle the error. One makes the code ignore the error and the second one resume error checking.
On Error Go [Label] is a way with which you can specify what you want to do in case your code has an error.
Below is the code structure that uses this error handler:
Sub Test() On Error GoTo Label: X = 10 / 0 'this line causes an error ' ....your remaining code goes here Exit Sub Label: ' code to handle the error End Sub
Note that before the Error handling ‘Label’, there is an Exit Sub. This ensures that in case there are no errors, the sub is exited and the ‘Label’ code is not executed. In case you don’t use Exit Sub, it will always execute the ‘Label’ code.
In the example code below, when an error occurs, the code jumps and executes the code in the handler section (and shows a message box).
Sub Errorhandler() On Error GoTo ErrMsg X = 12 Y = 20 / 0 Z = 30 Exit Sub ErrMsg: MsgBox "There seems to be an error" & vbCrLf & Err.Description End Sub
Note that when an error occurs, the code has already run and executed the lines before the line causing the error. In the above example, the code sets the value of X as 12, but since the error occurs in the next line, it doesn’t set the values for Y and Z.
Once the code jumps to the error handler code (ErrMsg in this example), it will continue to execute all the lines in and below the error handler code and the exit the sub.
On Error Goto -1
This one is a bit complicated, and in most cases, you’re unlikely to use this.
But I will still cover this as I have faced a situation where this was needed (feel free to ignore and jump to the next section if you’re only looking for basics).
Before I get into the mechanics of it, let me try and explain where can it be useful.
Suppose you have a code where an error is encountered. But all is good as you have one error handler in place. But what happens when there is another error in the error handler code (yeah.. somewhat like the inception movie).
In such a case, you can not use the second handler as the first error has not been cleared. So while you have handled the first error, in VBA’s memory it still exists. And the VBA memory only has a place for one error – not two or more than that.
In this scenario, you can use On Error Goto -1.
It clears the error and frees up VBA memory to handle the next error.
Enough talk!
Let’s me explain now by using examples.
Suppose I have the below code. This will throw an error as there is division by zero.
Sub Errorhandler() X = 12 Y = 20 / 0 Z = 30 End Sub
So to handle it, I use an error handler code (with the name ErrMsg) as shown below:
Sub Errorhandler() On Error GoTo ErrMsg X = 12 Y = 20 / 0 Z = 30 Exit Sub ErrMsg: MsgBox "There seems to be an error" & vbCrLf & Err.Description End Sub
All is good now again. As soon as the error occurs, the error handler is used and shows a message box as shown below.
Now, I expand the code so that I have more code in or after the error handler.
Sub Errorhandler() On Error GoTo ErrMsg X = 12 Y = 20 / 0 Z = 30 Exit Sub ErrMsg: MsgBox "There seems to be an error" & vbCrLf & Err.Description A = 10 / 2 B = 35 / 0 End Sub
Since the first error has been handled but the second has not been, I again see an error as shown below.
Still all good. The code is behaving in the way we expected it to.
So to handle the second error, I use another error handler (ErrMsg2).
Sub Errorhandler() On Error GoTo ErrMsg X = 12 Y = 20 / 0 Z = 30 Exit Sub ErrMsg: MsgBox "There seems to be an error" & vbCrLf & Err.Description On Error GoTo ErrMsg2 A = 10 / 2 B = 35 / 0 Exit Sub ErrMsg2: MsgBox "There seems to be an error again" & vbCrLf & Err.Description End Sub
And this is where it doesn’t work as expected.
If you run the above code, it will still give you a run-time error, even after having the second error handler in place.
This happens as we didn’t clear the first error from VBA’s memory.
Yes, we handled it! But it still remains in the memory.
And when VBA encounters another error, it’s still stuck with the first error, and hence the second error handler is not used. The code stops at the line that caused the error and shows the error prompt.
To clear VBA’s memory and clear the previous error, you need to use the ‘On Error Goto -1’.
So if you add this line in the below code and run it, it will work as expected.
Sub Errorhandler() On Error GoTo ErrMsg X = 12 Y = 20 / 0 Z = 30 Exit Sub ErrMsg: MsgBox "There seems to be an error" & vbCrLf & Err.Description On Error GoTo -1 On Error GoTo ErrMsg2 A = 10 / 2 B = 35 / 0 Exit Sub ErrMsg2: MsgBox "There seems to be an error again" & vbCrLf & Err.Description End Sub
Note: The error automatically gets cleared when a subroutine ends. So, ‘On Error Goto -1’ can be useful when you’re getting two or more than two errors in the same subroutine.
The Err Object
Whenever an error occurs with a code, it’s the Err object that is used to get the details about the error (such as the error number or the description).
Err Object Properties
The Err Object has the following properties:
Property | Description |
Number | A number that represents the type of error. When there is no error, this value is 0 |
Description | A short description of the error |
Source | Project name in which the error has occurred |
HelpContext | The help context id for the error in the help file |
HelpFile | A string that represents the folder location and the file name of the help file |
While in most cases you don’t need to use Err object, it can sometimes be useful while handling errors in Excel.
For example, suppose you have a dataset as shown below and for each number, in the selection, you want to calculate the square root in the adjacent cell.
The below code can do it, but since there is a text string in cell A5, it shows an error as soon as this occurs.
Sub FindSqrRoot() Dim rng As Range Set rng = Selection For Each cell In rng cell.Offset(0, 1).Value = Sqr(cell.Value) Next cell End Sub
The problem with this type of error message is that it gives you nothing about what has gone wrong and where the issue occurred.
You can use the Err object to make these error messages more meaningful.
For example, if I now use the below VBA code, it will stop the code as soon as the error occurs and show a message box with the cell address of the cell where there is an issue.
Sub FindSqrRoot() Dim rng As Range Set rng = Selection For Each cell In rng On Error GoTo ErrHandler cell.Offset(0, 1).Value = Sqr(cell.Value) Next cell ErrHandler: MsgBox "Error Number:" & Err.Number & vbCrLf & _ "Error Description: " & Err.Description & vbCrLf & _ "Error at: " & cell.Address End Sub
The above code would give you a lot more information than the simple ‘Type Mismatch’, especially the cell address so that you know where the error occurred.
You can further refine this code to make sure your code runs until the end (instead of breaking at each error) and then gives you a list of cell address where the error occurs.
The below code would do this:
Sub FindSqrRoot2() Dim ErrorCells As String Dim rng As Range On Error Resume Next Set rng = Selection For Each cell In rng cell.Offset(0, 1).Value = Sqr(cell.Value) If Err.Number <> 0 Then ErrorCells = ErrorCells & vbCrLf & cell.Address On Error GoTo -1 End If Next cell MsgBox "Error in the following cells" & ErrorCells Exit Sub End Sub
The above code runs until the end and gives the square root of all the cells that have numbers in it (in the adjacent column). It then shows a message that lists all the cells where there was an error (as shown below):
Err Object Methods
While the Err properties are useful to show useful information about the errors, there are two Err methods as well that can help you with error handling.
Method | Description |
Clear | Clears all the property settings of the Err object |
Raise | Generates a run-time error |
Let’s quickly learn what these are and how/why to use these with VBA in Excel.
Err Clear Method
Suppose you have a dataset as shown below and you want to get the square root of all these numbers in the adjacent column.
The following code will get the square roots of all the numbers in the adjacent column and show a message that an error occurred for cell A5 and A9 (as these have text in it).
Sub FindSqrRoot2() Dim ErrorCells As String Dim rng As Range On Error Resume Next Set rng = Selection For Each cell In rng cell.Offset(0, 1).Value = Sqr(cell.Value) If Err.Number <> 0 Then ErrorCells = ErrorCells & vbCrLf & cell.Address Err.Clear End If Next cell MsgBox "Error in the following cells" & ErrorCells End Sub
Note that I have used the Err.Clear method within the If Then statement.
Once an error has occurred and trapped by the If condition, Err.Clear method resets the error number back to 0. This ensures that IF condition only trap the errors for cells where it is raised.
Had I not used the Err.Clear method, once the error occurs, it would always be true in the IF condition, and the error number has not been reset.
Another way of making this work is by using the On Error Goto -1, which resets the error completely.
Note: Err.Clear is different from On Error Goto -1. Err.Clear only clears the error description and the error number. it doesn’t completely reset it. This means that if there is another instance of error in the same code, you won’t be able to handle it before resetting it (which can be done with ‘On Error Goto -1’ and not by ‘Err.Clear’).
Err Raise Method
The Err.Raise method allows you to raise a run-time error.
Below is the syntax of using the Err.Raise method:
Err.Raise [number], [source], [description], [helpfile], [helpcontext]
All these arguments are optional and you can use these to make your error message more meaningful.
But why would you ever want to raise an error yourself?
Good question!
You can use this method when there is an instance of an error (which means that there is going to an error anyway) and then you use this method to tell the user more about the error (instead of the less helpful error message that VBA shows by default).
For example, suppose you have a dataset as shown below and you want all the cells to have numeric values only.
Sub RaiseError() Dim rng As Range Set rng = Selection On Error GoTo ErrHandler For Each Cell In rng If Not (IsNumeric(Cell.Value)) Then Err.Raise vbObjectError + 513, Cell.Address, "Not a number", "Test.html" End If Next Cell ErrHandler: MsgBox Err.Description & vbCrLf & Err.HelpFile End Sub
The above code would show an error message that has the specified description and the context file.
Personally, I have never used Err.Raise as I mostly work with Excel only. But for someone who uses VBA to work with Excel along with other applications such as Outlook, Word or PowerPoint, this can be useful.
Here is a detailed article on Err.Raise method in case you want to learn more.
VBA Error Handling Best Practices
No matter how skilled you get a writing VBA code, errors are always going to be a part of it. The best coders are those who have the skills to handle these errors properly.
Here are some best practices you can use when it comes to error handling in Excel VBA.
- Use ‘On Error Go [Label]’ at the beginning of the code. This will make sure any error that can happen from there is handled.
- Use ‘On Error Resume Next’ ONLY when you’re sure about the errors that can occur. Use it with expected error only. In case you use it with unexpected errors, it will simply ignore it and move forward. You can use ‘On Error Resume Next’ with ‘Err.Raise’ if you want to ignore a certain type of error and catch the rest.
- When using error handlers, make sure you’re using Exit Sub before the handlers. This will ensure that the error handler code is executed only when there is an error (else it will always be executed).
- Use multiple error handlers to trap different kinds of errors. Having multiple error handler ensures that an error is properly addressed. For example, you would want to handle a ‘type mismatch’ error differently than a ‘Division by 0’ run-time error.
Hope you found this Excel article useful!
Here are some more Excel VBA Tutorials that you may like:
- Excel VBA Data Types – A Complete Guide
- Excel VBA Loops – For Next, Do While, Do Until, For Each
- Excel VBA Events – An Easy (and Complete) Guide
- Excel Visual Basic Editor – How to Open and Use it in Excel
“Abort, Retry, Fail?” – MS-DOS error message circa 1986
This post provides a complete guide to VBA Error Handing. If you are looking for a quick summary then check out the quick guide table in the first section.
If you are looking for a particular topic on VBA Error Handing then check out the table of contents below(if it’s not visible click on the post header).
If you are new to VBA Error Handling, then you can read the post from start to finish as it is laid out in logical order.
Contents
- 1 A Quick Guide to Error Handing
- 2 The Webinar
- 3 Download the Error Handling Library
- 4 Introduction
- 5 VBA Errors
- 5.1 Syntax Errors
- 5.2 Compilation Errors
- 5.2.1 Using Debug->Compile
- 5.2.2 Debug->Compile Error Summary
- 5.2.3 Debug->Compile Usage
- 5.3 Runtime Errors
- 5.3.1 Expected Versus Unexpected Errors
- 5.4 Runtime Errors that are not VBA Errors
- 6 The On Error Statement
- 6.1 On Error GoTo 0
- 6.2 On Error Resume Next
- 6.3 On Error GoTo [label]
- 6.4 On Error GoTo -1
- 6.5 Using On Error
- 7 Resume Next
- 8 The Err Object
- 8.1 Getting the Line Number
- 8.2 Using Err.Raise
- 8.3 Using Err.Clear
- 9 Logging
- 10 Other Error Related Items
- 10.1 Error Function
- 10.2 Error Statement
- 11 A Simple Error Handling Strategy
- 11.1 The Basic Implementation
- 12 A Complete Error Handling Strategy
- 12.1 An Example of using this strategy
- 13 Error Handling in a Nutshell
- 14 What’s Next?
A Quick Guide to Error Handing
Item | Description |
---|---|
On Error Goto 0 | When error occurs, the code stops and displays the error. |
On Error Goto -1 | Clears the current error setting and reverts to the default. |
On Error Resume Next | Ignores the error and continues on. |
On Error Goto [Label] | Goes to a specific label when an error occurs. This allows us to handle the error. |
Err Object | When an error occurs the error information is stored here. |
Err.Number | The number of the error. (Only useful if you need to check a specific error occurred.) |
Err.Description | Contains the error text. |
Err.Source | You can populate this when you use Err.Raise. |
Err.Raise | A function that allows you to generate your own error. |
Error Function | Returns the error text from an error number. Obsolete. |
Error Statement | Simulates an error. Use Err.Raise instead. |
The Webinar
Members of the Webinar Archives can access the webinar for this article by clicking on the image below.
(Note: Archive members have access to the webinar archive.)
Download the Error Handling Library
Introduction
Error Handling refers to code that is written to handle errors which occur when your application is running. These errors are normally caused by something outside your control like a missing file, database being unavailable, data being invalid etc.
If we think an error is likely to occur at some point, it is good practice to write specific code to handle the error if it occurs and deal with it.
For all other errors, we use generic code to deal with them. This is where the VBA error handling statement comes into play. They allow our application to deal gracefully with any errors we weren’t expecting.
To understand error handling we must first understand the different types of errors in VBA.
VBA Errors
There are three types of errors in VBA:
- Syntax
- Compilation
- Runtime
We use error handling to deal with runtime errors. Let’s have a look at each of these error types so that it is clear what a runtime error is.
Syntax Errors
If you have used VBA for any length of time you will have seen a syntax error. When you type a line and press return, VBA will evaluate the syntax and if it is not correct it will display an error message.
For example if you type If and forget the Then keyword, VBA will display the following error message
Some examples of syntax errors are
' then is missing If a > b ' equals is missing after i For i 2 To 7 ' missing right parenthesis b = left("ABCD",1
Syntax errors relate to one line only. They occur when the syntax of one line is incorrect.
Note: You can turn off the Syntax error dialog by going to Tools->Options and checking off “Auto Syntax Check”. The line will still appear red if there is an error but the dialog will not appear.
Compilation Errors
Compilation errors occur over more than one line. The syntax is correct on a single line but is incorrect when all the project code is taken into account.
Examples of compilation errors are:
- If statement without corresponding End If statement
- For without Next
- Select without End Select
- Calling a Sub or Function that does not exist
- Calling a Sub or Function with the wrong parameters
- Giving a Sub or Function the same name as a module
- Variables not declared(Option Explicit must be present at the top of the module)
The following screenshot shows a compilation error that occurs when a For loop has no matching Next statement.
Using Debug->Compile
To find compilation errors, we use Debug->Compile VBA Project from the Visual Basic menu.
When you select Debug->Compile, VBA displays the first error it comes across.
When this error is fixed, you can run Compile again and VBA will then find the next error.
Debug->Compile will also include syntax errors in it’s search which is very useful.
If there are no errors left and you run Debug->Compile , it may appear that nothing happened. However, “Compile” will be grayed out in the Debug menu. This means your application has no compilation errors at the current time.
Debug->Compile Error Summary
- Debug->Compile finds compilation(project wide) errors.
- It will also find syntax errors.
- It finds one error each time you use it.
- When there are no compilation errors left the Compile option will appear grayed out in the menu.
Debug->Compile Usage
You should always use Debug->Compile before you run your code. This ensures that your code has no compilation errors when you run it.
If you do not run Debug->Compile then VBA may find compile errors when it runs. These should not be confused with Runtime errors.
Runtime Errors
Runtime errors occur when your application is running. They are normally outside of your control but can be caused by errors in your code.
For example, imagine your application reads from an external workbook. If this file gets deleted then VBA will display an error when your code tries to open it.
Other examples of runtime errors are
- a database not being available
- the user entering invalid data
- a cell containing text instead of a number
As we have seen, the purpose of error handling is to deal with runtime errors when they occur.
Expected Versus Unexpected Errors
When we think a runtime error could occur we put code in place to handle it. For example, we would normally put code in place to deal with a file not being found.
The following code checks if the file exists before it tries to open it. If the file does not exist then a user friendly message is displayed and the code exits the sub.
' https://excelmacromastery.com/ Sub OpenFile() Dim sFile As String sFile = "C:docsdata.xlsx" ' Use Dir to check if file exists If Dir(sFile) = "" Then ' if file does not exist display message MsgBox "Could not find the file " & sFile Exit Sub End If ' Code will only reach here if file exists Workbooks.Open sFile End Sub
When we think an error is likely to occur at some point, it is good practice to add code to handle the situation. We normally refer to these errors as expected errors.
If we don’t have specific code to handle an error it is considered an unexpected error. We use the VBA error handling statements to handle the unexpected errors.
Runtime Errors that are not VBA Errors
Before we look at the VBA Handling there is one type of error we must mention. Some runtime errors are not considered errors by VBA but only by the user.
Let me explain this with an example. Imagine you have an application that requires you to add the values in the variables a and b
result = a + b
Let’s say you mistakenly use an asterisk instead of the plus sign
result = a * b
This is not a VBA error. Your code syntax is perfectly legal. However, from your requirements point of view it is an error.
These errors cannot be dealt with using error handling as they obviously won’t generate any error. You can deal with these errors using Unit Testing and Assertions. I have an in-depth post about using VBA assertions – see How to Make Your Code BulletProof.
The On Error Statement
As we have seen there are two ways to treat runtime errors
- Expected errors – write specific code to handle them.
- Unexpected errors – use VBA error handling statements to handle them.
The VBA On Error statement is used for error handling. This statement performs some action when an error occurs during runtime.
There are four different ways to use this statement
- On Error GoTo 0 – the code stops at the line with the error and displays a message.
- On Error Resume Next – the code moves to next line. No error message is displayed.
- On Error GoTo [label] – the code moves to a specific line or label. No error message is displayed. This is the one we use for error handling.
- On Error GoTo -1 – clears the current error.
Let’s look at each of these statements in turn.
On Error GoTo 0
This is the default behavior of VBA. In other words, if you don’t use On Error then this is the behavior you will see.
When an error occurs, VBA stops on the line with the error and displays the error message. The application requires user intervention with the code before it can continue. This could be fixing the error or restarting the application. In this scenario no error handling takes place.
Let’s look at an example. In the following code, we have not used any On Error line so VBA will use the On Error GoTo 0 behavior by default.
' https://excelmacromastery.com/ Sub UsingDefault() Dim x As Long, y As Long x = 6 y = 6 / 0 x = 7 End Sub
The second assignment line results in a divide by zero error. When we run this code we will get the error message shown in the screenshot below
When the error appears you can choose End or Debug
If you select End then the application simply stops.
If you select Debug the application stops on the error line as the screenshot below shows
This behaviour is fine when you are writing VBA code as it shows you the exact line with the error.
This behavior is unsuitable for an application that you are given to a user. These errors look unprofessional and they make the application look unstable.
An error like this is essentially the application crashing. The user cannot continue on without restarting the application. They may not use it at all until you fix the error for them.
By using On Error GoTo [label] we can give the user a more controlled error message. It also prevents the application stopping. We can get the application to perform in a predefined manner.
On Error Resume Next
Using On Error Resume Next tells VBA to ignore the error and continue on.
There are specific occasions when this is useful. Most of the time you should avoid using it.
If we add Resume Next to our example Sub then VBA will ignore the divide by zero error
' https://excelmacromastery.com/ Sub UsingResumeNext() On Error Resume Next Dim x As Long, y As Long x = 6 y = 6 / 0 x = 7 End Sub
It is not a good idea to do this. If you ignore the error, then the behavior can be unpredictable. The error can affect the application in multiple ways.You could end up with invalid data. The problem is that you aren’t aware that something went wrong because you have suppressed the error.
The code below is an example of where using Resume Next is valid
' https://excelmacromastery.com/ Sub SendMail() On Error Resume Next ' Requires Reference: ' Microsoft Outlook 15.0 Object Library Dim Outlook As Outlook.Application Set Outlook = New Outlook.Application If Outlook Is Nothing Then MsgBox "Cannot create Microsoft Outlook session." _ & " The email will not be sent." Exit Sub End If End Sub
In this code we are checking to see if Microsoft Outlook is available on a computer. All we want to know is if it is available or not. We are not interested in the specific error.
In the code above, we continue on if there is an error. Then in the next line we check the value of the Outlook variable. If there has been an error then the value of this variable will be set to Nothing.
This is an example of when Resume could be useful. The point is that even though we use Resume we are still checking for the error. The vast majority of the time you will not need to use Resume.
On Error GoTo [label]
This is how we use Error Handling in VBA. It is the equivalent of the Try and Catch functionality you see in languages such as C# and Java.
When an error occurs you send the error to a specific label. It is normally at the bottom of the sub.
Let’s apply this to the sub we have been using
' https://excelmacromastery.com/ Sub UsingGotoLine() On Error GoTo eh Dim x As Long, y As Long x = 6 y = 6 / 0 x = 7 Done: Exit Sub eh: MsgBox "The following error occurred: " & Err.Description End Sub
The screenshot below shows what happens when an error occurs
VBA jumps to the eh label because we specified this in the On Error Goto line.
Note 1: The label we use in the On…GoTo statement, must be in the current Sub/Function. If not you will get a compilation error.
Note 2: When an error occurs when using On Error GoTo [label], the error handling returns to the default behaviour i.e. The code will stop on the line with the error and display the error message. See the next section for more information about this.
On Error GoTo -1
This statement is different than the other three. It is used to clear the current error rather than setting a particular behaviour.
When an error occurs using On Error GoTo [label], the error handling behaviour returns to the default behaviour i.e. “On Error GoTo 0”. That means that if another error occurs the code will stop on the current line.
This behaviour only applies to the current sub. Once we exit the sub, the error will be cleared automatically.
Take a look at the code below. The first error will cause the code to jump to the eh label. The second error will stop on the line with the 1034 error.
' https://excelmacromastery.com/ Sub TwoErrors() On Error Goto eh ' generate "Type mismatch" error Error (13) Done: Exit Sub eh: ' generate "Application-defined" error Error (1034) End Sub
If we add further error handling it will not work as the error trap has not been cleared.
In the code below we have added the line
On Error Goto eh_other
after we catch the first error.
This has no effect as the error has not been cleared. In other words the code will stop on the line with the error and display the message.
' https://excelmacromastery.com/ Sub TwoErrors() On Error Goto eh ' generate "Type mismatch" error Error (13) Done: Exit Sub eh: On Error Goto eh_other ' generate "Application-defined" error Error (1034) Exit Sub eh_other: Debug.Print "eh_other " & Err.Description End Sub
To clear the error we use On Error GoTo -1. Think of it like setting a mouse trap. When the trap goes off you need to set it again.
In the code below we add this line and the second error will now cause the code to jump to the eh_other label
' https://excelmacromastery.com/ Sub TwoErrors() On Error Goto eh ' generate "Type mismatch" error Error (13) Done: Exit Sub eh: ' clear error On Error Goto -1 On Error Goto eh_other ' generate "Application-defined" error Error (1034) Exit Sub eh_other: Debug.Print "eh_other " & Err.Description End Sub
Note 1: There are probably rare cases where using On Error GoTo -1 is useful. In most cases using Resume Next is better as it clears the error and resumes the code at the next line after the error occurs.
Note 2: The Err Object has a member Clear. Using Clear clears the text and numbers in the Err object, but it does NOT reset the error.
Using On Error
As we have seen, VBA will do one of three things when an error occurs
- Stop and display the error.
- Ignore the error and continue on.
- Jump to a specific line.
VBA will always be set to one of these behaviors. When you use On Error, VBA will change to the behaviour you specify and forget about any previous behavior.
In the following Sub, VBA changes the error behaviour each time we use the On Error statement
' https://excelmacromastery.com/ Sub ErrorStates() Dim x As Long ' Go to eh label if error On Error Goto eh ' this will ignore the error on the following line On Error Resume Next x = 1 / 0 ' this will display an error message on the following line On Error Goto 0 x = 1 / 0 Done: Exit Sub eh: Debug.Print Err.Description End Sub
Resume Next
The Resume Next statement is used to clear the error and then resume the code from the line after where the error occurred.
If your code can have multiple errors and you want to keep detecting them then this line is very useful.
For example, in the following code we want to resume the code after the error has been reported:
Private Sub Main() On Error Goto eh Dim i As Long For i = 1 To 3 ' Generate type mismatch error Error 13 Next i done: Exit Sub eh: Debug.Print i, Err.Description End Sub
We could use On Error Goto -1 to clear the code and then use a goto statement to go back to the code like this:
Private Sub Main() On Error Goto eh Dim i As Long For i = 1 To 3 ' Generate type mismatch error Error 13 continue: Next i done: Exit Sub eh: Debug.Print i, Err.Description On Error Goto -1 ' clear the error Goto continue ' return to the code End Sub
The Resume Next provides a nicer way of doing it and it always means the code is much clearer and easier to understand:
Private Sub Main() On Error Goto eh Dim i As Long For i = 1 To 3 ' Generate type mismatch error Error 13 continue: Next i done: Exit Sub eh: Debug.Print i, Err.Description ' clear the error and return to the code Resume Next End Sub
The Err Object
When an error occurs you can view details of the error using the Err object.
When an runtime error occurs, VBA automatically fills the Err object with details.
The code below will print “Error Number: 13 Type Mismatch” which occurs when we try to place a string value in the long integer total
' https://excelmacromastery.com/ Sub UsingErr() On Error Goto eh Dim total As Long total = "aa" Done: Exit Sub eh: Debug.Print "Error number: " & Err.Number _ & " " & Err.Description End Sub
The Err.Description provides details of the error that occurs. This is the text you normally see when an error occurs e.g. “Type Mismatch”
The Err.Number is the ID number of the error e.g. the error number for “Type Mismatch” is 13. The only time you really need this is if you are checking that a specific error occurred and this is only necessary on rare occasions.
The Err.Source property seems like a great idea but it does not work for a VBA error. The source will return the project name, which hardly narrows down where the error occurred. However, if you create an error using Err.Raise you can set the source yourself and this can be very useful.
Getting the Line Number
The Erl function is used to return the line number where the error occurs.
It often causes confusion. In the following code, Erl will return zero
' https://excelmacromastery.com/ Sub UsingErr() On Error Goto eh Dim val As Long val = "aa" Done: Exit Sub eh: Debug.Print Erl End Sub
This is because there are no line numbers present. Most people don’t realise it but VBA allows you to have line numbers.
If we change the Sub above to have line number it will now print out 20
' https://excelmacromastery.com/ Sub UsingErr() 10 On Error Goto eh Dim val As Long 20 val = "aa" Done: 30 Exit Sub eh: 40 Debug.Print Erl End Sub
Adding line numbers to your code manually is cumbersome. However there are tools available that will allow you to easily add and remove line numbers to a sub.
When you are finished working on a project and hand it over to the user it can be useful to add line numbers at this point. If you use the error handling strategy in the last section of this post, then VBA will report the line where the error occurred.
Using Err.Raise
Err.Raise allows us to create errors. We can use it to create custom errors for our application which is very useful. It is the equivalent of the Throw statement in JavaC#.
The format is as follows
Err.Raise [error number], [error source], [error description]
Let’s look at a simple example. Imagine we want to ensure that a cell has an entry that has a length of 5 characters. We could have a specific message for this
' https://excelmacromastery.com/ Public Const ERROR_INVALID_DATA As Long = vbObjectError + 513 Sub ReadWorksheet() On Error Goto eh If Len(Sheet1.Range("A1")) <> 5 Then Err.Raise ERROR_INVALID_DATA, "ReadWorksheet" _ , "The value in the cell A1 must have exactly 5 characters." End If ' continue on if cell has valid data Dim id As String id = Sheet1.Range("A1") Done: Exit Sub eh: ' Err.Raise will send code to here MsgBox "Error found: " & Err.Description End Sub
When we create an error using Err.Raise we need to give it a number. We can use any number from 513 to 65535 for our error. We must use vbObjectError with the number e.g.
Err.Raise vbObjectError + 513
Using Err.Clear
Err.Clear is used to clear the text and numbers from the Err.Object. In other words, it clears the description and number.If you want the clear the actual error you can use either On Error GoTo -1 or Resume Next
It is rare that you will need to use Err.Clear but let’s have a look at an example where you might.
In the code below we are counting the number of errors that will occur. To keep it simple we are generating an error for each odd number.
We check the error number each time we go through the loop. If the number does not equal zero then an error has occurred. Once we count the error we need to set the error number back to zero so it is ready to check for the next error.
' https://excelmacromastery.com/ Sub UsingErrClear() Dim count As Long, i As Long ' Continue if error as we will check the error number On Error Resume Next For i = 0 To 9 ' generate error for every second one If i Mod 2 = 0 Then Error (13) ' Check for error If Err.Number <> 0 Then count = count + 1 Err.Clear ' Clear Err once it is counted End If Next Debug.Print "The number of errors was: " & count End Sub
Note 1: Err.Clear resets the text and numbers in the error object but it does not clear the error – see Resume Next Or On Error GoTo -1 for more information about clearing the actual error.
Logging
Logging means writing information from your application when it is running. When an error occurs you can write the details to a text file so you have a record of the error.
The code below shows a very simple logging procedure
' https://excelmacromastery.com/ Sub Logger(sType As String, sSource As String, sDetails As String) Dim sFilename As String sFilename = "C:templogging.txt" ' Archive file at certain size If FileLen(sFilename) > 20000 Then FileCopy sFilename _ , Replace(sFilename, ".txt", Format(Now, "ddmmyyyy hhmmss.txt")) Kill sFilename End If ' Open the file to write Dim filenumber As Variant filenumber = FreeFile Open sFilename For Append As #filenumber Print #filenumber, CStr(Now) & "," & sType & "," & sSource _ & "," & sDetails & "," & Application.UserName Close #filenumber End Sub
You can use it like this
' Create unique error number ' https://excelmacromastery.com/ Public Const ERROR_DATA_MISSING As Long = vbObjectError + 514 Sub CreateReport() On Error Goto eh If Sheet1.Range("A1") = "" Then Err.Raise ERROR_DATA_MISSING, "CreateReport", "Data is missing from Cell A1" End If ' other code here Done: Exit Sub eh: Logger "Error", Err.Source, Err.Description End Sub
The log is not only for recording errors. You can record other information as the application runs. When an error occurs you can then check the sequence of events before an error occurred.
Below is an example of logging. How you implement logging really depends on the nature of the application and how useful it will be:
' https://excelmacromastery.com/ Sub ReadingData() Logger "Information", "ReadingData()", "Starting to read data." Dim coll As New Collection ' add data to the collection coll.Add "Apple" coll.Add "Pear" If coll.Count < 3 Then Logger "Warning", "ReadingData()", "Number of data items is low." End If Logger "Information", "ReadingData()", "Number of data items is " & coll.Count Logger "Information", "ReadingData()", "Finished reading data." End Sub
Having a lot of information when dealing with an error can be very useful. Often the user may not give you accurate information about the error that occurred. By looking at the log you can get more accurate information about the information.
This section covers some of the other Error Handling tools that VBA has. These items are considered obsolete but I have included them as they may exist in legacy code.
Error Function
The Error Function is used to print the error description from a given error number. It is included in VBA for backward compatibility and is not needed because you can use the Err.Description instead.
Below are some examples:
' Print the text "Division by zero" Debug.Print Error(11) ' Print the text "Type mismatch" Debug.Print Error(13) ' Print the text "File not found" Debug.Print Error(53)
Error Statement
The Error statement allows you to simulate an error. It is included in VBA for backward compatibility. You should use Err.Raise instead.
In the following code we simulate a “Divide by zero” error.
' https://excelmacromastery.com/ Sub SimDivError() On Error Goto eh ' This will create a division by zero error Error 11 Exit Sub eh: Debug.Print Err.Number, Err.Description End Sub
This statement is included in VBA for backward compatibility. You should use Err.Raise instead.
A Simple Error Handling Strategy
With all the different options you may be confused about how to use error handling in VBA. In this section, I’m going to show you how to implement a simple error handling strategy that you can use in all your applications.
The Basic Implementation
This is a simple overview of our strategy
- Place the On Error GoTo Label line at the start of our topmost sub.
- Place the error handling Label at the end of our topmost sub.
- If an expected error occurs then handle it and continue.
- If the application cannot continue then use Err.Raise to jump to the error handling label.
- If an unexpected error occurs the code will automatically jump to the error handling label.
The following image shows an overview of how this looks
The following code shows a simple implementation of this strategy:
' https://excelmacromastery.com/ Public Const ERROR_NO_ACCOUNTS As Long = vbObjectError + 514 Sub BuildReport() On Error Goto eh ' If error in ReadAccounts then jump to error ReadAccounts ' Do something with the code Done: Exit Sub eh: ' All errors will jump to here MsgBox Err.Source & ": The following error occured " & Err.Description End Sub Sub ReadAccounts() ' EXPECTED ERROR - Can be handled by the code ' Application can handle A1 being zero If Sheet1.Range("A1") = 0 Then Sheet1.Range("A1") = 1 End If ' EXPECTED ERROR - cannot be handled by the code ' Application cannot continue if no accounts workbook If Dir("C:DocsAccount.xlsx") = "" Then Err.Raise ERROR_NO_ACCOUNTS, "UsingErr" _ , "There are no accounts present for this month." End If ' UNEXPECTED ERROR - cannot be handled by the code ' If cell B3 contains text we will get a type mismatch error Dim total As Long total = Sheet1.Range("B3") ' continue on and read accounts End Sub
This is a nice way of implementing error handling because
- We don’t need to add error handling code to every sub.
- If an error occurs then VBA exits the application gracefully.
A Complete Error Handling Strategy
The above strategy has one major drawback. It doesn’t provide any information about the error. It is better than having no strategy as it prevents the application crashing. But that is the only real benefit.
VBA doesn’t fill Err.Source with anything useful so we have to do this ourselves.
In this section, I am going to introduce a more complete error strategy. I have written two subs that perform all the heavy lifting so all you have to do is add them to your project.
The purpose of this strategy is to provide you with the Stack* and line number when an error exists.
*The Stack is the list of sub/functions that were currently in use when the error occurred.
This is our strategy
- Place error handling in all the subs.
- When an error occurs, the error handler adds details to the error and raises it again.
- When the error reaches the topmost sub it is displayed.
We are simply “bubbling” the error to the top. The following diagram shows a simple visual of what happens when an error occurs in Sub3
The only messy part to this is formatting the strings correctly. I have written two subs that handle this, so it is taken care of for you.
There are the two helper subs, RaiseError and DisplayError. You can download the library below:
An Example of using this strategy
Here is a simple coding example that uses these subs. In this strategy, we don’t place any code in the topmost sub. We only call subs from it.
' https://excelmacromastery.com/ Sub Topmost() On Error Goto EH Level1 Done: Exit Sub EH: DisplayError Err.source, Err.Description, "Module1.Topmost", Erl End Sub Sub Level1() On Error Goto EH Level2 Done: Exit Sub EH: RaiseError Err.Number, Err.source, "Module1.Level1", Err.Description, Erl End Sub Sub Level2() On Error Goto EH ' Error here Dim a As Long a = "7 / 0" Done: Exit Sub EH: RaiseError Err.Number, Err.source, "Module1.Level2", Err.Description, Erl End Sub
The result looks like this:
If your project has line numbers the result will include the line number of the error:
Error Handling in a Nutshell
- Error Handling is used to handle errors that occur when your application is running.
- You write specific code to handle expected errors. You use the VBA error handling statement On Error GoTo [label] to send VBA to a label when an unexpected error occurs.
- You can get details of the error from Err.Description.
- You can create your own error using Err.Raise.
- Using one On Error statement in the top most sub will catch all errors in subs that are called from here.
- If you want to record the name of the Sub with the error, you can update the error and rethrow it.
- You can use a log to record information about the application as it is running.
What’s Next?
Free VBA Tutorial If you are new to VBA or you want to sharpen your existing VBA skills then why not try out the The Ultimate VBA Tutorial.
Related Training: Get full access to the Excel VBA training webinars and all the tutorials.
(NOTE: Planning to build or manage a VBA Application? Learn how to build 10 Excel VBA applications from scratch.)