Tips Index

Microsoft Access Tips and Tricks

What Object Has the Focus?

Most often when you are writing code for an Access application, you know what object -- control, form, report, etc. -- that code is concerned with. For example, if you are writing an event procedure, you know what object raised the event. But sometimes this is not the case. If you are writing a general-purpose routine, you may not know in what context that routine will be called, what form or control triggered it, or what the user was doing when it happened. Nevertheless, there are various ways to find out. This article will list a variety of them.


Screen.ActiveXXXXX

There are some properties of the Screen object that return object references to active objects:

  • Screen.ActiveControl - returns a reference to the control that has the focus (if there is one)
  • Screen.ActiveForm - returns a reference to the form that has the focus (if there is one and it's not a popup form)
  • Screen.ActiveReport - returns a reference to the report that has the focus (if there is one and it's not a popup report)
  • Screen.ActiveDatasheet - returns a reference to the table or query datasheet that has the focus (if there is one)

In addition, the Screen object provides a means to refer to the object that *previously* had the focus:

  • Screen.PreviousControl - returns a reference to the control that last had the focus, before Screen.ActiveControl received the focus

All of those properties will raise an error if there is no such object. There's a difficulty with the ActiveDatasheet property, in that it's not easy to tell whether the datasheet is a query datasheet or a table datasheet (though you can figure it out from the TypeName of the object). Also, ActiveDatasheet won't tell you about a query or table that is open in design view.


Application.CurrentObjectName

There are also a couple of properties of the Application object that can come in handy. I believe they have existed since at least Access 97. These properties are:

  • Application.CurrentObjectName - the name of the currently active object, whether it's open or not, even if it's just selected in the database window
  • Application.CurrentObjectType - the type (numeric, from the AcObjectType enumeration; e.g., acTable = 0, acQuery = 1, acForm = 2, etc.) of the current object.

These properties will give you the name and type of the object that Access thinks is active. However, they don't tell you whether the current object is open, or what view it's in. For that, you can use SysCmd acSysCmdGetObjectState, or check the IsLoaded property of the appropriate AccessObject via CurrentProject.AllXXXXX (AllForms, AllReports, and others)) or CurrentData.AllXXXXX (AllTables, AllQueries, and others).

The example below appears in the help file for Access 2003. You can see how it uses CurrentObjectName and SysCmd to check the state of a particular form:

The following example uses the CurrentObjectType and CurrentObjectName properties with the SysCmd function to determine if the active object is the Products form and if this form is open and has been changed but not saved. If these conditions are true, the form is saved and then closed.
Public Sub CheckProducts()
    
    Dim intState As Integer
    Dim intCurrentType As Integer
    Dim strCurrentName As String

    intCurrentType = Application.CurrentObjectType
    strCurrentName = Application.CurrentObjectName
    
    If intCurrentType = acForm And strCurrentName = "Products" Then
        intState = SysCmd(acSysCmdGetObjectState, intCurrentType, _
                   strCurrentName)
             
        ' Products form changed but not saved.
        If intState = acObjStateDirty + acObjStateOpen Then
            
            ' Close Products form and save changes.
            DoCmd.Close intCurrentType, strCurrentName, acSaveYes
        End If
    End If

End Sub

Application.CodeContextObject

Another useful property, especially in error-logging, the CodeContextObject property of the Application object. This property returns a reference to the object from which the currently executing macro or VBA procedure was called. This may or may not be the active object. For example, for code running in the Timer event of a hidden form, CodeContextObject would return a reference to that form, even though some other object has the focus.

CodeContextObject becomes very useful for debugging a utility procedure that may be called from a variety of objects, because it allows you to determine exactly which object called the procedure.

Relevance: Microsoft Access
Versions: Access 97 to 2007
Categories: VBA, How To, Forms
Date: 14 October 2008

Tips Index