Inactivity Detection in Access

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • NeoPa
    Recognized Expert Moderator MVP
    • Oct 2006
    • 32669

    #1

    Inactivity Detection in Access

    Introduction

    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

    Code:
    '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
    Code:
    ...
    If Now() >= DateAdd("n", 420, IdleSince()) Then ...
    Explanation of Code

    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.
    Last edited by NeoPa; Jun 26 '14, 04:17 PM. Reason: Added comment in Approach section to cover question from Twinny.
  • twinnyfo
    Recognized Expert Moderator Specialist
    • Nov 2011
    • 3665

    #2
    NeoPa,

    I have some code that functions similarly, but looks completely differently at "idle" time, because it looks at the last user input, using a call to user32.dll.

    However, my code does detect mouse movements and other keystrokes, whether or not they are within the Access environment. My goal is to shut Access if the workstation has been left unattended (thus closing all links to the network BE).

    I guess an advantage of your code is that if a user is working in another application, Access can still recognize itself as being "idle". I can see some uses for that in some specific situations.

    Very interesting approach, and, as usual, you have taught me something I can probably use in the future.

    Thanks for the article!

    Grace and Peace,
    Twinnyfo

    Comment

    • NeoPa
      Recognized Expert Moderator MVP
      • Oct 2006
      • 32669

      #3
      My aim was to provide a specifically MS Access way to detect idleness.

      I suspect that OS functions do indeed give greater power and control in this area, but many prefer to avoid going off-piste, as it were, for good reasons. Principal of which, to my mind, is that it leaves a more easily supported and maintained project, as many Access developers are very nervous about using OS features..

      Don't get me wrong - I do use OS features sometimes, but I try strenuously to avoid them.

      Comment

      • zmbd
        Recognized Expert Moderator Expert
        • Mar 2012
        • 5501

        #4
        Neopa: ... Don't get me wrong - I do use OS features sometimes, but I try strenuously to avoid them ...
        I second that!

        and I have to have 20 characters to make a post.

        Comment

        • NeoPa
          Recognized Expert Moderator MVP
          • Oct 2006
          • 32669

          #5
          Me too ;-)

          Comment

          Working...