[AccessD] Form Controls

A.D.Tejpal adtp at airtelmail.in
Mon Oct 26 09:01:41 CDT 2009


Run time handling of form controls in the order of tab index.
========================================

    Use of a collection as suggested by J.C., appears to be the optimum 
approach, provided the point raised by Ken is addressed suitably. A form 
having three tab controls each with 4 pages, would need 15 collections as 
each form section or tab control page has its own set of tab indices for 
controls located therein.

    There could be an interesting way to handle this requirement 
conveniently by adoption of a single collection where each of its elements 
is itself a collection, permitting a generic subroutine to handle unlimited 
number of tab control pages apart from the three form sections (detail, 
header & footer)

    For convenient retrieval, one of the elements of this master collection 
could be a collection of object pointers to all sections and pages actually 
having tab indexed controls, thus serving as table of contents for primary 
containers.

    Sample code in form's module, demonstrating this approach, is given 
below. The collection at form level gets built up on loading the form. 
Thereafter, desired information can be retrieved from anywhere in the db, 
via either of the two public subroutines, named 
P_ListAllControlsByTabIndex() or P_ListControlsByTabIndexInSection() 
respectively. Some sample statements are given below (fm is an object 
pointer to the form in question):

' Sample statements for listing as per tab index
'=================================
    ' List all controls on all form sections as well as
    ' all pages of all tab controls as per tab index
    fm.P_ListAllControlsByTabIndex

    ' List all controls on Detail section as per tab index
    fm.P_ListControlsByTabIndexInSection _
                                        fm, fm.Section(0)

    ' List all controls on first page of given tab control
    ' as per tab index
    fm.P_ListControlsByTabIndexInSection _
                                fm, fm.MyTabControl.Pages(0)
'=================================

Best wishes,
A.D. Tejpal
------------

' Code in form's module
'===============================
' Declarations section

' It is a collection of collections
Private colCt As Collection
'-----------------------------------------------

Private Sub Form_Close()
    Set colCt = Nothing
End Sub
'-----------------------------------------------

Private Sub Form_Load()
    P_BuildControlColWholeForm Me
End Sub
'-----------------------------------------------

Public Sub P_BuildControlColWholeForm( _
                                fm As Access.Form)
    Dim Cnt As Long
    ' Initialize form level global collection
    ' It is a collection of collections
    Set colCt = New Collection

    ' Add a new collection element to above
    ' collection so as to serve as table of contents
    ' for all sections / pages holding independent
    ' set of tab indices for controls located there.
    colCt.Add New Collection, "TOC"

    ' While handling the form sections one by one,
    ' all pages of all tab controls located on the
    ' given section also get covered by recursive
    ' calls to P_BuildControlColForSection()
    For Cnt = 0 To 2
        P_BuildControlColForSection _
                        Me, Me.Section(Cnt)
    Next

    ' Note (Section Values):
    '   0 (acDetail) for detail
    '   1 (acHeader) for header
    '   2 (acFooter) for footer
End Sub
'-----------------------------------------------

Private Sub P_BuildControlColForSection( _
                fm As Access.Form, sc As Object)
    On Error Resume Next
    ' Builds a temp collection of controls keyed
    ' as per tab index and adds this collection to
    ' form level global collection colCt.
    ' sc represents either a form section or tab
    ' control page
    Dim ct As Access.Control
    Dim pg As Access.Page
    Dim colTemp As Collection
    Dim Idx  As Long, SKey As String
    Dim Cnt As Long

    ' Initialize temp collection of controls for this
    ' section or page (passed as argument sc)
    Set colTemp = New Collection

    Cnt = 0
    For Each ct In sc.Controls
        Err.Clear
        Idx = ct.TabIndex
        If Err.Number = 0 Then
            If sc.Parent Is fm Then
                ' sc is a form section. Cycle through
                ' all controls on this section
                ' (When the argument to this subroutine
                ' is a form section, all controls belonging
                ' to tab control pages are to be ignored as
                ' there is independent set of tab indices
                ' for each tab page).
                If ct.Parent Is fm Then
                    ' It is a control directly on the form
                    Cnt = Cnt + 1
                    colTemp.Add ct, CStr(Idx)

                    ' If it is a tab control, add the controls on
                    ' each of its pages as collection elements
                    ' in the main collection by recursive calls
                    ' to this procedure.
                    If ct.ControlType = acTabCtl Then
                        For Each pg In ct.Pages
                            P_BuildControlColForSection fm, pg
                        Next
                    End If
                End If
            Else
                ' sc is a tab control page
                Cnt = Cnt + 1
                colTemp.Add ct, CStr(Idx)
            End If
        End If
    Next

    If Cnt > 0 Then
        ' If it is a form section, the key is made up
        ' of section name.
        ' If it is a page, the key is made up of a
        ' combination of tab control & page names.
        If sc.Parent Is fm Then
            ' sc is a form section
            SKey = sc.Name
        Else
            ' sc is a page of tab control
            SKey = sc.Parent.Name & ":" & sc.Name
        End If

        ' Add the freshly built temp collection as an
        ' element in form level global collection colCt
        colCt.Add colTemp, SKey

        ' Add this section or page to TOC collection
        ' element (which is part of colCt collection)
        colCt("TOC").Add sc, _
                        CStr(colCt("TOC").Count + 1)
    End If

    ' Note:
    '   The parent for controls on tab control page is
    '   the relevant page. For all others it is the form.
    '   Section property for all controls on a given
    '   section is identical, (irrespective of the fact
    '   whether the control is located directly on the
    '   form or on a tab control page).

    Set ct = Nothing
    Set pg = Nothing
    Set colTemp = Nothing
    On Error GoTo 0
