How to Safely Disable Controls in Microsoft Access
I *never* set the Enabled property of a form control directly. Instead, I use a convenience function so that I don't have to worry about run-time error 2164.
You cannot disable an active control.*
If you try to disable the active control, you will get run-time error 2164, "You can't disable a control while it has the focus."
To avoid the error, set the focus to a different control first.
For a general solution to this problem, you can use my DefocusIfActive function.
Better yet, let's call a convenience function instead of setting the .Enabled
property.
Rather than this...
Me.tbMyTextbox.Enabled = IsEnabled
...use this...
SetCtlEnabled Me.tbMyTextbox, IsEnabled
The Code: SetCtlEnabled
The SetCtlEnabled routine wraps the DefocusIfActive procedure so that we avoid run-time error 2164, "You can't disable a control while it has the focus."
'----------------------------------------------------------------------------
' Procedure : SetCtlEnabled
' Author : Mike Wolfe
' Source : https://nolongerset.com/setctlenabled/
' Purpose : Safely sets the Enabled property of a form control.
' Params - Ctl: The control whose Enabled property is being set.
' - Enabled: A boolean to indicate whether the control
' should be enabled or not.
' - FallbackCtl: The control to receive focus if the original
' Ctl has focus and is being disabled.
' Notes : If FallbackCtl is not provided, the function will cycle through
' the form's controls collection looking for a suitable
' recipient of the focus.
'----------------------------------------------------------------------------
Sub SetCtlEnabled(Ctl As Control, Enabled As Boolean, _
Optional FallbackCtl As Control)
If Enabled Then
'It's always safe to enable a control
Ctl.Enabled = True
Else
'https://nolongerset.com/defocusifactive/
DefocusIfActive Ctl, FallbackCtl
Ctl.Enabled = False
End If
End Sub
*UPDATE: Behavior Change
According to this article from Access MVP Colin Riddington, Microsoft quietly changed this behavior (emphasis mine):
For as long as I can remember, I’ve always moved the focus to another control in order to disable the first control. This had always seemed completely logical to me.
However a recent comment by pdanes in this thread at Access World Forums : Disable ALL controls on form led me to re-check this behaviour.
I can confirm that although that had to be done up to Access 2007, from Access 2010 onwards, it is no longer necessary to move the focus before disabling a control.
That said, I don't think I'll be changing my ways any time soon. It's not clear to me where exactly the focus goes under the new behavior, so I'll stick with the code I know.
Additional reading
Cover image created with Microsoft Designer