When I had this problem, what I did, in essence, was to put code in the Form_Open routine to determine whether the user in question was an administrator. I did this by determining the username via Environ("Username") and doing a DLookup of the user's role from a table of users and roles (and other data not relevant to this question). In this same routine, if the user's account had been disabled, I cancelled the Open event, which effectively blocked the user. If the user was OK, I left behind a variable in the form's Class Module general declaration area to remember the role from that lookup.
In the Form_Load event, I checked the user's role and, for every control that would be restricted for that role, I either disabled it (which "greys it out") or "vanished" it by making it not visible at all.
The reason for doing it that way is that the Form_Open event occurs first in sequence and details of the form are not entirely available - but you can do a DLookup or other tests at that time for screening. The next event is Form_Load, and there you can do all the formatting you need. But you don't even waste the time if the Form_Open event gets cancelled because in that case Form_Load doesn't occur. Then, once the Open and Load events are done, Access populates the form with data from the underlying record and fires the Form_Current event. By that time, the form is already formatted, color coded, or whatever I needed to do. Which meant that my Form_Load routine didn't do very much, just a couple of minor overhead functions to record the status of the form.
This is also an easy way to do a "divide and conquer" for the work to be done if you are trying to build a really smooth user interface.