End Sub
'-----------------------------------------------

Public Sub P_ListAllControlsByTabIndex()
    Dim obj As Object

    For Each obj In colCt("TOC")
        P_ListControlsByTabIndexInSection Me, obj
    Next

    Set obj = Nothing
End Sub
'-----------------------------------------------

Public Sub P_ListControlsByTabIndexInSection( _
                    fm As Access.Form, sc As Object)
    On Error Resume Next
    ' Lists all controls located on form section or
    ' tab control page sc in the order of tab index.
    ' sc is an object pointer to the form section or
    ' tab control page.
    Dim Cnt As Long, Tot As Long
    Dim Hdg As String, SKey As String

    If sc.Parent Is fm Then
        ' sc is a form section. The key for sub-collection
        ' is made up of section name.
        SKey = sc.Name
        Tot = colCt(SKey).Count
        Hdg = "Section: " & SKey & _
                ": Tot Tab Indexed Controls = " & Tot
    Else
        ' sc is a page of tab control The key for sub-
        ' collection is made up of a combination of tab
        ' control & page names.
        SKey = sc.Parent.Name & ":" & sc.Name
        Tot = colCt(SKey).Count
        Hdg = "Page: " & SKey & _
                ": Tot Tab Indexed Controls = " & Tot
    End If

    If Err.Number = 0 And Tot > 0 Then
        Debug.Print Hdg
        For Cnt = 0 To Tot - 1
            Debug.Print colCt(SKey)(CStr(Cnt)).Name
        Next
    Else
        Debug.Print "No tab indexed controls " & _
                            "found in " & SKey
    End If

    On Error GoTo 0
End Sub
'===============================


----- Original Message ----- 
From: jwcolby
To: Access Developers discussion and problem solving
Sent: Saturday, October 24, 2009 06:18
Subject: Re: [AccessD] Form Controls

Well, the tab order only works for the section that the focus is in anyway,
so have three
collections, one for each section.

John W. Colby
www.ColbyConsulting.com
=====================================

Kenneth Ismert wrote:
> Hey, all:
>
> Charlotte Foust:
>> If you're talking about in design view, the controls follow the
>> order in which they were added, not the tab index, which
>> can be changed.
>
> That is right initially, but the rendering order determines the Controls
> collection order. Using the Bring to Front and Send to Back buttons in
> form
> design view changes the control order. This is how Access handles control
> overlap without a z-index property: controls later in the collection
> render
> on top of those before. I'm pretty sure of this.
>
> Tab indexes, on the other hand, get re-used by section and tab page. This
> means that if your form has header, footer  and detail sections, as well
> as
> a tab control with three pages, you could have 6 controls with a tab index
> of 1: one for each section and tab page.
>
> This means that any looping through controls by tab index has to be
> recursive. You must go by section, then any tab pages in that section.
>
> Of course, this complicates adding controls to a collection keyed by tab
> index. The straightforward way will work only for the simplest case: only
> a
> detail section with no tab pages. Otherwise, you will get duplicate tab
> indexes, and your item add won't work the way you expect.
>
> -Ken 




More information about the AccessD mailing list