2017-10-11 206 views
6

ABC.xls文件有宏。現在,當我按Ctrl + M時,該宏有一個被調用的子。 這個小組將打開一個打開文件對話框,用戶可以在其中選擇一個CSV文件。所以基本上,這個宏用於處理和保存CSV文件。 下面是按Ctrl + M調用的代碼。防止關閉工作簿

Sub runProperChangeSubroutine()    ' Assigned to shortcut key CTRL + M. 
    file_name = ActiveWorkbook.Name   ' Gets the file name. 
    Application.Run file_name & "!ChangeSub" 
End Sub 

當用戶關閉工作簿,我要測試等每行中的CSV具有終止字符串的條件。如果該終止字符串不是 ,我應該彈出一個消息框給用戶並阻止關閉工作簿。 所以我做了以下...

Private Sub Workbook_BeforeClose(Cancel As Boolean) 
    Dim improperRowNumber As Integer 
    Dim BlnEventState As Boolean 
    improperRowNumber = returnImproperRow() 

    BlnEventState = Application.EnableEvents 
    Application.EnableEvents = True 

    If improperRowNumber <> -1 Then 
     Cancel = True 
     MsgBox "The row number " & improperRowNumber & " is not ending with '@/#'. Please correct the row before closing." 
    Else 
     Call saveCSV 
    End If 
    Application.EnableEvents = BlnEventState 
End Sub 

在接近(在右上角的X標誌,workboox。我不關閉Excel中。關閉)按鈕的點擊,我能夠看到消息但工作臺關閉。如果行沒有正確結束,我希望用戶進行一些編輯。 請建議。

被修改: 作爲上述代碼不工作,我消息框之後使用ThisWorkbook.Saved = False如下所示...

If improperRowNumber <> -1 Then 
    MsgBox "The row number " & improperRowNumber & " is not ending with '@/#'. Please correct the row before closing." 
    Application.DisplayAlerts = False 
    ThisWorkbook.Saved = False 
    Cancel = False 
Else 

現在它顯示「Do you want to save the changes....」消息框。如果我在消息框上單擊Cancel按鈕,工作簿未關閉。

是否有自定義消息框文本或按鈕或隱藏此消息框的方法?

+0

你不應該能夠與取消關閉該工作簿=真在Workbook_BeforeClose中。可能你在soubroutine improperRowNumber中有類似EnableEvents = False的東西? – MarcinSzaleniec

+0

不,EnableEvents語句不存在於improperRowNumber子中。有沒有其他的可能性? – NJMR

+0

@MarcinSzaleniec禁用了應用程序事件,msgbox不會顯示出來......但OP的處理程序顯然正在運行。 –

回答

5

如果必須監測除包含宏的另一個工作簿的最後,你可以從你的啓用宏的工作簿攔截應用級事件如下:

添加(或修改)背後的ThisWorkbook此代碼:

Option Explicit 

Private m_CloseHelper As CloseHelper 

Private Sub Workbook_Open() 
    Set m_CloseHelper = New CloseHelper 
End Sub 

添加一個名爲CloseHelper一個新的類模塊:

Option Explicit 

Private WithEvents m_App As Excel.Application 

Private Sub Class_Initialize() 
    Set m_App = Excel.Application 
End Sub 

Private Sub Class_Terminate() 
    Set m_App = Nothing 
End Sub 

Private Sub m_App_WorkbookBeforeClose(ByVal Wb As Workbook, Cancel As Boolean) 
    'Logic goes here, e.g. the code below will prevent the user from closing 
    'any workbook other than this one, for as long as this workbook is open. 
    If Not Wb Is ThisWorkbook Then 
     Cancel = True 
     MsgBox "Hello from m_App_WorkbookBeforeClose" 
    End If 
End Sub 

重要的關鍵詞是WITHEVENTS,其原理是前夜由Excel應用程序引發的nts現在可以在CloseHelper類中進行編碼。

您會在這裏找到一個更深入的文章:Application Events

0

按右上角的X按鈕退出Excel應用程序。當應用程序關閉時,您不應該期望該工作簿保持打開狀態。你可以編寫一個應用程序事件程序來防止Excel退出,但更好的方法可能是簡單地擺脫使用該按鈕的壞習慣。查找另一種關閉工作簿的方法。

+0

右上角,我的意思是關閉工作簿,我沒有關閉excel。我將編輯帖子。謝謝。 – NJMR

+0

坦率地說,我懷疑工作簿是關閉文件 - >關閉,MsgBox出現,工作簿仍然關閉。如果在這種情況下它確實被關閉,那麼這個動作應該來源於意外運行的其他代碼。但是,如果您真的面臨Excel應用程序出現故障,或者無法控制人員關閉工作簿的方式,那麼接下來要嘗試使用應用程序事件(現在您正在使用Workbook事件)來執行你已經有了相同的測試。因此,我相信我的答案仍然有效。 – Variatus

+1

我認爲如果您關閉工作簿或關閉excel,應該沒有關係。 Workbook_BeforeClose被調用的方式。 – NJMR

0

的Workbook_BeforeClose事件僅適用於該代碼所在的工作簿。它在您嘗試關閉宏工作簿並將它的參數「取消」設置爲TRUE時才運行,只有在關閉Excel時才取消關閉宏工作簿。打開的csv文件是一個單獨的工作簿,Excel試圖單獨關閉該文件,生成一條關於保存csv文件的單獨消息。

要自動防止csv文件被關閉,您需要使用擴展性編程在Excel中打開時將Workbook_BeforeClose事件添加到csv文件。很明顯,你不能保存文件中的事件,但你不需要。坐在模塊中的代碼將在工作簿仍處於打開狀態時運行,以防止在您的條件未滿足時關閉;並且在條件 met之後允許的成功保存將以.csv格式將會擦除臨時添加的代碼。

http://www.cpearson.com/excel/vbe.aspx

0

您是否嘗試關閉所有已加載項(或在安全模式下運行Excel)?

我在問,因爲這個問題可能是由於你的一個加載項包含一個應用程序級別事件,如Excelosaurus的答案中所述。它可能包含Application.EnableEvents = False甚至Cancel = False並干擾您的代碼。

編輯:這將是特別困難與被保護,因爲該代碼會後 Workbook_BeforeClose運行,你將無法知道它在做什麼,即使你被線調試線的加載項中檢測使用F8。

+0

如果禁用事件,則「Workbook_BeforeClose」事件根本不會運行。 – AjimOthy

+0

應用程序級別事件在**工作簿級別事件之後運行**,因此即使應用程序級別事件禁用事件,工作級別事件也會始終運行。 – DecimalTurn

+0

(只要在按下X按鈕之前啓用了事件) – DecimalTurn

0

您可以在工作簿中的宏

Private Sub Workbook_BeforeClose(Cancel As Boolean) 
ActiveWorkbook.Save 
Workbooks.Open Application.ActiveWorkbook.FullName 
End Sub 

使用此代碼正如你可以看到它基本上保存和打開工作簿,當它接近