Hiding/Un-hiding Form Controls with a Module (1 Viewer)

Smokeeater

Registered User.
Local time
Today, 05:11
Joined
Jan 15, 2009
Messages
58
I have code tied to a command button on a subform, however, it is both lengthy and needs to be used in multiple locations (OnOpen, On Current, etc.). I would like to use a module instead, however, the code "hangs up" on each of the control names. I have tried to use the ME! and Me. identifier, but same issue.

Also, since this code is used in a module, do I need to link the control names back to the subform it is being used on?



Function Team2_Hide()

Dim iResponce As Integer
iResponce = MsgBox("Do you wish hide the Team 2 fields?", vbYesNo, "TEAM 2 HIDE")
If iResponce = vbYes Then

DoCmd.Echo (False)
Saf_Cross_UTD2.Visible = False
Saf_Open__Concerns2.Visible = False
Saf_Kaizen_Present2.Visible = False
Saf_Associate_Participation2.Visible = False
Saf_Assoc_BuyOff_DateCompleted2.Visible = False
Saf_Proper_Layout2.Visible = False

more code......
 

isladogs

MVP / VIP
Local time
Today, 10:11
Joined
Jan 14, 2017
Messages
18,239
If your code is in the same form as the controls, use Me.
If in a sub form, then reference the subform controls.
See this link for info http://allenbrowne.com/casu-04.html

There is no benefit in putting the code is in a standard module but if you did so you would need to reference all in a similar way to the above

There is a better way if you have a group of controls to show or hide at the same time
In such cases it's worth using the tag property to save a lot of unnecessary code.
See this link for an example database https://www.access-programmers.co.uk/forums/showthread.php?t=293439
 
Last edited:

pbaldy

Wino Moderator
Staff member
Local time
Today, 02:11
Joined
Aug 30, 2003
Messages
36,126
To your question, "Me" refers to the object containing the code, so can't be used in a standard module (no associated object). You can use the full form reference if it will only be used for a specific form, or put the function in the form's module instead of a standard module. If it might be used for multiple forms, you can leave it in a standard module and pass the form name to it.
 

Smokeeater

Registered User.
Local time
Today, 05:11
Joined
Jan 15, 2009
Messages
58
pbaldy, thank you for the reply. All of the code will be used in the same form, but for different events, that is why it is needed several times.
 

isladogs

MVP / VIP
Local time
Today, 10:11
Joined
Jan 14, 2017
Messages
18,239
As already stated, it would make your life much simpler to use the Tag property. All your code would be replaced with one line such as
Code:
ShowControls False, "H"
Where H is the tag value assigned to all the controls to be hidden

To make this visible again use
Code:
ShowControls True, "H"

Even better, several groups of controls can be managed at once e.g
Code:
ShowControls False, "A", "C", "G"

Full details in the link in post 2
 

pbaldy

Wino Moderator
Staff member
Local time
Today, 02:11
Joined
Aug 30, 2003
Messages
36,126
pbaldy, thank you for the reply. All of the code will be used in the same form, but for different events, that is why it is needed several times.

Then you can move the function to the form's module and use Me. Using the tag property is a good idea as well.
 

Smokeeater

Registered User.
Local time
Today, 05:11
Joined
Jan 15, 2009
Messages
58
I will look at the information on use of the tag property. I may not have done a good job of explaining how the subform is being used. There are 4 different groups of controls on the form. Each group holds 15 controls. The first 10 are always visible. Depending on the activity, the user can decide if the 2nd group of controls is needed, then the 3rd group and finally the 4th group. What I would like is to have all of the controls in groups 2, 3, and 4 hidden when there is a new record, if based on if the 1st control in each group is null. No issues there, I can figure that out.

Using command buttons, the user will unhide all of the controls in group 2, 3 and/or 4 based on what is needed. Instead of putting all of the controls and related labels in code within each command button, I was preferring to use a module.

Thanks again for the replies.
 

isladogs

MVP / VIP
Local time
Today, 10:11
Joined
Jan 14, 2017
Messages
18,239
I will look at the information on use of the tag property. I may not have done a good job of explaining how the subform is being used. There are 4 different groups of controls on the form. Each group holds 15 controls. The first 10 are always visible. Depending on the activity, the user can decide if the 2nd group of controls is needed, then the 3rd group and finally the 4th group. What I would like is to have all of the controls in groups 2, 3, and 4 hidden when there is a new record, if based on if the 1st control in each group is null. No issues there, I can figure that out.

Using command buttons, the user will unhide all of the controls in group 2, 3 and/or 4 based on what is needed. Instead of putting all of the controls and related labels in code within each command button, I was preferring to use a module.

Thanks again for the replies.

The Tag property would be perfect for this
If I refer to the groups as 1,2,3,4 then the first 10 always visible controls in each would have tags 1A, 2A, 3A, 4A and the remaining 5 would be 1B, 2B, 3B, 4B

