How to detect when a workbook is closing?

后端 未结 6 2387
后悔当初
后悔当初 2021-02-15 13:12

The Workbook.BeforeClose event triggers when the workbook is about to close but before the saving message prompt which allows cancelling it.

How can I detect when the wo

6条回答
  •  执念已碎
    2021-02-15 14:03

    I think trying to cancel the close event is the wrong approach for what you are trying to do. A better approach would be to have a function that is only called when the workbook is actually closing.

    Thank you for the comments regarding OnTime not being called while the dialog is open as that pointed me in the right direction. What we need to test is the time between the workbook deactivation and the closing of either the workbook itself or the save dialog. Using the Excel.Application.OnTime function to set this close time means this is possible as it can be delayed until the save dialogue has closed.

    Once we have this time, a simple comparison to the deactivation time allows us to decide whether to call the exit function or not.

    I initially ran into issues with the workbook reopening to run the .OnTime procedure, so an artificial delay needs to be added into the Deactivation function so the workbook hasn't closed until the close time has been set. Using the code from here - Delay Macro to allow events to finish we can accomplish this.

    In ThisWorkbook

    Option Explicit
    
    Private Sub Workbook_BeforeClose(Cancel As Boolean)
        Excel.Application.OnTime EarliestTime:=Now, Procedure:="SetCloseTime"
    End Sub
    
    Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
        If Timer < CloseTime + 0.2 Then Call CloseProcedure
    End Sub
    
    Private Sub Workbook_Deactivate()
        Delay (0.3)
        If Timer < CloseTime + 0.4 Then Call CloseProcedure
    End Sub
    

    In a module

    Option Explicit
    
    Public CloseTime As Single
    
    Function SetCloseTime()
        CloseTime = Timer
    End Function
    
    Function Delay(Seconds As Single)
        Dim StopTime As Single: StopTime = Timer + Seconds
        Do While Timer < StopTime
            DoEvents
        Loop
    End Function
    
    Function CloseProcedure()
        MsgBox "Excel is closing"
    End Function
    

    The .OnTime seems to run within one second cycles which dictates the length of the delay and the time difference test has a little leeway added with an additional 1/10th of a second (which I found necessary). These timings could potentially need slight tweaking but have so far worked for me with the different scenarios when closing the workbook.

提交回复
热议问题