ACC: Screen.ActiveForm Returns Main Form, Not Subform

Last reviewed: August 28, 1997
Article ID: Q139040
The information in this article applies to:
  • Microsoft Access versions 2.0, 7.0, 97

SYMPTOMS

Advanced: Requires expert coding, interoperability, and multiuser skills.

If the currently active control on the screen is in a subform, Screen.ActiveControl will correctly reference this control. Screen.ActiveForm, however, will reference the main form and not the subform the control is contained on.

CAUSE

A subform is not really a form, but a control (just like a text box or command button) that appears on a form. Screen.ActiveForm will always return the active form, not a subform control.

RESOLUTION

You can use the Set_Screen_ActiveSubformControl function provided below to determine what subform control contains the Screen.ActiveControl. This function will set a global control variable Screen_ActiveSubformControl to the currently active subform control on screen.

   Syntax:

      Function Set_Screen_ActiveSubformControl()

   Return:

      True:  Screen_ActiveSubformControl was set to the subform control
             that contains Screen.ActiveControl.
      False: Screen.ActiveControl does not exist or is not in a subform.

MORE INFORMATION

The following information describes how to create a module with the Set_Screen_ActiveSubformControl() function. Further, information is provided demonstrating how to use this function using the sample database Northwind.mdb (or NWIND.MDB in 2.0).

This article assumes that you are familiar with Visual Basic for Applications and with creating Microsoft Access applications using the programming tools provided with Microsoft Access. For more information about Visual Basic for Applications, please refer to your version of the "Building Applications with Microsoft Access" manual.

NOTE: Visual Basic for Applications is called Access Basic in Microsoft Access version 2.0. For more information about Access Basic, please refer to the "Building Applications" manual.

NOTE: In the following sample code, an underscore (_) at the end of a line is used as a line-continuation character. Remove the underscore from the end of the line when re-creating this code in Access Basic.

  1. Create a module and type the following lines in the Declarations section if they are not already there:

          Option Explicit
          Dim Screen_ActiveSubformControl As Control
    

  2. Type the following two procedures:

          Function Set_Screen_ActiveSubformControl()
    
             Dim frmActive As Form, ctlActive As Control
             Dim hWndParent As Long
    
             ' Clear the control variable.
             Set Screen_ActiveSubformControl = Nothing
    
             ' Assume a subform is not active.
             Set_Screen_ActiveSubformControl = False
    
             ' Get the active form and control.
             On Error Resume Next
             Set frmActive = Screen.ActiveForm
             Set ctlActive = Screen.ActiveControl
             If Err <> 0 Then Exit Function
    
             ' Get the unique window handle identifying the form
             ' .. the active control is on.
             hWndParent = ctlActive.Parent.Properties("hWnd")
    
             ' If the active form window handle is the same as the window
             ' handle of the form the active control is on, then we are on the
             ' mainform, so exit.
             If hWndParent = frmActive.hWnd Then Exit Function
    
             ' Find a subform control that has a window handle matching the
             ' .. window handle of the form the active control is on.
             Set_Screen_ActiveSubformControl = FindSubform(frmActive, _
                 hWndParent)
    
          End Function
    
          Function FindSubform(frmSearch As Form, hWndFind As Long)
             Dim i As Integer
             On Error GoTo Err_FindSubForm
    
             ' Assume we will find a subform control with a window
             ' .. handle matching hWndFind.
             FindSubform = True
    
             ' Visit each control on the form frmSearch.
             For i = 0 To frmSearch.Count - 1
                ' If the control is a subform control...
                If TypeOf frmSearch(i) Is SubForm Then
                   ' .. does the window handle match the one we are looking
                   ' for?
                If frmSearch(i).Form.hWnd = hWndFind Then
                   ' We found it! Set the global control variable and exit.
                   Set Screen_ActiveSubformControl = frmSearch(i)
                   Exit Function
                Else
                   ' Otherwise, search this subform control (recursively)
                   ' .. to see if it contains a sub-subform control
                   ' .. with a window handle matching the one we are
                   ' .. interested in.
    
                   ' If we found a subform control, then exit.
                   If FindSubform(frmSearch(i).Form, hWndFind) Then
                      Exit Function
                   End If
                End If
             End If
          Next i
    
          Bye_FindSubform:
          ' If we didn't exit the function earlier, then there is no
          ' .. subform or sub-subform control on this form that has a window
          ' .. handle matching the one we are interested in, so return false.
          FindSubform = False
          Exit Function
    
          Err_FindSubForm:
             MsgBox Error$, 16, "FindSubform"
             Resume Bye_FindSubform
          End Function
    
    

How To Use the Set_Screen_ActiveSubformControl() Function

The following information demonstrates how to use the Set_Screen_ActiveSubformControl() function using the sample database Northwind.mdb (or NWIND.MDB in 2.0).

  1. Open the sample database Northwind.mdb and follow the steps above to create the module containing the Set_Screen_ActiveSubformControl procedure.

  2. Create a new macro called AutoKeys as followed:

          Macro Name   Action
          -------------------
          {F2}         RunCode
    
          AutoKeys Actions
          --------------------------------------------
          RunCode
             Function Name: =DisplayActiveSubformName()
    
    

  3. Add the following function to the module created in step 1:

          Function DisplayActiveSubformName()
    
             Dim Msg As String
             Dim CR As String
             CR = Chr$(13)  ' Carriage Return.
    
             If Set_Screen_ActiveSubformControl() = False Then
                Msg = "There is no active subform!"
             Else
                Msg = "Active Form Name = " & Screen.ActiveForm.Name
                Msg = Msg & CR
                Msg = Msg & "Active ControlName = " & Screen.ActiveControl.Name
                Msg = Msg & CR
                Msg = Msg & "Active Subform ControlName = "
                Msg = Msg & Screen_ActiveSubformControl.Name
                Msg = Msg & CR
                Msg = Msg & "Active Subform Form Name = "
                Msg = Msg & Screen_ActiveSubformControl.Form.Name
             End If
    
             MsgBox Msg
    
          End Function
    
    

  4. Open the Customers form in Design view and press F11 to activate the Database window.

  5. Drag the Orders form from the Database window to the bottom of the Customers form to create a subform control. This will enable you to test the function on a subform and a sub-subform.

  6. Select the new subform control and set the following properties:

          Name: Testing 123
          SourceObject: Orders
    

  7. View the Customers form in Form view. Note that the Orders subform contains only orders for the current customer.

  8. Set the focus to a control in the Customers form, the Orders form (subform), or the Orders Subform (sub-subform) and press the F2 key.
Keywords          : kbusage SynFnc FmsHowTo
Version           : 2.0 7.0 97
Platform          : WINDOWS
Hardware          : x86
Issue type        : kbprb
Solution Type     : kbcode


================================================================================


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: August 28, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.