DataBase - Enumerating controls
Asked By Kirk Wilson
07-Feb-10 11:52 AM

I found a code snippet in help that lists all controls on a tab control.
For Each ctlCurrent In tabCtl
Debug.Print ctlCurrent.Name
Next ctlCurrent
I modified the code to return a control by its index
For I = 0 To 15
Debug.Print tabCtl!ctlCurrent(I).Name
Next I
This creates a type mismatch runtime error
How do I correct this error? Full code listing follows:
frmMonth24 is the main form.
tabForm is a tabcontrol on frmMonth24
Public Function GetPageName()
Dim tabCtl As TabControl
Dim ctlCurrent As Control
Dim I As Integer
On Error GoTo ErrorHandler
' Return reference to tab control on Employees form.
Set tabCtl = Forms!frmMonth24!tabForm
' List all controls on the tab control in the Debug window.
' For Each ctlCurrent In tabCtl
' Debug.Print ctlCurrent.Name
' Next ctlCurrent
For I = 0 To 15
Debug.Print tabCtl!ctlCurrent(I).Name
Next I
Set tabCtl = Nothing
Set ctlCurrent = Nothing
ErrorHandler:
MsgBox "Error #: " & Err.Number & vbCrLf & vbCrLf & Err.Description
End Function
ListSubFormsOnTabControl
(1)
Access 2003
(1)
CtlOnPage.ControlType
(1)
EnumerateTabSubForms
(1)
IsSubFormOld
(1)
Debug.Print
(1)
CtlPage.Controls.Count
(1)
BolIsMainForm
(1)
Banana replied to Kirk Wilson
I believe the syntax ought to be:
Debug.Print tabCtl(I).Name
IOW, you do not need the ctlCurrent when you are accessing a collection by
its index/key unlike the For Each...
Kirk Wilson replied to Banana
Your modified code also creates a type mismatch runtime error.
David W. Fenton replied to Kirk Wilson

I do not understand your code.
A tab control has no controls collection and it has no default
collection, either, so I cannot see how any of your code ever worked.
This code:
For Each ctlCurrent In tabCtl
Debug.Print ctlCurrent.Name
Next ctlCurrent
...would have to have been:
Dim ctlPage as Control
Dim ctlCurrent As Control
For Each ctlPage In Forms!frmMonth24!tabForm.Pages
For Each ctlCurrent In ctlPage.Controls
Debug.Print ctlCurrent.Name
Next ctlCurrent
Next ctlPage
Set ctlCurrent = Nothing
Set ctlPage = Nothing
There is really no need to navigate by index unless you have keyed
control names to their index number (which is inadvisable in most
cases, but not completely out of bounds). In that case, you would do
this:
Dim ctlPage as Control
Dim i As Integer
For Each ctlPage In Forms!frmMonth24!tabForm.Pages
For i = 0 To ctlPage.Controls.Count - 1
Debug.Print ctlPage.Controls(i).Name
Next ctlCurrent
Next ctlPage
Set ctlPage = Nothing
But as you can see, it is actually more efficient to use the object
control instead of the index.
--
David W. Fenton http://www.dfenton.com/
usenet at dfenton dot com http://www.dfenton.com/DFA/
Kirk Wilson replied to David W. Fenton
I appreciate your reply but you have missed my point. I do not know the
subform name in advance. I need to programatically determine the subform
name so that I can determine it is record source to build an SQL statement
to populate the subform at runtime with different where clauses depending
on the conditions at run time. A tab control may not have a controls
collection but it does have pages and on those pages are controls
(subforms) with properties. I needed a general purpose procedure to run
on many tab controls with many subforms to determine those properties
during execution. The reason to navigate by index is to determine the
subform name for a particular but changing tabcontrol. Once the subform
name is determined then I can refer to the properties explicitly. IT
looks like your last snippet is what I need. I hope it works.
Thanks for the help Kirk
Dirk Goldgar replied to David W. Fenton
Oddly enough, the original code does work, at least in Access 2003; I
tested it. I do not know why. I cannot figure out what collection the For
Each is iterating through.
--
Dirk Goldgar, MS Access MVP
Access tips: www.datagnostics.com/tips.html
(please reply to the newsgroup)
Banana replied to Dirk Goldgar
Same here. I actually never knew that it could be done until OP
mentioned that he cited from a help file. Unforunately, help file on
TabControl collection (yes, a collection, not a control. At least if the
help file is to be believed) was quite terse and cryptic. However, while
it does enumerate controls on a tab, it also enumerates pages as well so...
As for the OP's question about using For...Next, I am not sure what else
to suggest since the syntax I suggested should have worked neither could
I find an explicit collection within the tab control. I'd probably use
nested loops over the pages then its controls collection if only because
it is better documented and will not get pages enumerated which I do not
think you want that anyway.
David W. Fenton replied to Dirk Goldgar
I could not get it to work in A2003. I would have written a different
post if I had (I would have suggested explicitly using the Pages
collection instead of doing it implicitly).
--
David W. Fenton http://www.dfenton.com/
usenet at dfenton dot com http://www.dfenton.com/DFA/
David W. Fenton replied to Kirk Wilson

