tags:

views:

289

answers:

5

I am trying to loop through all controls in a form: For Each ctrl in Me.Controls in order enable/disable the control based on some conditions. But there is a control on the form that gives an error when I try to access it. What kind of control does that, and how do I find it?

+1  A: 

When you get your error and click Debug, is the error on the line setting a control's Enabled property?

If so, add a Debug.Print statement writing out the control's name. Do so on the line before setting the Enabled property.

Here's what I mean:

Dim ctrl As Control
For Each ctrl In Me.Controls
    Debug.Print ctrl.Name
    ctrl.Enabled = True      
Next

The Debug.Print statement will write out to the Immediate Window the name of the control that was last processed in the loop, presumably the one that caused your error.

EDIT

This might work. Put this control in a Panel control and set the Panel's Enabled property to False. If I recall correctly, in VB6 setting a container control's Enabled property to False will also set the container's child controls Enabled to False. If your control's Enabled property really is read-only, I'm curious what would happen.

Jay Riggs
The when trying to access this ctrl (as in looping through all controls to debug.print them), a popup box saying the "Property is write only" when this particular control is encountered.
tosa
The error you describe is when you're trying to set the Enabled property of the control that's giving you problems? What kind of control is it? Is there an Enabled property that you can set for the control when you're viewing your form in the designer? It's possible that the control's Enabled property is read only - that is what the error message you're setting is saying. See my edit for another idea that may work.
Jay Riggs
A: 

Another approach is as follows, that also works at runtime (as opposed to just in the IDE):

private sub SetEnabled()
  on error goto errHandle

  Dim ctrl As Control
  For Each ctrl In Me.Controls
    ctrl.Enabled = True      
  Next

  exitPoint:
    exit sub
  errHandle:
    MsgBox "Error " & err.Description & " with Control " & ctrl.Name
    resume exitPoint
end sub
AngryHacker
It's crapping out on SSTab. I'm checking if the control's container is a certain frame, then enable/disable it..."If ctrl.Container = fraMovies Then...". But when the program loops and tries to check SSTab's container it throws an exception.
tosa
I am guessing that SSTab does not have an Enabled property.
AngryHacker
@AngryHacker: at first I also thought SSTab must not have an Enabled property: but `tosa`'s problem code line is **not using the Enabled property**. See my answer for my take on the problem (= not Is). Your answer is a good one give the original question, which strongly implies that the problem happens when changing the Enabled property, rather than trying to establish the control's Container.
MarkJ
A: 

Tosa: from your comment on AngryHacker's answer, I think you are checking the container incorrectly.

Your code is like this

 ' BAD CODE '
 If ctrl.Container = fraMovies Then

For me that gives error 450 Wrong number of arguments or invalid property assignment. Do you get the same error?

The code should use Is rather than =, like this

 ' GOOD CODE '
 If ctrl.Container Is fraMovies Then

Explanation. You want to check whether two variables "point" to the same control. Controls are objects: you must use Is not = to check whether two object variables "point" to the same object. This is a classic pitfall in VB6.

One last word. Next time, could you try to post 10 lines or less of actual code, reproducing the error, and give the exact error number and message and the exact line on which it occurs? It really does make it much easier for us to solve your problem - I know it's work for you to shorten the code, but you'll get better answers that way.

EDIT Welcome back! :) You said some controls don't have a Container property. You could try wrapping the test in On Error Resume Next, something like this.

 ' GOOD CODE '
 Dim bMatch As Boolean  
 Dim ctrl As Control 
 For Each ctrl In Me.Controls 
   bMatch = False  
   On Error Resume Next  
   bMatch = (ctrl.Container Is fraMovies)  
   On Error Goto 0 
   If bMatch Then  
     ctrl.Enabled = True       
   End If
 Next 
MarkJ
Hello, I'm back looking at this issue. Thanks, the "is" works. Now the problem is at the .container check portion. There are controls that don't have a container (such as commondialog), and checking them for a container gives an error. What I am trying to do is loop through all the objects in a frame and disable them. This should also be the case for and objects in frames that are in the original frame (iterative loop). What's the best way for this?
tosa
Hi, thanks for your response. Instead of continuing processing at the next line (via On Error Resume Next, how do I instead go to the next object in the For Each loop? The problem is that even though some controls don't have containers, they do have an enabled property, and thus they get disabled/enabled on the resume part. Better yet, how do I check if an object has a container property (without using an error catcher)?
tosa
Hi, there's no `Cycle` statement in VB6 that allows you to go straight to the next object. My suggestion is to use an `If` block to wrap the use of the Enabled property. I'll edit my answer again to make that plainer. I don't think there's any simpler way to detect whether an object has a container property other than using an error trap.
MarkJ
+1  A: 

Try this:

Dim ctr As Control
Dim CtrStatus Boolean

CtrStatus = False

For Each ctr In Me.Controls

  If (SSTab.hwnd = GetParent(ctr.hwnd)) Then
    Call CallByName(ctr, "Enabled", VbLet, CtrStatus)
  else
    ctr.Enabled = CtrStatus
  End If

Next
Dan S
A: 

Suppress the error reports before the loop and then set it back to standard error handling:

On Error Resume Next
 For Each ctrl In Me.Controls
      ctrl.Enabled = lIsEnabled
 Next
 On Error GoTo 0

OR name your controls with a standard prefix/suffix that you can check by name and skip in the loop.

For Each ctrl In Me.Controls
      If Left(ctrl.Name, 3) = "sst" Then
           ctrl.Enabled = lIsEnabled
      End If
 Next
jasonk