1

I have a subroutine invoked via Application.OnTime scheduled call.

How can I determine with Excel VBA whether the subroutine's workbook is the focused application/process in Windows?

(If it is not the active application then I will run a code that blocks the process for a little bit. If it is active I don't want to do that because I may be doing work in the workbook that I don't want interrupted.)

feetwet
  • 3,248
  • 7
  • 46
  • 84
  • 2
    `ActiveWorkbook.Name`? Ideally your objects in code would be properly qualified with a workbook object so you don't have to worry about what workbook is active. – urdearboy Apr 13 '20 at 21:05
  • 5
    `If ActiveWorkbook Is ThisWorkbook Then` – Tim Williams Apr 13 '20 at 21:28
  • @TimWilliams This doesn't work if I switch to another application. E.g., if I click over to Chrome the VBA still thinks `ActiveWorkbook Is ThisWorkbook`. – feetwet Apr 13 '20 at 21:45
  • 1
    Based on your response to Tim, you will need to use some Windows API to determine the in focus windows application. Please update your question to reflect this. – Samuel Everson Apr 13 '20 at 22:14
  • @SamuelEverson – I updated the text of my question as best I could to reflect this. Do you mean I should add one or more tags? – feetwet Apr 13 '20 at 22:20
  • Im not sure of the right tags but i'd assume there is something fkr windows API. Fyi of you or someone has an account this [Excelforums post](https://www.excelforum.com/excel-programming-vba-macros/1043238-test-if-application-has-focus.html) seems to have an answer for you - I dont have an account so cant see the code sorry. Remember tho, Google is your friend! – Samuel Everson Apr 13 '20 at 22:29
  • Also [this question on Stack Overflow](https://stackoverflow.com/q/20486944/9663006) seems to have answers that will help you – Samuel Everson Apr 13 '20 at 22:34

1 Answers1

1

Try this. I tested it and it seems to work.

On module level:

Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr

For testing purposes I wrote these 2 subs:

Sub Test()
    If GetActiveWindow <> 0 Then
          'Application in focus
          Debug.Print "Focus"
    Else
          'Application not in focus
          Debug.Print " No focus"
    End If
End Sub

Sub Timer()
    Application.OnTime Procedure:="Test", EarliestTime:=Now + TimeValue("00:00:10")
End Sub

Now, try like this:

  1. Run Timer (from the immediate window for example).
  2. Before the timer reaches the 10 seconds set, switch to another app like your internet browser for example. Wait a bit for the time to complete.
  3. Look at what the console displays:
  • If you stay on the excel window, the console will display "Focus".
  • If you switch window it will say "No focus".
Greedo
  • 4,967
  • 2
  • 30
  • 78
Lorthas
  • 376
  • 3
  • 11
  • 1
    Excellent! I edited the declaration because [it is now necessary to add `PtrSafe` for compatibility with 64-bit](https://learn.microsoft.com/en-us/office/vba/language/concepts/getting-started/64-bit-visual-basic-for-applications-overview). – feetwet Apr 15 '20 at 17:46