why doesn't this For Each work?

  • Thread starter Thread starter Martin Williams
  • Start date Start date
M

Martin Williams

I have a working version of my survey program, but i'm trying to optimize
now. On the last page, i have a sub that examines all of the answers and
assigns them to variables for uploading to the dataset. A few questions
have multiple checkboxes and i used multiple 'if then' statements to append
the text of the checked boxes to a variable.

I decided to try and tighten the code, but it doesn't seem to work. Can
anyone tell me why?

dim ctrl as control
dim sbQ4 as new StringBuilder(QuestionFourAnswer) // This is a public
variable

for each ctrl in frmpage2.controls
if typeof ctrl is panel then
if ctrl.name is frmpage2.pnlQ4 then
for each subctrl as checkbox in frmpage2.pnlQ4.controls
if subctrl.checked = true then
sbQ4.append(subctrl.text + ", ")
end if
next
end if
end if
next
 
I don't see you declaring subctrl. What errors are you getting?

Bernie Yaeger
 
I made it a little more generic so I could run it easily and found the
errors. Here is the code as I was able to make it run:

Dim ctrl As Control
Dim ctrl2 As Control
For Each ctrl In Me.Controls
If TypeOf ctrl Is Panel Then
If ctrl.Name Is Me.Panel1.Name Then
For Each ctrl2 In ctrl.Controls
If TypeOf ctrl2 Is CheckBox Then
Dim cb As CheckBox = DirectCast(ctrl2, CheckBox)
If cb.Checked = True Then
'your code...
End If
End If
Next
End If
End If
Next
 
You have a potential problem --- if one of the panel's values isn't a
checkbox, I think you'll have an invalid cast exception. This should work
for you though

Dim sbQ4 As New StringBuilder

For Each ctrl As Control In Me.Controls

If TypeOf ctrl Is Panel AndAlso ctrl.Name Is Me.panMain.Name Then

For Each Subctrl As Control In ctrl.Controls

If TypeOf Subctrl Is CheckBox AndAlso CType(Subctrl, CheckBox).Checked Then

sbQ4.Append(Subctrl.Text + ", ")

End If

Next

End If

Next
 
Bernie - it's a little elusive as far as subctrl - in the 1.1 framework you
can declare it in the loop so this subctrl as checkbox
serves as the declaration
 
Well, all the objects in this particular panel are checkboxes. But, this
revised code is still not working.
 
When you say it isn't working - is it throwing an exception, is it not
giving you the desired values, what specifically is not working?

That code should work if the form is the container object of the panel.
Throw in a Debug.WriteLine(ctrl.Parent) and ensure that it's the form. If
it isn't, for instance if that panel is in a groupbox, then you'll need to
iterate through the parent's Controls collection instead.

The only reason I mentioned the possibly cast issue is that if you were to
ever add a control in it that wasn't a Checkbox - you'd break the code. I
wasn't being critical and I apologize if I came off that way.
 
Hey, I appreciate all the help I get from you guys.

What's happening now is that I get an "InvalidCast" error. One thing I did
forget is that in this panel, there is one textbox that remains hidden
unless the checkbox named "other" is checked. And I need to append the text
of that textbox if it's visible. How do I work that in?
 
Hi Martin,

You seem to be going through every single control on your form in order
to obtain a reference to a single panel control. Why do it that way? If
frmpage2 exposes the public field pnlQ4 you could iterate over it's
controls directly, saving yourself considerable time.

Perhaps something like this:

Dim pnl As Panel
Dim sbQuestion4 As New StringBuilder()

pnl = frmpage2.pnlQ4

For Each childControl In pnl.Controls
If TypeOf childControl Is Checkbox Then
' This next line should *not* fail.
Dim checkControl As Checkbox = DirectCast(childControl, CheckBox)
If checkControl.Checked Then
sbQuestion4.Append(checkControl.Text & ", ")
End If
End If
Next

Or have I completely missed what you're trying to do? :)

Regards,
-Adam.
 
No, you haven't missed it, that's exactly what I'm trying to do. But this
example, along with the others, doesn't seem to be assigning the value of
the checkbox text to the QuestionFourAnswer variable. When I update the
database, that field remains blank.

