Limiting access to parts of custom menu

  • Thread starter Thread starter Jonathan Blitz
  • Start date Start date
J

Jonathan Blitz

I have an Access project in which the user uses a custom-built command bar
to execute functions.

I need to limit certain users to certain partsof the program and do not want
to have to build a number of different command bars.

I don't mind if the user can see in the command bar entries that they are
not allow to use.
The best way would be to disable the functions that the user cannot use.

However, I need some sort of flexibility to allow me to easily add new
entries and also to change who may see what.

I am not talking about hundreds of users each one with a different choice.
The users will be grouped into 3 or 4 differant groups and the permissions
dependant on which group they belong to.


What is the best way to do this?


Jonathan Blitz
AnyKey Limited
Israel
 
A reasoned approach here is to implement user security. That way, each user
that runs the application will have to log in with a user id, and a
password.

You then simply give permissions to certain forms, and reports. IF a user
tries to use a report, or form that they don't have permissions to, then
they get a message. This is by far the least amount of work, as it takes NO
code to prevent users from running parts of the applications.

The above is not the most user friendly, as those menu options are still
visible..but it is the easy way to solve this problem, and it lets you
add/remove users permissions and not have to write code each time to you do
this.
 
So there is no real easy way to disable entries in a menu?

I don't want to build 3 or 4 differant menus (one for each type of user)
because I want one of the expert users to be in controland be able to change
who can do what.

Jonathan Blitz
 
So there is no real easy way to disable entries in a menu?

It is quite easy, but my suggest was one where you need ZERO CODE! (you
can't get to be much less work then that!!). As I mentioned, I not sure if
it
is such a big deal if a user clicks on a option, and gets a message. It is
not like they are going click on that option again and again to see some
stupid message telling them that they can't use the option! Once the user
learns they can't use that option...then they move on.

However, I 100% agree that the above approach is not the most user friendly.
If you are willing to write code to enable, and disable men options, then be
my guest. I mean, there is no other way to solve this problem. If you want
to disable certain menu options for certain users, then you have no choice
but
to write some code that checks the users permissions, and then enables, or
disable the menu options. To me, this is not that big of a coding problem,
but you most certainly will have to write code.

The key to assigning security and NOT having to modify the code each time is
to ALWAYS assign permissions to a security group, and NOT a users (however,
I
think anyone who implements security in ms-access will rapidly figure out
this is the ONLY way to do this and not wind up in a mental ward).

If you ALWAYS assign users to security
groups, then you NEVER have to write or modify code when a user
permissions are changed. In fact, it
also means you can develop code and write stuff off site from a client, and
when you re-deploy your "next new" great version, then security settings
that the client, or local admin set/un-set are NOT lost if you do this.
Also, by ALWAYS assigning permissions to security groups and not users
then it means that user security settings are NEVER in the mdb/mde
application, but ALWAYS remain in the workgroup file.

So, I would put some code in each form in the on-open event that checks the
users membership in a particular security group, and then enable/disable
the correct menu options. This approach would be quite clean, and would NOT
requite you to modify the code each time you change, or add, or remove a
users membership in a particular security group (so, if the user does not
have member ship in the "CanDeleteInvoice" security group, then you would
disable the delete invoice button in the menu bar.

if IsInGroup(CurrentUser(),"CanDeleteInvoice") = true then

CommandBars("myCustomBar").Controls("AdminOptions").
Controls("DeleteInvoice").Enabled = True

end if

I suppose you could write the above as:

CommandBars("myCustomBar").Controls("AdminOptions").
Controls("DeleteInvoice").Enabled =
IsInGroup(CurrentUser(),"CanDeleteInvoice")

(the above is just air code..and would belong on ONE line of code).


Up to this point, I think the coding required is quite minimal. HOWEVER this
assume that you ALWAYS built a menu bar for each form (at least forms with
options that matter). I have a small application with 160 forms, and out of
that
only about 12-15 actually have menu bars that matter.

However, where the code does get messy is if you have any menus that are
common to more then one form. The problem is when you switch between
a form, and then switching back to that form (the activate/ reactive problem
you mentioned). It turns out, that I NEVER did re-use the menu bars for
forms
with other forms, and thus when you switch between forms, you don't have to
run any code.

If the menus don't apply to each form, then you will have to write code all
over the place
I don't want to build 3 or 4 differant menus (one for each type of user)
because I want one of the expert users to be in controland be able to
change
who can do what.

As mentioned, you don't have to. You can use the zero code approach I
mentioned, or the 2nd approach works quite well. For the 2nd approch to be
workable, and with not too much work, you must:

1) always assign user permissions to security groups..and not actual forms
(like I said, anyone with a brain will realize this is the only workable
solution here).

2) Don't share menu bars between forms that can be opened at the same time.

if you following both of the above, then enabling (or hiding) menu options
is quite easy.


The function IsInGroup is something I wrote some time ago...I have
reproduced it here at the end of this post.


--
Albert D. Kallal (Access MVP)
Edmonton, Alberta Canada
(e-mail address removed)
http://www.members.shaw.ca/AlbertKallal

Public Function IsInGroup(UsrName As String, GrpName As String) As Boolean
'Determines whether UsrName is a member of GrpName

Dim grp As Group
Dim IIG As Boolean
Dim usr As user

IIG = False

For Each usr In DBEngine.Workspaces(0).Users
If usr.Name = UsrName Then GoTo FoundUser
Next

GoTo IIG_Exit

FoundUser:
For Each grp In usr.Groups
If grp.Name = GrpName Then IIG = True
Next

IIG_Exit:
IsInGroup = IIG


End Function
 
Many, many thanks.

This seems to be the best approach.

I would have assigned users to group sanyway - that was the first decision I
made.

Thanks again.

Jonathan Blitz
 
Back
Top