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