Monitoring Logged In Users in MS Access 2016 - vba

I have a form on a tab that I use to monitor users who are logged in to my application.
The table is called USysRollCall (prefixed with USys to automatically make it invisible as a system table if access is gained to the navigation pane)
Only 3 fields are necessary: UserName (string) , As_of (date) and Logged_In (boolean)
All new users are automatically added to the UsysRollCall table
A "frm_Invisible" form launches with my main form and remains in the background. On the load and unload event of this form, I call the following routine like this:
Upon logging in: UserActive(AcquireUser, True)
Upon Logging Out UserActive(AcquireUser, False)
Public Sub UserActive(strUserName As String, bTrueFalse)
If bTrueFalse = True Then
CurrentDb.Execute "UPDATE USysRollCall SET Logged_In =-1, As_of=#" & Now & "# WHERE UserName='" & strUserName & "';"
Else
CurrentDb.Execute "UPDATE USysRollCall SET Logged_In =0, As_of=#" & Now & "# WHERE UserName='" & strUserName & "';"
End If
End Sub
'The following function can be used any time to get the username. It also serves a dual purpose of automatically taking necessary actions to add a new username to the user table if it is called and a username is not in the table. (not provided for this example)
Public Function AcquireUser() As String
'Returns the username
'but checks to see if it is in the table - if not... it adds it to the table as the lowest security level
Dim strUserName As String
strUserName = GetUserName
If Len(CheckUser(strUserName)) = 0 Then
MsgBox "Will be adding " & strUserName & " to the database"
AddUser (strUserName)
AcquireUser = strUserName
'MsgBox GreetUser(strUSERNAME), vbInformation, "Welcome"
Else
AcquireUser = strUserName
End If
End Function
I can verify that when I login and check the backend table, UsysRollCall I see a check in the Logged_In box. I can also verify that no matter how I close the database i.e. appropriately by using my quit button - or even just using the close X in the top right, that it still effectively logs me out.
I cannot verify what causes people to remain "Logged_In"
Is there a piece I am missing?

Related

MS Access - Main menu form with 2 text boxes used to open and filter a different form - getting a type mismatch (Run error 13)

I have a main menu where users type in a name of a station (text box) and the name of a cohort (text box) and it would open a new form based on these values. For example, if "New York" was entered for a station and "1b" was entered for cohort, then the form would filter to only show data that have both. However, I am getting a data mismatch error.
The fields text boxed at my main menu are called "detailed_s_station" and "detailed_s_cohort". The names of the respective fields in the form I want to filter these values are called "station" and "cohort".
I can get this to work if there are only one set of criteria (e.g., if I just search for the cohort or just search for the station), however something is going on with my AND here. Any help is appreciated to help me get rid of this data mismatch error.
Private Sub Command41_Click()
Dim stDocName22 As String
Dim stLinkCriteria22 As String
stDocName22 = "frm_scans"
stLinkCriteria22 = "[station] ='" & Me![detailed_s_station] & "'" And "[cohort] ='" & Me![detailed_s_cohort] & "'"
DoCmd.OpenForm stDocName22, , , stLinkCriteria22, acFormEdit, acWindowNormal
End Sub
The problem that you are having is how you are joining the string together. Instead try:
Private Sub Command41_Click()
Dim stDocName22 As String
Dim stLinkCriteria22 As String
stDocName22 = "frm_scans"
stLinkCriteria22 = "[station] ='" & Me![detailed_s_station] & "' And [cohort] ='" & Me![detailed_s_cohort] & "'"
DoCmd.OpenForm stDocName22, , , stLinkCriteria22, acFormEdit, acWindowNormal
End Sub
If you ever have problems like this in future, a quick Debug.Print strLinkCriteria22 would show you the contents of the string that is causing problems.
Regards,

Stop popup window to fill parameter in query