My post was not intended to address that in any way. I was just
addressing the fact that the code you provided for navigating a tab
control could not possibly work.
(though it seems to work for Dirk, I could not get it to work)
No, you do not need to use an index for that.
Public Sub ListSubFormsOnTabControl(frm As Form)
Dim ctl As Control
Dim ctlPage As Control
Dim ctlOnPage As Control
For Each ctl In frm.Controls
Select Case ctl.ControlType
Case acTabCtl
For Each ctlPage In ctl.Pages
For Each ctlOnPage In ctlPage.Controls
Select Case ctlOnPage.ControlType
Case acSubForm
Debug.Print ctlOnPage.Name
End Select
Next ctlOnPage
Next ctlPage
Set ctlPage= Nothing
End Select
Next ctl
Set ctl = Nothing
End Sub
Indeed, in a lot of cases where you might try to use a counter, it is
actually simpler to use a variant. Where you might have this (where
col is some collection):
For i = 0 To col.Count
Debug.Print col(i).Name
Next i
...can be replaced with this:
For Each varItem In col
Debug.Print col(varItem).Name
Next i
You save setting up the range of the counter.
The ListSubFormsOnTabControl() sub above does exactly what you asked
for without using any counters at all.
--
David W. Fenton http://www.dfenton.com/
usenet at dfenton dot com http://www.dfenton.com/DFA/
David W. Fenton replied to Dirk Goldgar

