Many developers within Access need to be able to detect when the user has been inactive for a while. It's quite common to have a requirement to run something if/when the system's not been used for a certain length of time. Examples range from running action queries in order to update data, to closing the database, or even Access itself, when it hasn't been used for a while.
Approach
My approach, like a number of similar ones that can be found on the web, is to detect and log the state of the currently selected form and control on the screen. I go a little further though, and detect all the forms and reports that are open in the project. It's not unusual for users, particularly those who mainly do data entry, to end up in exactly the same objects every time they finish entering a record - thus giving the impression to code which just checks which objects (Form and Control) are currently selected, that there has been no activity between checks. For that reason it's important to check the current data in the current control too.
Since Twinnyfo's question - Problem with Inactivity Detection - it is also important to ensure that this process is run regularly throughout the period of detection. If the checking is suspended at any point then the results can be misleading.
Code
Expand|Select|Wrap|Line Numbers
- 'IdleSince() returns the time of the last detected activity.
- 'NB. Code must run live (Full speed - Not tracing) to capture data correctly.
- Public Function IdleSince(Optional ByVal blnSet As Boolean = False) As Date
- Static strPrevState As String
- Static datPrevious As Date
- Dim strState As String
- Dim objVar As Object
- On Error Resume Next
- With Screen
- strState = strState & "," & .ActiveDatasheet.NAME
- strState = strState & "," & .ActiveDatasheet.SelTop
- strState = strState & "," & .ActiveDatasheet.SelLeft
- strState = strState & "," & .ActiveForm.NAME
- strState = strState & "," & .ActiveReport.NAME
- strState = strState & "," & .ActiveControl.NAME
- strState = strState & "," & .ActiveControl.Text
- End With
- On Error GoTo 0
- strState = strState & ";Forms"
- For Each objVar In Forms
- strState = strState & "," & objVar.NAME
- Next objVar
- strState = strState & ";Reports"
- For Each objVar In Reports
- strState = strState & "," & objVar.NAME
- Next objVar
- 'If we pop up a new form to notify the user then strState will change -
- ' even without human intervention - so we allow for this with blnSet.
- If strState <> strPrevState Then
- strPrevState = strState
- If Not blnSet Then datPrevious = Now()
- End If
- IdleSince = datPrevious
- End Function
Expand|Select|Wrap|Line Numbers
- ...
- If Now() >= DateAdd("n", 420, IdleSince()) Then ...
This is about detecting inactivity, rather than how to handle inactivity when found, so the parameter (blnSet) is not too relevant. However, for the curious, it was added in order to enable the code to show a form on the screen to notify the user that there has been inactivity, and potentially warn them that the system will shut itself down within a set time unless activity is detected. Obviously, showing the form would lead the procedure to detect activity when run normally, so blnSet is provided as an override.
Code Block A
Lines 04 - 05 These variables remember the values from previous calls.
Lines 09 - 19 These register all that Screen has to say on what's what and where. Some of these lines may refer to objects that aren't set - hence the error handling around these lines.
Lines 20 - 27 These lines log any forms and reports that may be be open.
Lines 30 - 33 These save the current state if necessary.
Line 34 This returns the last time activity was detected.
Code Block A
This is how a call to this procedure could be used. In this case 420 is the number of minutes that you want to check for. When this criteria has been met you can run whatever code you want that depends on this length of inactivity.
Conclusion
While this doesn't detect mouse movements, or even keystrokes, made by the user, it does detect almost all situations where activity has occurred within an Access session.