I make command buttons appear and disappear all the time, and while it is a pain in the toches to do it the first time, you can write a subroutine for these manipulations and use it when you need it. After that, it is trivial.
What I do is pass in the name of the form and of the control so that the code can do Forms("formname").Controls("Controlname") as a starting point. If you define a Control variable in your subroutine and do a
SET cltvar = Forms("formname").Controls("Controlname")
then you can just use the control variable later in the code. You can also have a form variable assigned this way (obviously, to the form only) to look at the properties of the form as a whole, for example, FormVar.Width, FormVar.Height, etc.
Then the other subroutine input parameters are passed to determine visibility (Yes/No) and position if visible (you need a .Top and a .Left passed ByRef so that you can update the position if visibility is Yes). As it happens, I also pass in a code that tells the routine the color to use for ForeColor, BackColor, and BorderColor of the main control and of the associated label (see below for more.)
If the control's visibility is NO then you can move it to a "neutral" area on the form and make it invisible and disabled (so you can't accidentally click it when you weren't supposed to be able to see it.) There is also the option of moving the control to the bottom of a stack of such controls. You can determine the size of the control from its .Height and .Width properties to adjust the "new" .Top and .Left as appropriate if you moved the control to a point where it was visible.
You can also a test on CtlVar to see what type of control it is, because sadly, Access is not consistent in regards to whether something is .Visible or whether some other keyword is used. (Hint: Use the Object Browser to determine the correct keyword and do a SELECT CASE on control type to decide how to handle it.)
Now, here's the pay-off for this apparent walk through the woods. If you know the form name and the data control name (which you DO know because you passed them into this putative subroutine), you can write some code to step through the FormVar.Controls

collection to find labels and their names - and their .Parent objects, which will be the text boxes, combo boxes, list boxes, etc. Just as you can move a text item, you can move a label because it ALSO has a .Top and .Left and .Height and .Width that you can use for the computation. And the parent's .Name property for the control to be moved will be the same as the control name you passed in. So if you had one more control variable in the subroutine to act as a Label pointer, you could move the label and control (or make them hidden) at the same time. Once you know the control name, the label name, and the correct settings, it is all downhill from there.
Of course, you don't HAVE to do it this way - but it is the way I do it on my forms that make control positions just one more dynamic thing to be computed and controlled. Write one subroutine with lots of smarts and just call it when you need to move stuff around.