| |||||||||
|
|
| Employee_ID | Username | Password | Access_Level |
|---|---|---|---|
| 15 | AndreaF | ******* | A |
| 14 | HeidiH | ****** | M |
| 3 | HollyW | ******** | A |
| 5 | JenniferC | ***** | M |
| 6 | JodyB | ******** | A |
| 7 | JonE | ***** | A |
| 1 | Joe | *** | M |
| 8 | KristalD | ******* | M |
| 9 | MariaH | ***** | M |
| 10 | MaryC | ********** | A |
| 11 | MaryW | ******* | A |
| 12 | RussellN | ***** | A |
| 13 | ScottR | ******* | A |
| 2 | TinaC | ****** | M |
Note the Access_Level field - M is for Managers (full access); A is for Artists (partial access).
When the database opens the On Open event is activated and the following VB code runs:
Private Sub Form_Open(Cancel As Integer)
' initialize global variables
set_globals
' Hide tabs
Me.TabCtl0.Pages.Item(0).Caption = "Welcome"
Me.TabCtl0.Pages.Item(1).Visible = False
Me.TabCtl0.Pages.Item(2).Visible = False
Me.TabCtl0.Pages.Item(3).Visible = False
Me.TabCtl0.Pages.Item(4).Visible = False
username = Environ("Username")
me.username=username
End Sub
Here is the set_globals routine and get_globals functions. Put them into a Module:
Option Compare Database
Global GBL_employee_ID As Long
Global GBL_Access_Level As String
Function set_globals()
GBL_employee_ID = 0
End Function
Public Function get_global(gname As String)
Select Case gname
Case "Employee_ID"
get_global = GBL_employee_ID
End Select
End Function
Place the above code in a new module and you can name the new module anything you like - the important part is the 'Global GBL_Access_Level As String' line that must come after the Option Compare Databse and before the Option Explicit line.
The result is a login form on the welcome screen of the tabbed interface:
(Click to view full size image)

After the correct username and password has been entered then the following subroutine is called. Here is the login subroutine code:
(note that some lines are wrapped because of page width limitations)
Private Sub Login_btn_Click()
' ************************************* login sequence
On Error GoTo local_err
DoCmd.RunCommand acCmdSaveRecord
'
' set global access level to failsafe no access then lookup access level
'
GBL_Access_Level = "X"
GBL_Access_Level = Nz(DLookup("Access_Level", "L_Employees", "Username='" & Nz(Me.USername, " ") & "' and password='" &
Nz(Me.Password, " ") & "'"), "X")
'
' examine results of username/password lookup
'
If GBL_Access_Level = "X" Then
MsgBox "Invalid Username or Password... try again."
Exit Sub
End If
'
' get employee id
'
GBL_employee_ID = Nz(DLookup("Employee_ID", "L_Employees", "Username='" & Nz(Me.USername, " ") & "' and password='" &
Nz(Me.Password, " ") & "'"), "X")
'
'set welcome to include users name or invalid logon if bad logon
'
Me.TabCtl0.Pages.Item(0).Caption = "Welcome " & Nz(DLookup("employee_name", "L_Employees", "employee_id=" &
get_global("Employee_ID")), "Invalid Login")
' setup privs based on artist or manager
'
Form_F_Projects.Requery
'
' call subroutine to set access to forms
'
Call set_privs
'
' reset login screen fields
'
Form_F_Projects.Requery
Me.USername = ""
Me.Password = ""
Me.TabCtl0.Pages.Item(1).SetFocus
Exit Sub
'
' error handler
'
local_err:
MsgBox "unexpected error= " & Err.Description
Resume ok_exit
ok_exit:
Exit Sub
Below is the subroutine to set privileges and show/hide menu tabs. Note that we use a simple case statement to examine user access level and set visibility of tabs and properties of appropriate forms. For the limited access 'A' - Artists the Reports and Lists tab are hidden since only the managers can run reports and modify list data (including passwords and usernames).
Public Sub set_privs()
Form_F_Projects.Form.AllowAdditions = False
Form_F_Projects.Form.AllowDeletions = False
Form_F_Projects.Form.AllowEdits = False
Form_F_Projects.Form.AllowFilters = False
'
'
Form_F_Project_Actions.Form.AllowAdditions = True
Form_F_Project_Actions.Form.AllowDeletions = True
'
'status field is updateable by everyone
'
Form_F_Project_Status_Only.Form.AllowEdits = True
Form_F_Project_Status_Only.Form.AllowAdditions = True
'
Select Case GBL_Access_Level
Case "M" ' manager
Me.TabCtl0.Pages.Item(1).Visible = True
Me.TabCtl0.Pages.Item(2).Visible = True
Me.TabCtl0.Pages.Item(3).Visible = True
Me.TabCtl0.Pages.Item(4).Visible = True
'
Form_F_Projects.Form.AllowEdits = True
Form_F_Projects.Form.AllowAdditions = True
Form_F_Projects.Form.AllowDeletions = True
'
Form_F_Project_Products.Form.AllowEdits = True
Form_F_Project_Products.Form.AllowAdditions = True
Form_F_Project_Products.Form.AllowDeletions = True
'
Form_F_Project_Status_Only.Form.AllowEdits = True
Form_F_Project_Status_Only.Form.AllowAdditions = True
'
Form_F_Project_Actions.Form.AllowEdits = True
Form_F_Project_Actions.Form.AllowAdditions = True
Form_F_Project_Actions.Form.AllowDeletions = True
'
Form_F_Projects.Requery
Form_F_Project_Products.Requery
Case "A" ' artist
Me.TabCtl0.Pages.Item(1).Visible = True
Me.TabCtl0.Pages.Item(2).Visible = True
'
Form_F_Project_Products.Form.AllowAdditions = False
Form_F_Project_Products.Form.AllowDeletions = False
Form_F_Project_Products.Form.AllowEdits = False
'
Form_F_Project_Status_Only.Form.AllowEdits = True
Form_F_Project_Status_Only.Form.AllowAdditions = True
'
Form_F_Project_Actions.Form.AllowEdits = True
Form_F_Project_Actions.Form.AllowAdditions = True
Form_F_Project_Actions.Form.AllowDeletions = True
'
Form_F_Projects.Requery
Form_F_Project_Products.Requery
End Select
Here is the resulting main menu after security settings - all tabs are available in this case:
(Click to view full size image)