I setup a textbox ("custlookup") which takes a business ID, then when I press the "Search/Update customer" button, it takes me to a previously created form to update that particular customer details, using a macro (On_Click) and in the where clause I specified the following:
WHERE = custlookup[Forms]![WelcomeMenu]![custlookup]=[CustomerFACT]![customer_id]
yet when I give an ID and press the "Search/Update customer" I get a popup window asking me to "enter parameter value" and I don't know why. In previous buttons (which do the same for in different forms) it works fine, AND RELY ON THE SAME "custlookup" textbox.
After cancelling the macro and trying in code:
Private Sub button7_Click()
DoCmd.OpenForm "loanupdateform", , , "[custlookup] = '" & [CustomerFACT]![cust_id] & "' And [LownFACT]![history_ind] ='" & True & "'"
End Sub

When setting user permissions to open up a particular form for a particular user I am getting a Runtime error from the DLookup statement

I am trying to restrict the availability of a form to be opened by a user. the following code picks up on the correct user access type and the correct form name, however i am getting the runtime error 2471. I would appreciate some help here as i cannot see what is wrong?
The error statement in this case is: Run-Time error '2471': The expression you entered as a query parameter produced this error: 'Stock'. When i go to debug it brings me to the DLookup and i cannot see what is wrong.
Watch expression:Watch : : "Employeeaccesstype =" & cable & " " & "AND FormName=" & thisform : "Employeeaccesstype =0 AND FormName=Stock" : String : Form_Stock.Form_Load
Private Sub Form_Load()
Dim cable As String
cable = TempVars("AccessType")
Dim thisform As String
thisform = Me.Form.Name
If DLookup("Hasaccess", "tblemployeeaccess", "Employeeaccesstype =" & cable & " " & "AND FormName=" & thisform) = False Then
DoCmd.Close
MsgBox "You Do Not Have Access"
End If
End Sub
All help will be most appreciated as i am on a deadline to finish this
If your fields Employeeaccesstype and FormName are text, then the values in the Dlookup need to be wrapped in single quotes. Additionally, you should cater for the possibility that the record doesn't exist in the table (returning a Null value from the DLookup):
If Nz(DLookup("Hasaccess", "tblemployeeaccess", "Employeeaccesstype ='" & cable & "' AND FormName='" & thisform & "'"),False) = False Then
You should also consider not actually allowing them to open the form in the first place.
Regards,
I changed tack here and went for a different approach. I created a new table to hold user login details and a query to join details on tables and referenced that on the Dlookup rather than trying to reference the login form through a variable. Witth those changes made i changed the DLookup to
If DLookup("Hasaccess", "AccessQuery", "HasAccess =false and Formname = 'Part' ") =
False Then
DoCmd.Close
MsgBox "You Do Not Have Access"
End If
This is now working correctly. Many thanks o Applecore for the assistance with this problem

Can't Go To Specific Record on Continuous Form in MS Access

Searched and searched and cannot find a solution to this. I have a form with many continuous form subforms. When I change a value in, lets say FIELD_A on one of the subforms, I run calculations on several other subforms, then the focus returns to FIELD_A. However, during the calculations an update to the PARENT form happens, and needs to happen. So, when I return focus to the original subform, the first record on my subform has the focus. I need to then go to the record I was working on.
I've tried several options, but nothing works. However, if I set a DEBUG breakpoint at the line in the code where it moves to the specified record, then physically RUN the code from that line, it works! I've tried setting a wait period in there to no avail.
Here's a snippet of the code:
Call common.CalculateAllLoadTotals _
(Me, Me.AffiliateID, Me.ClientID, Me.FacilityID, Me.ProposalRevision)
Me.Recordset.FindFirst "[AffiliateID] = '" & Me.AffiliateID & "'" & _
" AND [ClientID] = " & Me.ClientID & _
" AND [FacilityID] = " & Me.FacilityID & _
" AND [ProposalRevision] = " & Me.ProposalRevision & _
" AND [EquipmentID] = " & currItemID
I also tried this:
dim currRecord as Long
currRecord = Me.CurrentRecord
' >>> REST OF CODE HERE <<<
Call common.CalculateAllLoadTotals _
(Me, Me.AffiliateID, Me.ClientID, Me.FacilityID, Me.ProposalRevision)
Me.Form.Recordset.Move = currRecord
As I said, the code works (either one) IF I pause it with a debug then continue executing. Strange.
Sorry that's will not be a complete answer but it is quite lot for a comment.
Regarding your first solution - I'd advise you to try Me.Recordset.Requery
to refresh current record in the main form without moving position.
Regarding you 2nd option - I'd advise to have a look at bookmarks - before update remember bookmark, make some calculations and then move position to the saved bookmark. Something like this -
Dim rs As DAO.Recordset
Set rs = Me.RecordsetClone
rs.FindFirst "[MyPK]=" & Me!cmbFindByPK
If Not rs.NoMatch Then
If Me.Dirty Then
Me.Dirty = False
End If
Me.Bookmark = rs.Bookmark
End If
Set rs = Nothing
taken from here Why clone an MS-Access recordset?
I suspect you are updating the recordset underlying the parent form. This causes the parent form to automatically requery, hence the subform position returning to the first record.
The solution is to update the controls on the parent form instead:
Me.Parent!Controlname = XXXX