OK, I see why I could not get it to work -- I did not realize there
was a dedicated TabControl object type and was defining my tab as a
regular control. This code works, and is much simpler than the other
code I posted earlier:
Public Sub EnumerateTabSubForms(ctlTab As TabControl)
Dim ctl As Control
For Each ctl In ctlTab
If ctl.ControlType = acSubform Then
Debug.Print ctl.Name
End If
Next ctl
End Sub
That's pretty simple. I have never needed to enumerate the controls on
a tab control, but this would be handy if I did.
My big annoyance about the relationship of tab controls and their
controls is that the parent of a control on a tab control is the TAB
PAGE. This causes issues when I want to know if a form is loaded as
a subform -- I have a few forms that are loaded normally but also as
subforms and while I could check if the form is in the Forms
collection, that would break if the form happened to be open on its
own while it is also loaded as a subform.
Oops. I see I have already solved that issue -- here is my old
IsSubForm() function:
Public Function IsSubFormOld(frm As Form) As Boolean
On Error GoTo errHandler
IsSubFormOld = Len(frm.Parent.Name) > 0
exitRoutine:
Exit Function
errHandler:
Select Case err.Number
Case Is <> 2452
MsgBox err.Number & ": " & err.Description, vbExclamation, _
End Select
Resume exitRoutine
End Function
I also note that there is no problem if the parent is a tab page or
not -- I am obviously misremembering where this was an issue!
I replaced that with this:
Public Function IsSubForm(frm As Form) As Boolean
On Error GoTo errHandler
Dim frmLoop As Form
Dim bolIsMainForm As Boolean
For Each frmLoop In Forms
If frmLoop.Name = frm.Name Then
If frmLoop.hWnd = frm.hWnd Then
bolIsMainForm = True
Exit For
End If
End If
Next frmLoop
Set frmLoop = Nothing
IsSubForm = Not bolIsMainForm
exitRoutine:
Exit Function
errHandler:
MsgBox err.Number & ": " & err.Description, vbExclamation, _
Resume exitRoutine
End Function
That takes care of my earlier objection, because it compares the
window handles (I forgot that I'd written this code!).
Anyway, the place where the parent issue is a problem is when I need
to know the parent form of a control. I have this very ugly line in
one of my apps:
Set frm = ctl.Parent.Parent.Parent
Ack. That makes my teeth hurt. It is, fortunately, used in a
situation where I know for sure that the control it is acting on is
on a tab control, so there is no danger of it breaking. But I
hesitate to think how awful it would be if the control were on a
subform that was on a tab. I think it would be:
Set frm = ctl.Parent.Parent.Parent.Parent.Parent.Parent

Roger Jennings on Access / Sharepoint DataBase http: / / www.quepublishing.com / articles / article.aspx?p = 1606238 I was very dismayed is it makes it pretty clear that in-house hosting of your Sharepoint server with Access Services to support browser-based Access apps is something only large companies will be able to afford, because the pricing and licensing for the Enterprise version is very, very steep. The alternative is hosted Sharepoint / Access Services, and the costs do not seem terribly high. It seems to me that the pricing is upside-down. Big enterprises do not want to deploy Access apps in the browser - - they will build their own .NET apps, browser-based or not 2010, it could vastly increase those costs for organizations with legacy hardware). The features of Access 2010 used in conjunction with Sharepoint 2010 seem to me to be most compelling for and small businesses. I do not know if I could sell clients on hosted Sharepoint / Access. I have been able to sell clients on hosted Exchange, and it is been very W. Fenton http: / / www.dfenton.com / contact via website only http: / / www.dfenton.com / DFA / Access Discussions SQL Express (1) SQL Server (1) MySQL (1) Exchange Server (1) Windows Server (1
Access 2010 for software development DataBase Hi, What do I need to use Access 2010 (or perhaps 2007) to port our 2003 application and create an executable (MDE in Access 2003)? Are there any issues with 2010? -paulw Access Discussions SQL Server (1) SharePoint (1) Albert D. Kallal (1) Office 2007 (1) Office 2003 (1) Access 2007 (1) Access 2010 (1) Access 2003 (1) You can use Access 2010 to develop
Considerations migrating from Access 97 mdb to Access 2003 (or up)? DataBase What are the things I need to watch for? I know about sheet properties and Sandboxing mode and making sure to run Jet 4.0 SP8 for 2003 but what else should I look for? We're kind of at the end of the road (so it seems) with Access 97. It does not play well with Windows 7 Professional even in XP Mode, the is crashy / unsreponsive at times. I figure moving up to a more 'modern' version of Access can help alleviate some of these problems and allow it to run native in Windows XP mode. So I am all ears for recommendations on migration or ways to get Access 97 to work properly in Win 7. Thanks a bunch. Access Discussions Visual Studio .NET (1) Windows XP (1) Office 2007 (1) Access 2007 (1) Access
more confused I get. Looking forward to getting a new toy though! Cheers The Frog Access Discussions Larry Linson Microsoft Office Access MVP Co author Microsoft Access (1) James A. Fortune CDMAPoster (1) Visual Studio 2010 (1) Entity Framework (1) Microsoft Excel 1) Microsoft Word (1) Office 2010 (1) Access 2007 (1) No. There is a free Access 2007 / 2010 runtime you can download and distribute. Reuse. Still works. Mind you not for the web version of Access 2010 which only has macros. Tony - - Tony Toews, Microsoft Access MVP Tony's Main MS Access pages - http: / / www.granite.ab.ca / accsmstr.htm Tony's Microsoft Access Blog - http: / / msmvps
Might be outgrowing Access but daunted by SQL Server DataBase I am close to completing the consolidation of various small Access databases and a couple of Excel spreadsheets that my little company uses (5 staff) into an all encompasing Access database and I was planning on splitting the database when I was finished to allow more and more obvious to me that I am going to need to give staff access to this new database from remote locations (outside of our office network). Two staff members out. It all started when I came across a very encouraging article on keeping your Access database as your front end application and linking to SQL Server database tables. I am more complicated than I had hoped. Can anyone suggest a simpler way of achieving remote access to my database? I have at my disposal a Network Storage Device which has remote access capabilities (this is where the database is currently stored), our website which it could be no IT guru by any stretch so please bare this in mind with any suggestions. Access Discussions SQL Server Migration Assistant (1) SQL Server 2005 (1) SQL Server 2008 (1) SQL