The last part of the security setup for this database is to restrict artists viewing of project data. Artists are only allowed to modify certain fields of their own projects. And, are only allowed to review their own projects.
Here is the query record source for the main projects form:
SELECT M_Projects.Project_ID, M_Projects.ProjectName, M_Projects.Manager_ID, M_Projects.DateOpened,
M_Projects.Project_Status_ID, M_Projects.Due_Date, M_Projects.Artist_ID, M_Projects.DateClosed, M_Projects.Agent_ID,
M_Projects.Sale_Rep_ID, M_Projects.RouteTo, M_Projects.BillTo_ID, M_Projects.ProjectPaidDate, M_Projects.Project_Type_ID,
M_Projects.FarmList, M_Projects.Indicia_ID, M_Projects.Design_ID, M_Projects.Output_Spec_ID, M_Projects.Files_Submitted,
M_Projects.Payment_Method_ID, M_Projects.Comments, M_Projects.Date_Modified, M_Projects.Modified_By
FROM M_Projects
WHERE (((M_Projects.Artist_ID) In (select employee_id from Q_Employee_Access_List) Or (M_Projects.Artist_ID)=0));
(note that (M_Projects.Artist_ID)=0) allows new projects to be created)
Below is the SQL code for the Q_Employee_Access_List query referenced above
SELECT L_Employees.Employee_ID
FROM L_Employees
WHERE (((L_Employees.Employee_ID)=get_global('employee_id'))) OR (((get_global('access_level'))="M"));
The combination of these two queries limits access to project data. Artists with an 'A' access level can only see their own
projects and Managers with 'M' access level can see all projects. The individual form setting defined in the Set_Privs
subroutine (above) determines who can modify data in which forms.
Finally, you can see that once setup, this method for applying security and access levels to databases is fairly easy to implement. The method is also flexible since additional levels access can be added by simply adding more Select Case statements in the Set_Privs subroutine.
We have developed a simplified downloadable Access Security Alternative database example. You can find this running example in our new Access Database Downloads.
|
|