Dustin Stanley
asked on
MS Access How To Keep Track Of Users or Employees Using the Database
I have most of this set up. The things I have already.
This is where I am stuck....
How do I set up for Access to retain the EmpID after successful login and apply that to all the altered database tables when someone changes them?
Basically how does Access know what EmpID is currently using the database and changing records?
Thanks for the help!
- Login Page Form on AutoExec
- Employee/User Table With fields like EmpID (Key), Username, Password, First Name, Last Name, Etc.....
- On Every Table in the Database a Foreign Key EmpID field and Relationship on the Foreign Key EmpID to the Employees Table EmpID Key.
This is where I am stuck....
How do I set up for Access to retain the EmpID after successful login and apply that to all the altered database tables when someone changes them?
Basically how does Access know what EmpID is currently using the database and changing records?
Thanks for the help!
ASKER
Thanks Crystal. You said:
Now is this an example of a single person in a single office or can this be used on a computer that several people use. Such as logging into Access with my form and then logging out on exit?
Thanks for all the help!
I like using a database property to keep track of the user for each FE since it is remembered even when you close Access -- so you only have to do this once.
Now is this an example of a single person in a single office or can this be used on a computer that several people use. Such as logging into Access with my form and then logging out on exit?
Thanks for all the help!
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
you're welcome, Dustin
If users are not specifically assigned a FE, then you will need a list of users and their IDs in a table. Once they enter who they are, set the database property. Another advantage is that database properties do not lose their values like global variables sometimes do.
My tracking fields for tables are:
here is a general function I call on a form BeforeUpdate event when data is added or edited:
If users are not specifically assigned a FE, then you will need a list of users and their IDs in a table. Once they enter who they are, set the database property. Another advantage is that database properties do not lose their values like global variables sometimes do.
My tracking fields for tables are:
- IDadd, long
- IDedit, long
- dtmAdd, date/time, default value =Now()
- dtmEdit, date/time, default value =Now()
here is a general function I call on a form BeforeUpdate event when data is added or edited:
Public Function FormBeforeUpdate( _
pF As Form _
, Optional bUpdateParentToo As Boolean = False _
) As Boolean
'161220 strive4peace, 28
'
' call on the form BeforeUpdate event - before record is saved
'
'UPDATE the record on the current form with dtmEdit, IDadd, IDedit
' optionally, also update the record in the parent form
'
On Error GoTo Proc_Err
FormBeforeUpdate = False
Dim nUserID As Long _
, nCount As Long
nUserID = get_UserID
With pF
If bUpdateParentToo Then
.Parent.dtmEdit = Now()
.Parent!IDedit = nUserID
End If
!dtmEdit = Now()
!IDedit = nUserID
If .NewRecord Then
!IDadd = nUserID
End If
End With
Proc_Done:
FormBeforeUpdate = True
Proc_Exit:
On Error Resume Next
Exit Function
Proc_Err:
MsgBox Err.Description, , _
"ERROR " & Err.Number _
& " FormBeforeUpdate"
Resume Next
Resume Proc_Exit
Resume
End Function
ASKER
Thanks!
Crystal:
What exactly do you mean by this? Is the Tempvar Dale suggested a Global Variable?
What Happens when it loses its value...It just becomes Blank or something?
Also For any future viewers. Here is a video of the tempvar solution on youtube. Link Here
Crystal:
Another advantage is that database properties do not lose their values like global variables sometimes do.
What exactly do you mean by this? Is the Tempvar Dale suggested a Global Variable?
What Happens when it loses its value...It just becomes Blank or something?
Also For any future viewers. Here is a video of the tempvar solution on youtube. Link Here
Dustin,
Tempvars are actually part of a collection, which can be created from the immediate window even when the application is not running (during development). Although they are similar to global variables in that they can be called from anywhere in your code, they have the added advantage that once they are set, they do not lose their value, even in the event of an unhandled error, until the application is closed. But they do lose their value, unlike the database property described by Crystal.
Many times, developers will use references to a value on a form in a query, like:
Tempvars are actually part of a collection, which can be created from the immediate window even when the application is not running (during development). Although they are similar to global variables in that they can be called from anywhere in your code, they have the added advantage that once they are set, they do not lose their value, even in the event of an unhandled error, until the application is closed. But they do lose their value, unlike the database property described by Crystal.
Many times, developers will use references to a value on a form in a query, like:
SELECT * from yourTable where [ClientID] = Forms![yourFormname].cbo_ClientID
But this query can only be run when the form is open. I use tempvars, and set the value of the tempvar in the afterupdate event of a control on a form, for example:Private Sub cbo_ClientID_AfterUpdate()
Tempvars!ClientID = me.cbo_ClientID
End Sub
Then, in my query I would use:SELECT * from yourTable where [ClientID] = [Tempvars]![ClientID]
But I don't have to have the form open to test this, I can just enter a line of code in the immediate window, like:Tempvars!ClientID = 5
and then am able to test the query. With the technique Chrystal is suggesting, your query would look like:SELECT * FROM yourTable where [ClientID] = GetProperty("ClientID")
hi Dustin,
you're welcome
>> What Happens when it loses its value...It just becomes Blank or something? <<
if there is an unhandled error, variables can lose their values. Therefore it is like the values were never set.
>> What exactly do you mean by this? Is the Tempvar Dale suggested a Global Variable?<<
TempVars is a collection so it works differently than global variables. I use them sometimes. They are preferable, in my opinion, to global variables. When Access closes, however, they are lost.
I like using database properties to keep values persistent even when Access closes (or crashes) and opens again, and explicitely declaring the data type. For example: user and privileges (local_UserID, local_PrivilegeCD), form active records (ie: local_CID, local_MyTypeID, local_CustomerID, local_OrderID, local_ProductID) for processing code behind other objects and to be put back to that record when they go there again, criteria (including the "friendly" way to say it) and other form and report options (local_Where, local_Friendly, local_View, local_Title, etc) which avoids having to send and parse OpenArgs, whether or not user has admin privileges, if BE is verified to be valid, paths (ie: to back-end, to images and templates for constructing relative addressing, opening stand-alone, using like in RecordSources to render a picture file name using a relative path in an image control), and other settings depending on the application.
thanks for the link, I'll check it out ~
[edit: I just saw Dale's comment ... he said some of the same things ... and shared some nice code :) ]
have an awesome day,
crystal
you're welcome
>> What Happens when it loses its value...It just becomes Blank or something? <<
if there is an unhandled error, variables can lose their values. Therefore it is like the values were never set.
>> What exactly do you mean by this? Is the Tempvar Dale suggested a Global Variable?<<
TempVars is a collection so it works differently than global variables. I use them sometimes. They are preferable, in my opinion, to global variables. When Access closes, however, they are lost.
I like using database properties to keep values persistent even when Access closes (or crashes) and opens again, and explicitely declaring the data type. For example: user and privileges (local_UserID, local_PrivilegeCD), form active records (ie: local_CID, local_MyTypeID, local_CustomerID, local_OrderID, local_ProductID) for processing code behind other objects and to be put back to that record when they go there again, criteria (including the "friendly" way to say it) and other form and report options (local_Where, local_Friendly, local_View, local_Title, etc) which avoids having to send and parse OpenArgs, whether or not user has admin privileges, if BE is verified to be valid, paths (ie: to back-end, to images and templates for constructing relative addressing, opening stand-alone, using like in RecordSources to render a picture file name using a relative path in an image control), and other settings depending on the application.
thanks for the link, I'll check it out ~
[edit: I just saw Dale's comment ... he said some of the same things ... and shared some nice code :) ]
have an awesome day,
crystal
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Ok so as Pat said to keep the form open at all times and make it invisible. Would you see the form tab?
When I post code on a test form with a button and click it it seems to just close completely also the tab.....Or is it actually still there????
Also Can this work on a popup form as well?
Ok I am pretty sure I answered that question. I did the unloading event with a msgbox. That is good to know! Thanks.
When I post code on a test form with a button and click it it seems to just close completely also the tab.....Or is it actually still there????
Private Sub btnButton1_Click()
On Error GoTo ErrorHandler
Me.Visible = False
Exit Sub
ErrorHandler:
MsgBox "Error " & Err.Number & ": " & Err.Description & " in " & _
VBE.ActiveCodePane.CodeModule, vbCritical, "Error"
End Sub
Also Can this work on a popup form as well?
Ok I am pretty sure I answered that question. I did the unloading event with a msgbox. That is good to know! Thanks.
hi Dustin,
you're welcome
>> Would you see the form tab? <<
No. When a form becomes not Visible, users cannot see it -- but it is still open, so code and queries and other objects can use it. Keeping a form open is also another way to increase performance for retrieving data from a back-end, if the form is bound to a table in that back-end.
>> is it actually still there???? <<
yes. To see this:
press Ctrl-G to go to the Immediate window
type:
forms!MyFormName.Visible = true
and press ENTER
WHERE
MyFormName is the name of your form, assuming the name does not have special characters (except _) or spaces
>>Can this work on a popup form as well?<<
yes -- even though the user cannot see it when Visible is not True, you can get values it stores in code, queries, and other objects.
have an awesome day,
crystal
you're welcome
>> Would you see the form tab? <<
No. When a form becomes not Visible, users cannot see it -- but it is still open, so code and queries and other objects can use it. Keeping a form open is also another way to increase performance for retrieving data from a back-end, if the form is bound to a table in that back-end.
>> is it actually still there???? <<
yes. To see this:
press Ctrl-G to go to the Immediate window
type:
forms!MyFormName.Visible = true
and press ENTER
WHERE
MyFormName is the name of your form, assuming the name does not have special characters (except _) or spaces
>>Can this work on a popup form as well?<<
yes -- even though the user cannot see it when Visible is not True, you can get values it stores in code, queries, and other objects.
have an awesome day,
crystal
ASKER
Well isn't that some Witchcraft ;)
Honestly this form idea is seeming like a best option for me. I have a few questions to clarify some things.
Would I use on the login form a Invisible Textbox say txtEmpID?
If so would I then use a dlookup to get the value of the EmpID from my employees table WHERE the Username matches the Login Forms User name?
Most of all what are the drawbacks on this way versus other ways. Especially security? (I will be keeping the table on the back end.
Thanks for all the help and clarifying all this.
Honestly this form idea is seeming like a best option for me. I have a few questions to clarify some things.
Would I use on the login form a Invisible Textbox say txtEmpID?
If so would I then use a dlookup to get the value of the EmpID from my employees table WHERE the Username matches the Login Forms User name?
Most of all what are the drawbacks on this way versus other ways. Especially security? (I will be keeping the table on the back end.
Thanks for all the help and clarifying all this.
hi Dustin,
Slick, eh? Access can do so many cool things like this ~
you're welcome
>> Would I use on the login form a Invisible Textbox say txtEmpID? <<
The form would be visible when the information is collected and then then WHOLE FORM would probably be made not visible. Individual controls would probably be visible when the user looks at the form so they can be seen, if they are meant to be seen, when the form is active.
>> If so would I then use a dlookup to get the value of the EmpID from my employees table WHERE the Username matches the Login Forms User name? <<
If all employees will be users then yes, sort of -- I would usually a numeric value, like EmpID for the UserID, not look up a string like name, but --yes, could use that table if there is a flag in there for Active or not, so past employees are still there too -- although you might want to consider a separate Usrs table for this purpose since some users, in the future perhaps?, may not be employees. DLookup would be one way of getting the value. Another is using a recordset in vba, or getting the value from a control on a form that is always open (like what Pat suggested). If the form was not open, you could also use a database property.
Another advantage, imo, of database properties is that casual browsers do not usually know how to enumerate them. Access has other database properties (AppTitle, etc), so I preface all of mine with something consistent for that application -- my examples used "local_"
>> Especially security? (I will be keeping the table on the back end. <<
if you are concerned about casual browsers, you can encrypt data for storage in tables and decrypt it for viewing by those with privileges ... this adds complexity. Alternately (not as secure but good enough for most cases), in the table design, set field property InputMask as Password and then a number of * (asterisk)s will display instead of the real data when a table is opened directly (which users shouldn't do!).
have an awesome day,
crystal
Slick, eh? Access can do so many cool things like this ~
you're welcome
>> Would I use on the login form a Invisible Textbox say txtEmpID? <<
The form would be visible when the information is collected and then then WHOLE FORM would probably be made not visible. Individual controls would probably be visible when the user looks at the form so they can be seen, if they are meant to be seen, when the form is active.
>> If so would I then use a dlookup to get the value of the EmpID from my employees table WHERE the Username matches the Login Forms User name? <<
If all employees will be users then yes, sort of -- I would usually a numeric value, like EmpID for the UserID, not look up a string like name, but --yes, could use that table if there is a flag in there for Active or not, so past employees are still there too -- although you might want to consider a separate Usrs table for this purpose since some users, in the future perhaps?, may not be employees. DLookup would be one way of getting the value. Another is using a recordset in vba, or getting the value from a control on a form that is always open (like what Pat suggested). If the form was not open, you could also use a database property.
Another advantage, imo, of database properties is that casual browsers do not usually know how to enumerate them. Access has other database properties (AppTitle, etc), so I preface all of mine with something consistent for that application -- my examples used "local_"
>> Especially security? (I will be keeping the table on the back end. <<
if you are concerned about casual browsers, you can encrypt data for storage in tables and decrypt it for viewing by those with privileges ... this adds complexity. Alternately (not as secure but good enough for most cases), in the table design, set field property InputMask as Password and then a number of * (asterisk)s will display instead of the real data when a table is opened directly (which users shouldn't do!).
have an awesome day,
crystal
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you for the help. This really set me in the right direction!
you're welcome, Dustin ~ happy to help
have an awesome day,
crystal
have an awesome day,
crystal
I like using a database property to keep track of the user for each FE since it is remembered even when you close Access -- so you only have to do this once. Alternately, if you collect the user with a login screen, you can set it then ... for cases when multiple people use the same computer
Here is code to set it:
Open in new window
WHEREsPropName is the property name -- I use "local_UserID" and myValue is the value you want to change it to. The FE does not need a list of who each UserID is.
here is code to see who the user is:
Open in new window
I put tracking fields in all tables for IDadd and IDedit -- these get updated on each form BeforeUpdate event (I call a general procedure that also updates when a record was changed)and here is the function it calls:
Open in new window
and here is the Get_Property function that is called:
Open in new window
have an awesome day,crystal