I have sample code below that does work. However, in my case most of
my controls are NOT control arrays, so this code is very slow because
it assumes the exception, which we all know is not efficient.
Is there ANY WAY to check for a ControlArray?? Does VB have anything
like a "IsControlArray" method or something similiar??
The code I have that works is below, but I would really appreciate
something that works much more efficiently (and reads a little clearer)!
- Ben Hadden
ben_h...@hotmail.com
Dim Index as Integer
For Each Control in Form.Controls
'This will raise error if it is not a control array.
'this error is handled in error handling and Index set to -1.
Index = Control.Index
'Index of 0 or greater means we have a control array, so skip code.
'Index of -1 assumes we do not have control array, so run code.
If Index < 0 then
<<Code that we run when we know we do NOT have a control array>>
End If
Next Control
Err_Handling:
Select Case Err.Number
Case 343
Index = -1
Resume Next
Case Else
'Do Error Handling
End Select
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
Perhaps this would help:
Use the Count property of the controls collection, if you for example have
a textbox named txtinput use txtinput.count
Regards
/Richard
ben_h...@hotmail.com skrev i meddelandet <7q4gte$dvi$1...@nnrp1.deja.com>...
>I have sample code below that does work. However, in my case most of
>my controls are NOT control arrays, so this code is very slow because
>it assumes the exception, which we all know is not efficient.
I doubt very much that you would notice the performance difference (if any).
>Is there ANY WAY to check for a ControlArray
IMO, checking for the Index property is just as good as any other.
Doug.
> Use the Count property of the controls collection, if you for example have
>a textbox named txtinput use txtinput.count
Count property only works on Indexed controls -- controls that don't have an
Index property do not support the count property.
Doug.
>> Is there ANY WAY to check for a ControlArray?? Does VB have anything
>> like a "IsControlArray" method or something similiar??
>..he he.. /\/\/\/\/\/\/\/\/\/\ .......IsArray( )
> | | | | | | | | | | |
AFIK, this does not work on controls, only on variables. Could you post
some working code that demonstrates using this on controls?
Doug.
(note: it is not essential to loop through
every control like this example...duh)
Anyway....here ya go.....
put some controls that are arrays and
controls that are not on a form. Then
place one textbox ....call it textbox1
with no index (for this example to work)
set Text1.multiline = true
Then run this code.
Option Explicit
Private Const IsNotControlArray = 343
Private Sub Form_Load()
Dim x As Control
On Error GoTo ERRORTRAP:
For Each x In Controls
If x.Index >= 0 Then
Text1.Text = Text1.Text _
& x.Name & "(" & x.Index & ") is an array." & vbCrLf
Else
NotArray:
Text1.Text = Text1.Text _
& x.Name & " " & "is NOT an array." & vbCrLf
End If
Next
Exit Sub
ERRORTRAP:
Select Case Err
Case IsNotControlArray
Resume NotArray:
Case Else
MsgBox Str$(Err.Number) & " - " & Err.Description
End Select
End Sub
Rick
Bill McCarthy <bil...@gsat.edu.au> wrote in message
news:um9VgHK8#GA.263@cppssbbsa03...
> Actually you can try the "TypeOf IS" statement or the typename function.
> eg.
>
> If TypeName(Label1) = "Object" Then
> Debug.Print "is a control array"
> End If
>
>
>
> Eg If
> Timothy Kessler <Tak...@RocketMail.Com> wrote in message
> news:01bee91f$55fc2b00$9a98...@kih.net...
Public Function AddControl(cntr As Variant, Caption As String)
Dim cnt As Long
If TypeName(cntr) = "Object" Then
cnt = cntr.UBound + 1
Load cntr(cnt)
cntr(cnt).Top = cntr(cnt - 1).Top + cntr(cnt).Height
cntr(cnt).Caption = Caption
cntr(cnt).Visible = True
Else
AddControl = 0
End If
End Function
Rick Rothstein пишет в сообщении <#yUJwhK8#GA...@cppssbbsa02.microsoft.com>
...
Perhaps I wasn't as clear as I could have been in my post. IF you use the
Control's Name *directly*, or set a variable to that Control Name and then
use it, then yes TypeName will distinguish between a Control Array and a
Non-Control Array. The problem is if you know the Name you are passing, then
you (as the programmer) already know if it is a Control Array or not -- no
knowledge was gained. In practical use, the user gives focus to a control
and the question is - is it part of a Control Array or not? This TypeName
can't distinguish for you.
The easiest way to see this is to put a Control Array of components on a
form along with a Non-Control-Array component and run through the form's
Controls collection. If you run through all the components, TypeName does
not see the Control Array -- only the individual elements of the Control
Array.
The challenge if you are still skeptical is this:
Given the following
For Each ControlItem in Controls
If ???(ControlItem.???) = "Object" Then
Debug.Print "Control Array"
Else
Debug.Print "Nope"
End If
Next
tell me what function (TypeName or other) and what Property you would put in
for the ???'s in order to have "Control Array" printed out (given that a
Control Array of components exists on the Form).
The point is -- if you don't use the actual Control Name either directly or
through a proxy variable, then you can't tell me if a component is part of a
Control Array or not UNLESS you use an On Error routine.
Rick
Rick Rothstein <fnr...@aosi.com> wrote in message
news:#yUJwhK8#GA...@cppssbbsa02.microsoft.com...
> That only works if you use the actual control name (Label1 in your
example)
> in the TypeName function. However, if you try and reference the control
via
> a passed argument into a function call or via a variable while looping
> through the Controls collection, you lose the ability to use TypeName to
> test this way. I find this surprising but accepted it quite a while ago
when
> I made this identical argument in response to a similar post 6 or so
months
> ago.
>
> Rick
>
> Bill McCarthy <bil...@gsat.edu.au> wrote in message
> news:um9VgHK8#GA.263@cppssbbsa03...
> > Actually you can try the "TypeOf IS" statement or the typename
function.
> > eg.
> >
> > If TypeName(Label1) = "Object" Then
> > Debug.Print "is a control array"
> > End If
> >
> >
> >
Dim cntlCntrl As Control
For Each cntlCntrl In Controls
Debug.Print TypeName(Controls(cntlCntrl.Name))
Next
Rick Rothstein <fnr...@aosi.com> wrote in message
news:#yUJwhK8#GA...@cppssbbsa02.microsoft.com...
> That only works if you use the actual control name (Label1 in your
example)
> in the TypeName function. However, if you try and reference the control
via
> a passed argument into a function call or via a variable while looping
> through the Controls collection, you lose the ability to use TypeName to
> test this way. I find this surprising but accepted it quite a while ago
when
> I made this identical argument in response to a similar post 6 or so
months
> ago.
>
> Rick
>
> Bill McCarthy <bil...@gsat.edu.au> wrote in message
> news:um9VgHK8#GA.263@cppssbbsa03...
Well if you , as the programmer can identify the control purely by it's
name, just use it's .Name property.
In practice though, this would probably require an extensive Select Case
statement or a dictionary to work it out. By way do that if the Control
collection can tell you. As per my previous post Control(cntlThingy.Name)
returns a refernce to the control on which you can use TypeName.
> The easiest way to see this is to put a Control Array of components on a
> form along with a Non-Control-Array component and run through the form's
> Controls collection. If you run through all the components, TypeName does
> not see the Control Array -- only the individual elements of the Control
> Array.
>
> The challenge if you are still skeptical is this:
>
> Given the following
>
> For Each ControlItem in Controls
> If ???(ControlItem.???) = "Object" Then
> Debug.Print "Control Array"
> Else
> Debug.Print "Nope"
> End If
> Next
>
> tell me what function (TypeName or other) and what Property you would put
in
> for the ???'s in order to have "Control Array" printed out (given that a
> Control Array of components exists on the Form).
>
For Each ControlItem in Controls
If TypeName(Controls(ControlItem.Name)) = "Object" Then
Bill McCarthy пишет в сообщении ...
For Each ControlItem in Controls
If ??? Then
Debug.Print "Control Array"
Else
Debug.Print "Nope"
End If
Next
Tell me what logical expression to put in place of the ??? so that the If
statement evaluates as true (and the words "Control Array" are printed in
the Immediate Window). Don't make a guess and post that -- try it out inside
of VB. You will be surprised to find that no expression can be found. (Yes,
some elaborate Select-Case structure could be created, but let's assume your
Form has a thousand controls on it and you don't fell like trying that
approach.)
That's my challenge. Post back a logical expression (using the ControlItem
variable) that I can paste into my VB that prints "Control Array" in this
general case. (And remember, we are trying to rule out the use of an
On-Error trap to accomplish this.)
Rick
P.S. -- I'm not familiar with Control(cntlThingy.Name); is this supposed to
be a Collection you have created within your program? If so, remember, I
proposed that there are a thousand controls on your Form so manually forming
a Collection (via typing) is out. We are looking for a "general" solution,
not one based on knowing the facts before hand -- this is an event driven
world and the user is in control, not the programmer. I believe these
conditions would force you to find a solution in keeping with the intent of
the original post.
Bill McCarthy <bil...@gsat.edu.au> wrote in message
news:uMfaYuQ8#GA.224@cppssbbsa03...
Try it again, and see what you get:
For Each ControlItem In Controls
If TypeName(Controls(ControlItem.Name)) = "Object" Then
Debug.Print "Control Array"
Else
Debug.Print "Nope"
End If
Next
P.S. That bit about Control(cntlThingy.Name) was a typo, (actually the
whole sentence/paragraph was full of typos), it should have read
Controls(cntlThingy.Name).
Note: when you do a for each iteration you are referencing each and every
control, hence you get the control type. But when you call on the control
from the Controls collection, eg: Controls(cntlThingy.Name) you are
returning a reference to the control or the control array. That is, if it
was an array, you could reference the individual items such as by
Controls(cntlThingy.Name)(i)
Rick Rothstein <fnr...@aosi.com> wrote in message
news:OI6BTfR8#GA.229@cppssbbsa05...
Private Sub Command1_Click()
Dim c As Control
For Each c In Controls
If IsControlArray(c) Then
Debug.Print c.Name & " is a control array."
Else
Debug.Print "Nope " & c.Name & " is not."
End If
Next
End Sub
Public Function IsControlArray(c As Control) As Boolean
On Error Resume Next
IsControlArray = Len(TypeName(c.Index))
End Function
David
Rick Rothstein wrote in message ...
David
Bill McCarthy wrote in message ...
Private Sub cmdCheck_Click()
Dim ControlItem As Control
For Each ControlItem In Me.Controls
If IsInControlArray(ControlItem) Then
Debug.Print ControlItem.Name & " is index " & CStr(ControlItem.Index)
Else
Debug.Print ControlItem.Name & " is not an Array member"
End If
Next
End Sub
Private Function IsInControlArray(ByVal ControlItem As Control)
Dim x As Long
On Error Resume Next
x = ControlItem.Index
If Err.Number = 0 Then IsInControlArray = True
End Function
VERY interesting.... I learn something new every day...
YOUR SOLUTION WORKS PERFECTLY.
Thank you. That's what I love about these news groups, there is always
someone out there who can provide an answer to a question. For some reason,
this particular question has always presented a blind spot to me. I thought
I looked into, and I thought didn't find a solution in, the Controls
collection back when I first ran into this particular problem. Obviously, I
missed it then and never thought to look at it again. Thanks again.
Rick
Bill McCarthy <bil...@gsat.edu.au> wrote in message
news:uba8BzS8#GA.227@cppssbbsa05...
Glad you got it.
It seems that with VB we all have to say OOPs sooner or later, you can
.Count on it. :-)
Rick Rothstein <fnr...@aosi.com> wrote in message
news:e8ycIYW8#GA.197@cppssbbsa04...
<SNIP>
438 - "Object doesn't support this property or method."
Thanks but no good.
Anyone else?
- Ben
"Richard Nettleingham" wrote:
>
> Hi Ben,
>
> Perhaps this would help:
>
> Use the Count property of the controls collection, if you for
example have
> a textbox named txtinput use txtinput.count
>
> Regards
> /Richard
Function IsControlArray(ControlIn) As Boolean
If TypeName(Controls(ControlIn.Name)) = "Object" Then
IsControlArray = True
Else
IsControlArray = False
End If
End Function
The loop you want to do is:
For Each Cntrl In Controls
If IsControlArray(Cntrl) = False Then
'It is NOT a control array so do your thing
End If
Next
Rick
<ben_h...@hotmail.com> wrote in message
news:7q4gte$dvi$1...@nnrp1.deja.com...
> I have a method that I want to use for many forms. On some of those
> forms I have control arrays and on others I do not. The method I
> execute should loop through all controls and do some special stuff to
> those controls that are NOT part of a control array.
>
> I have sample code below that does work. However, in my case most of
> my controls are NOT control arrays, so this code is very slow because
> it assumes the exception, which we all know is not efficient.
>
> Is there ANY WAY to check for a ControlArray?? Does VB have anything
> like a "IsControlArray" method or something similiar??
>
> The code I have that works is below, but I would really appreciate
> something that works much more efficiently (and reads a little clearer)!
>
> - Ben Hadden
> ben_h...@hotmail.com
>
>
> Dim Index as Integer
>
> For Each Control in Form.Controls
>
> 'This will raise error if it is not a control array.
> 'this error is handled in error handling and Index set to -1.
> Index = Control.Index
>
> 'Index of 0 or greater means we have a control array, so skip code.
> 'Index of -1 assumes we do not have control array, so run code.
> If Index < 0 then
> <<Code that we run when we know we do NOT have a control array>>
> End If
>
> Next Control
>
> Err_Handling:
> Select Case Err.Number
> Case 343
> Index = -1
> Resume Next
> Case Else
> 'Do Error Handling
> End Select
>
>
I ran two tests. The only difference was to take out the line where
I'm accessing the Index property. Instead I just hardcoded the number
to -1. My screen opened in half of the time (8 sec. vs. 4 sec.).