Results 1 to 13 of 13

Thread: User idle time

  1. #1
    2 Star Lounger
    Join Date
    Mar 2004
    Posts
    185
    Thanks
    37
    Thanked 1 Time in 1 Post

    Arrow

    In VBA (running Acces) how can I determine that the mouse & keyboard have not been used (for ANY application) for a given period of time? Alternativelly, (less desired) that the screen saver is running? Resolution to the nearest minute is OK.
    Peter

  2. #2
    Plutonium Lounger
    Join Date
    Mar 2002
    Posts
    84,353
    Thanks
    0
    Thanked 29 Times in 29 Posts
    Paste the following code at the top of a module:
    Code:
    Private Type LASTINPUTINFO
      cbSize As Long
      dwTime As Long
    End Type
    
    Private Declare Sub GetLastInputInfo Lib "user32" (ByRef plii As LASTINPUTINFO)
    
    Private Declare Function GetTickCount Lib "kernel32" () As Long
    The following function will return the time (in seconds) that the system has been idle:
    Code:
    Function IdleTime() As Single
      Dim a As LASTINPUTINFO
      a.cbSize = LenB(a)
      GetLastInputInfo a
      IdleTime = (GetTickCount - a.dwTime) / 1000
    End Function
    You can use this function in your code. Note that if you execute

    Debug.Print IdleTime

    from the Immediate window, it will always return 0, because pressing Enter resets the idle time. You can test the code as follows:
    Code:
    Sub PrintIdleTime()
      Debug.Print IdleTime
    End Sub
    
    Sub Test()
      Application.OnTime Now + TimeSerial(0, 0, 5), "PrintIdleTime"
    End Sub

  3. #3
    Platinum Lounger
    Join Date
    Feb 2001
    Location
    Weert, Limburg, Netherlands
    Posts
    4,812
    Thanks
    0
    Thanked 0 Times in 0 Posts
    You know Hans, I had been looking for this piece of code, thanks!
    Jan Karel Pieterse
    Microsoft Excel MVP, WMVP
    www.jkp-ads.com
    Professional Office Developers Association

  4. #4
    3 Star Lounger
    Join Date
    Mar 2001
    Location
    Canton, Ohio, USA
    Posts
    270
    Thanks
    3
    Thanked 0 Times in 0 Posts
    [quote name='HansV' post='770346' date='13-Apr-2009 15:17']Paste the following code at the top of a module:
    Code:
    Private Type LASTINPUTINFO
      cbSize As Long
      dwTime As Long
    End Type
    
    Private Declare Sub GetLastInputInfo Lib "user32" (ByRef plii As LASTINPUTINFO)
    
    Private Declare Function GetTickCount Lib "kernel32" () As Long
    The following function will return the time (in seconds) that the system has been idle:
    Code:
    Function IdleTime() As Single
      Dim a As LASTINPUTINFO
      a.cbSize = LenB(a)
      GetLastInputInfo a
      IdleTime = (GetTickCount - a.dwTime) / 1000
    End Function
    You can use this function in your code. Note that if you execute

    Debug.Print IdleTime

    from the Immediate window, it will always return 0, because pressing Enter resets the idle time. You can test the code as follows:
    Code:
    Sub PrintIdleTime()
      Debug.Print IdleTime
    End Sub
    
    Sub Test()
      Application.OnTime Now + TimeSerial(0, 0, 5), "PrintIdleTime"
    End Sub
    [/quote]

    Hans,
    As you know, I know very little about VBA..and what I do know is learned from your posts in the forum either direct answers to my questions or answers you provide to others. My question is can the script above be modified for MS Word? I would be looking to use it in Word xp. Thanks. JimC

  5. #5
    Plutonium Lounger
    Join Date
    Mar 2002
    Posts
    84,353
    Thanks
    0
    Thanked 29 Times in 29 Posts
    Hi Jim,

    This code works in Word too, without any modification.

  6. #6
    2 Star Lounger
    Join Date
    Mar 2004
    Posts
    185
    Thanks
    37
    Thanked 1 Time in 1 Post
    Hans,
    Thanks for the code - you have answered my question exactly. However it does lead to a follow up!

    My application is suposed to be running a large part of the time while the user is doing other things, both on and off the pc. Just putting your code into the top level forms code in a loop which then trigers internal events every X minutes of idle time will use up CPU time to no good purpose. Is there any way of getting the system to trigger this part of my code periodically? Say every minute? I would assume that if there is, this would be based on a timer interupt into the exec, which would be more cpu economical than having my loop running all the time. Or is this a wrong view of how Windows operates? Since there are many processes running would my app only get a look in on a polled basis (assuming none of it's trigger events had ocoured.) If this is a beter description then just looping round your code for the time my code is active would be OK. Or what?

    Peter

  7. #7
    Plutonium Lounger
    Join Date
    Mar 2002
    Posts
    84,353
    Thanks
    0
    Thanked 29 Times in 29 Posts
    You could use Application.OnTime as in the example I posted. This doesn't use a VBA loop, but an efficient Windows timer.

    For example:

    Code:
    Sub ExecAfter5Mins()
      If IdleTime > 60 * 5 Then
    	' Do something here
    	Beep
      End If
      ' Run self after 1 minute
      Application.OnTime Now + TimeSerial(0, 1, 0), "ExecAfter5Mins"
    End Sub
    This version will execute some code (here only "Beep") each time the computer has been idle for approximately 5 minutes. If you want to run the code only once:

    Code:
    Sub ExecAfter5Mins()
      If IdleTime > 60 * 5 Then
    	' Do something here
    	Beep
      Else
    	' Run self after 1 minute
    	Application.OnTime Now + TimeSerial(0, 1, 0), "ExecAfter5Mins"
      End If
    End Sub

  8. #8
    2 Star Lounger
    Join Date
    Mar 2004
    Posts
    185
    Thanks
    37
    Thanked 1 Time in 1 Post
    Hans,
    I am having trouble with the code - version 2. looked op OnTime and found the spec. I says this is for excell 2003. I added the only Excel library I have in my list of references - which is Excell 10.0 Object Library. I still get the same error mesage. Is Excell 10.0 before 2003? and hence does not have this function?
    ---------------------------
    Microsoft Visual Basic
    ---------------------------
    Compile error:

    Method or data member not found
    ---------------------------
    OK Help
    ---------------------------

    - pointing at Ontime. If I comment out the line with OnTime in it I get no other errors.

    when I try to compile or run.

    Am I missing the relevant library? I currently have
    Visual Basic For Applications
    Microsoft Access 10.0 Object Library
    Microsoft DAO 3.6 Object Library
    OLE Automation
    Microsoft Visual Basic for Applications Extensibility 5.3
    Adobe Illustrator CS2 Type Library
    UA OLE Control module

    BTW I have VBA 6.3

    My code looks like -

    Option Compare Database
    Option Explicit
    Private Type LASTINPUTINFO
    cbSize As Long
    dwTime As Long
    End Type

    Private Declare Sub GetLastInputInfo Lib "user32" (ByRef plii As LASTINPUTINFO)

    Private Declare Function GetTickCount Lib "kernel32" () As Long

    Dim dbs As Database ' for this database only
    Dim .............

    Public Sub Form_Open(Cancel As Integer)
    'When the Main switchboard is opened, open database and display the latest data on the switchboard

    Set dbs = CurrentDb()
    Dim .............

    Test
    End Sub

    Function IdleTime() As Single
    Dim a As LASTINPUTINFO
    a.cbSize = LenB(a)
    GetLastInputInfo a
    IdleTime = (GetTickCount - a.dwTime) / 1000
    End Function

    Sub PrintIdleTime()
    Debug.Print IdleTime
    End Sub

    Sub Test()
    Application.OnTime Now + TimeSerial(0, 0, 5), "PrintIdleTime"
    End Sub
    ..........

  9. #9
    Plutonium Lounger
    Join Date
    Mar 2002
    Posts
    84,353
    Thanks
    0
    Thanked 29 Times in 29 Posts
    I apologize - OnTime is for Word and Excel, not for Access. Adding the Excel object library would be overkill.

    In Access, you can set the TimerInterval property of a form to for example 60000 (milliseconds, i.e. 60 seconds or 1 minute), and put code in the On Timer event of the form.

    Code:
    Private Sub Form_Timer()
      If IdleTime > 5 * 60 Then
    	' do something
    	Beep
      End If
    End Sub

  10. #10
    2 Star Lounger
    Join Date
    Mar 2004
    Posts
    185
    Thanks
    37
    Thanked 1 Time in 1 Post
    Hans,
    But wont that just monitor activity on my application? I need to monitor user activity on any and all applications - that is any use of mouse or keyboard at all.
    Peter

  11. #11
    3 Star Lounger
    Join Date
    Mar 2001
    Location
    Canton, Ohio, USA
    Posts
    270
    Thanks
    3
    Thanked 0 Times in 0 Posts
    [quote name='HansV' post='770433' date='14-Apr-2009 09:26']Hi Jim,

    This code works in Word too, without any modification.[/quote]

    Hans,
    Many thanks for the confirmation...off to play with the code now. Take care.
    Jim

  12. #12
    Plutonium Lounger
    Join Date
    Mar 2002
    Posts
    84,353
    Thanks
    0
    Thanked 29 Times in 29 Posts
    The IdleTime function returns the time the entire system hasn't had keyboard or mouse input, not just your application.

  13. #13
    2 Star Lounger
    Join Date
    Mar 2004
    Posts
    185
    Thanks
    37
    Thanked 1 Time in 1 Post
    [quote name='HansV' post='770480' date='14-Apr-2009 17:37']I apologize - OnTime is for Word and Excel, not for Access. Adding the Excel object library would be overkill.

    In Access, you can set the TimerInterval property of a form to for example 60000 (milliseconds, i.e. 60 seconds or 1 minute), and put code in the On Timer event of the form.

    Code:
    Private Sub Form_Timer()
      If IdleTime > 5 * 60 Then
    	' do something
    	Beep
      End If
    End Sub
    [/quote]

    Hans,
    Magic!
    Thanks again1
    Peter

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •