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