Open new instance of a form based on data in field of first form

I have a data entry form where the data clerk enters client ID among other things. Client ID's are unique to each client. I am currently trapping for duplicate ID's and allowing the clerk to go to the search form and seach for the duplicate ID to verify that it is indeed the same person and not an error inputting data. I would rather open a new instance of the data entry form based on the client ID inputted into the data entry form. I can open a new instance but am not sure how to make it display the client data based on the client ID.
There is no good way to do this except to just turn off the screen painting. Here's some code from one of my apps:
Dim frm As Form_frmInventory
Dim strRecordsource As String
Dim intType As Integer
DoCmd.Hourglass True
Application.Echo False
Set frm = New Form_frmInventory
frm!boxHeader.BackColor = 3276900 ' 5483007
frm!boxFooter.BackColor = 3276900 ' 5483007
strRecordsource = "SELECT qryInventoryForm.*, varZLStoNull(IIf([tblInventory].[InventoryClass] In ('BKS','FAC','MTH','MUS','REF','SSC'),[Creator] & [Dates] & OtherAuthors([OtherAuthors]))) AS BibCreator, CreatorDates([Birth],[Death],[OtherAuthors]) AS Dates, varZLStoNull(Trim(nz(UCase([tblBib_Authors].[LastName]) & IIf(Not IsNull([tblBib_Authors].[FirstName]),', ') & [tblBib_Authors].[FirstName],'Anon.'))) AS Creator, tblBib_Authors.CreatorCategories, Nz([CreatorSort],[LastName] & [FirstName]) AS NameSort FROM qryInventoryForm LEFT JOIN tblBib_Authors ON qryInventoryForm.CreatorID = tblBib_Authors.CreatorID WHERE ([quantity]>0 Like getSold()) AND (qryInventoryForm.InventoryID=" & lngInventoryID & ") ORDER BY Nz([CreatorSort],[LastName] & [FirstName]), InventoryClass, ShortTitle;"
frm.RecordSource = strRecordsource
' need to change the caption and disable certain things
frm.Caption = frm.Caption & " -- " & frm!InventoryClass & "-" & Nz(frm!InventoryNo, Format(frm!InventoryID, "00000"))
frm!fldShortTitle.SetFocus
frm!cmbClassFind.Enabled = False
frm!cmbCreatorFind.Enabled = False
frm!cmbInventoryNumber.Enabled = False
[etc.]
frm.Visible = True
GoTo exitRoutine
CloseForm:
Call CloseForm(Me, True)
exitRoutine:
Application.Echo True
DoCmd.Hourglass False
Exit Sub
The CloseForm() sub is pretty important, as you have to keep track of multiple instances of the form and close the right one. I got the code from the ADH97 and adapted it from there (just the basics).
It would appear from that code (I've forgotten the details) that a form instantiated with Set frm = New Form_frmInventory is not visible until you explicitly reveal it. That's a plus, as it should mean that you don't have to turn off the screen (i.e., Application.Echo False), but I'm pretty sure that I recall needing it anyway to make things appear smoothly. My memory is that the form would appear with its normal colors and then the background colors would change visibly as the code ran. This means it was visible, so I'm not sure why it's necessary to then explicitly set the form visible.
Anyway, that should get you started, I think!