It almost definitely has something to do with the stringbuilder. This
works:

QuestionFourAnswer += checkcontrol.text + ", "

but this doesn't:

sbQ4.append(checkcontrol.text + ", ")

My stringbuilder is declared as:

dim sbQ4 as new stringbulder(QuestionFourAnswer)

Is there something wrong with the above declaration?
 
Martin,

Why do you not look at the code from Charlie, probably he assumed that you
would do it on the currenct form. I changed it bellow in this message (so
maybe typos) a little bit for when it is on a seperated instanced form.

\\\\
For Each ctrl as Control In frmPage2.Controls
If ctrl.Name = "pnlQ4f" Then
For Each ctrl2 as control In ctrl.Controls
if TypeOf ctrl2 Is CheckBox Then
If DirectCast(ctrl2 CheckBox).Checked = True Then
'your code...
End If
End If
Next
End If
Next
///

I hope this helps?

Cor



Cor
 
Cor,

First off, thanks to everyone for the help. Just because I didn't respond
to charlie's post, doesn't mean i didn't try it. I've tried all of them.
None work. I think it has something to do with the stringbuilder. It only
works when I have:

questionfouranswer += somecontrol.text + ", "
 
Martin,

At least I would try
sbQ4.append(somecontrol.text & ",")
or even better
sbQ4.append(subctrl.text)
sbQ4.append(", ")

The + is ambigious, I dont know how this is used in the very overloaded
stringbuilder, maybe is it assumed as a decimal or something,

Cor
 
Sorry ,Cor, the & doesn't work either.

Cor Ligthert said:
Martin,

At least I would try
sbQ4.append(somecontrol.text & ",")
or even better
sbQ4.append(subctrl.text)
sbQ4.append(", ")

The + is ambigious, I dont know how this is used in the very overloaded
stringbuilder, maybe is it assumed as a decimal or something,

Cor
 
Martin,

Because of the other answers, I did not look at your code anymore and saw
now that subcontrol was the control in controls.

I could be something in my code as and see than the directcast.

For Each ctrl as Control In frmPage2.Controls
If ctrl.Name = "pnlQ4f" Then
For Each ctrl2 as control In ctrl.Controls
if TypeOf ctrl2 Is CheckBox Then
If DirectCast(ctrl2,CheckBox).Checked = True Then
sbQ4.append(directcast(ctrl2, Checkbox).text)
sbQ4.append(", ")
End If
End If
Next
End If
Next
///

Because what you do Checkbox in XX.controls is impossible.

I hope this helps now.
(And when not than it is probably only a typo, this is very standard)

Cor
 
The way I have it right now, with some help from Adam, this works:

objPanel = frmPage2.pnlQ4
For Each objControl In objPanel.Controls
If TypeOf objControl Is CheckBox Then
objCheckbox = CType(objControl, CheckBox)
If objCheckbox.Checked Then
If objCheckbox.Text <> "other" Then
QuestionFourAnswer += objCheckbox.Text + ", "
End If
End If
ElseIf TypeOf objControl Is TextBox Then
objText = CType(objControl, TextBox)
QuestionFourAnswer += objText.Text + ", "
End If
Next

If I replace the questionfouranswer += objtext.text + ", " with the
stringbuilder method, it fails. I can't figure it out.
 
Martin,

It appears as though you want the string builder to modify your
QuestionFourAnswer variable directly - this won't happen. Strings in
..NET are immutable, so when you pass in a string to the StringBuilder's
constructor a copy of this string is made. It is this copy that is
mutable - the original is still an immutable string. Any changes you
make to the StringBuilder affect only the internal mutable copy, not the
string you passed to the Constructor.

In your case the modifications you make are local to the StringBuilder
and will not affect the value of QuestionFourAnswer.

The solution is to copy the value of the StringBuilder back into
QuestionFourAnswer once you have finished building the answer:

QuestionFourAnswer = sbQ4.ToString()

Hope that helps!

Regards,
-Adam.
 
Well, I would like to thank everyone for their help. I got everything
working for this program, resulting in a significant speed boost.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top