Set a group of controls as visible/hidden, enabled/disabled or locked/unlocked

Status
Not open for further replies.

isladogs

MVP / VIP
Local time
Today, 01:50
Joined
Jan 14, 2017
Messages
18,549
The attached utility demonstrates a way of setting the state of a group of controls at the same time using the controls' Tag property.

The properties that can be controlled are: .Visible , .Enabled, .Locked

However, some control types do not allow all of the properties.
For example labels can not be disabled or locked

For full details of control types & properties, see the table tblControlTypes

All the controls in the 2 forms have tags A, B, C or D.
Use the buttons to control the state of those with tags A, B, C
To ensure the form remains usable, controls with tag D remain visible, enabled & unlocked at all times!

The forms aren't intended to be elegant, just to show what can be done

attachment.php


UPDATED 29/04/2017:
For portability, all the functionality is now included in the module modControlState.
There are 3 procedures: ShowControls, EnableControls & LockControls

2 forms have been included - identical apart from colour
This is just to confirm that the forms are controlled independently as you would expect

To use this approach, just copy the module modControlState to your own project


An alternative approach suggested by Static & using parameter arrays rather than tags is listed in Module1 but has not been used here
 

Attachments

Last edited:
Ridders, thank you for the reply. I would prefer to not tie these back to a tag on a control. The end user will unhide a large number of fields all at once, based on need. If not needed, them all of them in the module will stay hidden. If they are needed, I see them using a button to unhide the controls.

I may just have to keep the code tied to a command button if a module cannot be used.
 
Smokeeater
You referred to my reply but as your post has only just been approved, I can't remember if this was done via a PM.

To my mind this approach is perfectly suited to what you describe.
Users can click a button to show additional controls if that's what you want... However, normally I just build that into the code as needed

For example:
a) admin user logged in - show additional controls
b) user clicks Yes on a combo / option group => items shown are updated
etc, etc
 
Ridders,

Thank you for following up. All of the changes have been made and the end users are really satisfied with the hidden fields, and unhiding them with the buttons. I also threw in a couple other minor changes to splash it up a little. On to the next challenge!
 
Pleased it worked for you
BTW please see sticky post about reporting your own posts to moderated areas
 
@Ridder
This is a good concept of using the TAG property to update multiple controls, but I think you have may lose the average user in some areas. Less may be more. I recommend get rid of this
Code:
Public Sub EnableControls(State As Boolean, Tg1 As String, Optional Tg2 As String, Optional Tg3 As String, _
        Optional Tg4 As String, Optional Tg5 As String, Optional Tg6 As String)

On Error GoTo Err_Handler

    'set controls to locked or not according to the control tag value
     For Each ctrl In Screen.ActiveForm.Controls
        Select Case ctrl.ControlType
        
        Case acLabel, acImage, acLine, acRectangle, acPageBreak
            'no code here - these can't be disabled
        Case Else
            If ctrl.Tag = Tg1 Or ctrl.Tag = Tg2 Or ctrl.Tag = Tg3 Or ctrl.Tag = Tg4 _
                    Or ctrl.Tag = Tg5 Or ctrl.Tag = Tg6 Then ctrl.Enabled = State
        End Select
        
    Next ctrl
  
Exit_Handler:
    Exit Sub

Err_Handler:
    MsgBox "Error " & Err.Number & " " & Err.description
    Resume Exit_Handler
    
End Sub

You make your code less generic (unless you get rid of those tag parameters and add a ParamArray). Recommend replace simply with the below code because the multiple tags does not add to what you are trying to demonstrate and only adds a level of complexity. I understand you are trying to be efficient, but does not really help show what you are doing.

Code:
Public Sub EnableControls(State As Boolean, TheTag as string)
On Error GoTo Err_Handler
    'set controls to Enabled or not according to the control tag value
     For Each ctrl In Screen.ActiveForm.Controls
        If ctrl.Tag = TheTag Then ctrl.Enabled = State
    Next ctrl
 
Exit_Handler:
    Exit Sub

Err_Handler:
    MsgBox "Error " & Err.Number & " " & Err.description
    Resume Exit_Handler
    
End Sub

Then modify the call from
Code:
EnableControls True, "A", "B", "C", "D"
    ShowControls True, "A", "B", "C", "D"
    LockControls False, "A", "B", "C", "D"
to the longer but simpler for the average user to follow
Code:
    EnableControls True, "A" 
    EnableControls True, "B"
    EnableControls True, "C"
    EnableControls True, "D" 
    ShowControls True, "A"
    ....
    ShowControls True, "D"
    LockControls False, "A"
    ...
    LoctControls False, "D"

Also may want to label the controlType subform as for information only. I was lost on what its purpose was. I assumed you actually used it to determine if a control had the property, but you do not it is for visibility only. If you do then I recommend adding the field controltypevalue.
ControlTypeValue 'Long
Code:
ControlType	ControlTypeValue
acLabel         100
acRectangle     101
acCommandButton 104
acOptionButton  105
acCheckBox      106
acOptionGroup   107
acTextBox       109
acListBox       110
acComboBox      111
acTabCtl        123
....

Then if you made the field names the actual Property name and made the values boolean (Show/Hide to Visible, Enable/Disable to Enable, Lock/Unlock to Lock) you could actually check this table to see if a property is settable
Code:
Public Function HasProperty(PropName As String, ControlType As Long) As Boolean
  'This may be more work than it is worth. You would have to keep the table updated. You are probably better off just trapping the error if the property does not exist
  HasProperty = Nz(DLookup(PropName, "tblControlTypes", "ControlTypeValue = " & ControlType), False)
End Function

However, it may just be quicker to try to set a property that does not exist and throw the error.
 
Hi MajP

Always happy to hear your opinion but in this case I completely disagree with it.

I tried it with a parameter array as suggested by static but user feedback from various forums was that the current system was preferred.

Similarly, feedback from users was that more concise code like
Code:
EnableControls True, "A", "B", "C", "D"
was preferable to writing each on a separate line.

But as both will work, users can decide for themselves

The subform is indeed for info / display purposes only.
The form includes examples of all standard control types.
I needed a subform so that worked on two levels.
If users needed it in their own databases, I would have told them to include it

As for your final point, I dislike code that is designed around checking for a property error.
Sometimes it is unavoidable however.
 
Last edited:
When you have large groups of controls that should be visible/hidden, locked/unlocked as a group, consider using a tabbed form. That doesn't require any code.
 
Thanks for the comment Pat which I've only just spotted
I use tabbed forms regularly and agree your suggestion would indeed be useful for many people.

However, I also have many tabbed forms where I still need to hide selected controls at various points in the code depending on the choices made by users
 
The ACCDB version of this app was created in A2010 and may not work in earlier versions
For the benefit of anyone using A2007 or earlier, I've attached an A2003 MDB version as well as the latest ACCDB version

Hope that helps
 

Attachments

Last edited:
Status
Not open for further replies.

Users who are viewing this thread

Back
Top Bottom