Now you should be able to group the controls very easily

In form load event
Code:
ShowControls True, "1A", "2A", "3A", "4A" 
ShowControls False, "1B", "2B", "3B", "4B"

You would then modify the visible state of one or more group for:
a) new records
b) user decisions as described above

NOTE: the ShowControls code IS placed in a standard module and can be used throughout your database
The supplied code also includes LockControls & EnableControls functions which work in a similar way
Just copy the module to your own database to use it

HTH
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Today, 17:11
Joined
May 7, 2009
Messages
19,247
If the function is in the module you must completely qualify your variables:


Function Team2_Hide()

Dim iResponce As Integer
iResponce = MsgBox("Do you wish hide the Team 2 fields?", vbYesNo, "TEAM 2 HIDE")
If iResponce = vbYes Then

DoCmd.Echo (False)
[Forms]![mainform name]![subform name].form!Saf_Cross_UTD2.Visible = False



Or to be generic modify the sub/func to accept a form object:


Function Team2_Hide(frm as form)

Dim iResponce As Integer
iResponce = MsgBox("Do you wish hide the Team 2 fields?", vbYesNo, "TEAM 2 HIDE")
If iResponce = vbYes Then

DoCmd.Echo (False)
Frm.form!Saf_Cross_UTD2.Visible = False



Then you modify how you call it:

Team2_hide me.parent![subformname]
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 04:11
Joined
Feb 28, 2001
Messages
27,194
I always used this method for using a general module to diddle with form states:

Code:
Public Sub SetClrStyle( ByRef ctlX as Access.Control, ByRef frmY as Access.Form, lCode as Long )
...
   Select Case lCode
        Case 0
            ctlX.Enabled = False
            ctlX.Visible = False
        Case 1
            ctlX.Enabled = True
            ctlX.Visible = True
            ctlX.Forecolor = vbBlack
            ctlX.Backcolor = vbWhite
            ctlX.Bordercolor = vbBlack
        Case 2
            ctlX.Enabled = True
            ctlX.Visible = True
            ctlX.Forecolor = vbRed
            ctlX.Backcolor = vbYellow
            ctlX.Bordercolor = vbRed
       etc. etc. et.c

If I needed to do something to the form, I had a reference to it. My codes let me select a state that would make the control visible or not, change colors based on state code, etc. And if I needed to search the form's list of controls, it was available as ctlX.Controls (as a collection to be enumerated).

When you want to do something to a bunch of controls, you can go through the collection easily enough.

The actual code I used was a bit more complex than that because up front I would test what kind of control it was and would set flags internally to tell me if I could use the particular property of that control. For instance, if I ran into a line (which IS a type of control), I knew it had no back color. So the code was complex enough to know what could and could not be done for each type of control. But of course, if you have the reference to the control, you can use ctlX.Type and find out if it is acTextBox or acLine or acRectangle etc.
 

Smokeeater

Registered User.
Local time
Today, 05:11
Joined
Jan 15, 2009
Messages
58
ridders, arnelgp, & The_Doc_Man:

Thank you each for your replies and examples. I now have it figured out using your guidance!!

On to the next quest!

Smokeeater
 

isladogs

MVP / VIP
Local time
Today, 10:11
Joined
Jan 14, 2017
Messages
18,239
Excellent.
For the benefit of others reading this thread in the future, please give an outline of your solution
 

Smokeeater

Registered User.
Local time
Today, 05:11
Joined
Jan 15, 2009
Messages
58
ridders,

Good point. I will post the method and code I used once fully completed. That will probably be mid-week due to other work "fires" that taking priority today.
 

Uncle Gizmo

Nifty Access Guy
Staff member
Local time
Today, 10:11
Joined
Jul 9, 2003
Messages
16,282
It is a mistake to put code which works only within a particular form into a separate module. Code that only works within one particular form should go in that forms module.

The only exception to this would be if you had code which works generically on any form.
 

Smokeeater

Registered User.
Local time
Today, 05:11
Joined
Jan 15, 2009
Messages
58
ridders,

Finally had a little time to get back to this db. I marked by tags for the controls, T2 (group 2 controls) for now. Eventually I will tag the other controls T3 & T4 respectively based on when they are needed by the user.

I used the modules from your example db, and the code on the controls. I have initially set up 2 command buttons for testing purposes only, one to hide the T2 controls, one to unhide them. When I press the hide button, not only does the T2 controls go hidden, so do other controls where the tag is not indicated. Additionally, all of these controls are in a subform "B", and there is another subform "A". When I press the Hide T2 command button, it hides subform "B" and all of its controls as well. Also, for the form "OnLoad" code from your db, I put it on the subform, which I know now is probably incorrect - it should go in the parent form, and then somehow put the focus on subform B.

Finally, I get an error message every time I run the code, Error 2165, You can't hide a control that has the focus. I know I need to call out a control in group 1, that will never be hidden, but even if I manually put the focus on one of those controls before running the command, I still get the same error message.

Further along than I was a week ago...
 

isladogs

MVP / VIP
Local time
Today, 10:11
Joined
Jan 14, 2017
Messages
18,239
ridders,

Finally had a little time to get back to this db. I marked by tags for the controls, T2 (group 2 controls) for now. Eventually I will tag the other controls T3 & T4 respectively based on when they are needed by the user.

I used the modules from your example db, and the code on the controls. I have initially set up 2 command buttons for testing purposes only, one to hide the T2 controls, one to unhide them. When I press the hide button, not only does the T2 controls go hidden, so do other controls where the tag is not indicated. Additionally, all of these controls are in a subform "B", and there is another subform "A". When I press the Hide T2 command button, it hides subform "B" and all of its controls as well. Also, for the form "OnLoad" code from your db, I put it on the subform, which I know now is probably incorrect - it should go in the parent form, and then somehow put the focus on subform B.

Finally, I get an error message every time I run the code, Error 2165, You can't hide a control that has the focus. I know I need to call out a control in group 1, that will never be hidden, but even if I manually put the focus on one of those controls before running the command, I still get the same error message.

Further along than I was a week ago...

Using this method, you need to assign a tag to all form controls.
For consistency, I use "A" for controls that are always visible & "X" for those that are always hidden. That's just my system - use what works for you.
Other letters are used for those that are sometimes visible, with those in a 'group' having the same letter e.g. "B".
Subforms are just controls on a form so these are treated like any other control

As you said, before hiding any controls, you must move the focus to another control. I often use a form close button for this purpose as its always visible / enabled

Hopefully that will get you where you need to be.
I use it for some very complex multi purpose forms some of which have with hundreds of controls whose visible / enabled / locked state depends on which option has been chosen ... study my example to understand how to use the idea
 

Smokeeater

Registered User.
Local time
Today, 05:11
Joined
Jan 15, 2009
Messages
58
Excellent! Now it is making more sense, and I like the idea of drawing control focus on a command button. I will hopefully get time to work on this tomorrow. Thanks!!
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 04:11
Joined
Feb 28, 2001
Messages
27,194
Smokeeater,

That is a common problem when you write a For Each loop because ONE of those controls will sometimes have focus when it should not, for purposes of dynamic form control management.

An approach I sometimes used for this was to have a control that was ALWAYS going to be visible and editable. I would set focus to that control in the form's OnCurrent event. Still in that event, I used my For Each loop and an indicator of the state desired for all controls. The For Each loop called that per-control routine to do the actual diddling to set all controls to whatever that state needed them to be.

Once the user started actually USING the form, the LostFocus routine of each control would test whether the control losing focus would have an effect on anything else and if so, it would call the per-control routine once for each affected control BEFORE allowing the LostFocus routine to do its Exit Sub. I would have used the OnChange event for that purpose, but it gets called once per character if you are typing into it, and bulky strings would cause a lot of needless testing and control management.

However, every now and then it would happen that the next control in tab-stop order would be affected (or the user could use the cursor to pick the next control) and I would still get that error, because the (X).LostFocus and (X+1).GotFocus fired back-to-back. You see, regardless of TAB or mouse use, Access has already chosen (X+1) on ENTRY to the (X).LostFocus code, and will thus attempt to change focus to it even if other decisions in the routine would have disabled (X+1).

That usually took a bit of thinking and control re-ordering to try to assure that such back-to-back sequences couldn't happen. The moral of my story is that it looks GREAT to make your form dynamically adjust to its own changing conditions, but it takes a bit of engineering to get it working smoothly. Do NOT be surprised if you have the 2165 problem now and then.
 

Smokeeater

Registered User.
Local time
Today, 05:11
Joined
Jan 15, 2009
Messages
58
The_Doc_Man,

You gave me good information, and things to take into consideration, especially making sure the controls are adapted to the expected conditions for new and existing records. I tend to be a perfectionist and want my db's to run correctly all of the time. Errors are frustrating, but I always try to learn not only how to correct, but what I could have done differently during developing the db to keep it from happening to start with.

Thanks again for the insight! Much appreciated!
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 04:11
Joined
Feb 28, 2001
Messages
27,194
Oh, do I know that "perfectionist attitude" intimately well. My neighbors in the cube farm used to chuckle when I would say, "Machine, don't fight me on this. I know where your power cord is plugged in."

But then again, when you are opening up a DB App for others to use, they get to judge you by it, so that perfectionist attitude becomes a matter of pride. Which in the long run is dangerous unless, of course, you are masochistic.

There might be no "i" in TEAM but there sure is one in PRIDE. Also in PERFECTIONIST, where it appears twice for double the impact!
 

Users who are viewing this thread

Top Bottom