2010-03-29 41 views
7

每天,一個人需要檢查具體的工作簿是否已經根據彭博和路透市場數據正確更新;即所有數據都已經通過並且'數字看起來正確'。過去,人們並沒有檢查導致其他系統上傳不準確的「數字」。如何正確有效地使用WorkbookBeforeClose事件?

的想法是,「東西」需要發展,防止關閉使用/保存工作簿,除非他/她已經檢查了更新正確/準確。 numbers look correct動作純粹是一種直觀的練習,因此不會以任何方式進行編碼。

簡單的解決辦法是之前關閉所述特定工作簿,以驗證該數據已被檢查提示用戶。

使用VSTO SE爲Excel 2007,外接程序創建其中掛鉤到其被初始化在外接ThisAddIn_Startup

private void wb_BeforeClose(Xl.Workbook wb, ref bool cancel) 
{ 
    //.... snip ... 

    if (list.Contains(wb.Name)) 
    { 
     DailogResult result = MessageBox.Show("some message", "sometitle", MessageBoxButtons.YesNo); 

     if (result != DialogResult.Yes) 
     { 
      cancel = true; // i think this prevents the whole application from closing 
     } 
    } 
} 

我已經找到了WorkbookBeforeClose事件以下ThisApplication.WorkbookBeforeSave vs ThisWorkbook.Application.WorkbookBeforeSave其中建議,一要使用ThisApplication.WorkbookBeforeClose事件,我認爲這是我正在做的事情,因爲將跨越所有打開的文件。

我使用該方法的問題是,假設我打開了幾個文件,其中一些文件位於我的list中,該事件阻止Excel順序關閉所有文件。現在要求每個文件分別關閉。 編輯:發生這種情況時退出Excel從文件菜單中使用。

問題

  1. 我是否正確使用WorkbookBeforeClose事件,這是有效的&有效地利用事件的?
  2. 我應該使用應用程序級事件 或文檔級別的事件
  3. 是正常上述行爲?

    擺弄周圍,我也試過,嘗試從綁定的情況如下:

  4. 任何其他建議可在附加

更新[30-MAR-2010]使用在工作簿事件時歡迎從上面的鏈接建議打開的每個工作簿的BeforeClose事件處理程序。

private void ThisAddIn_Startup(...) 
{ 
    // snip 
    Globals.ThisAddin.Application.WorkbookOpen += Application_Open; 
} 

private void Application_Open(XL.Workbook wb) 
{ 
    wb.BeforeClose += Document_WorkbookBeforeClose; // method does the same as above 
} 

,我發現這種方法的問題是,是我試圖關閉所有的Excel文件(使用退出Excel選項)事件處理程序不執行。根據我的觀察,當要檢查的文檔不是活動文檔時會發生這種情況。相比我最初的做法

這種方法似乎飄忽不定。每當文檔打開時,我不確定或感到舒服的一件事情就是綁定事件。

更新[07-APR-2010]:

格倫建議的回答是有用的,但不解決手頭現有的問題,我就此澄清了最後一個問題有點進一步。

我還發現這個博客How to Get an Excel VSTO Workbook Closed Event這是我的問題,因爲它可以替代的方法中使用顯示器型的方法來處理工作簿(並且還可能使用新引進的OnWorkbookClosed事件來我的解決方案有些相關)。

更新[08-APR-2010]:

似乎有一些混亂,我不擔心在工作簿任何驗證自己,但我寧願該方法是否正在使用(即使用的應用程序級別WorkbookBeforeClose事件)是正確的。 下面@Mathias的評論顯示了與問題3有關的部分問題的正確理解,我認爲這是默認的excel行爲。克服這個問題的解決方案是創建一個關閉功能,只關閉我的特定文件。

  • 是正常上述行爲? 是的,但是爲什麼? 由於插件掛接到應用程序級別的事件中,事件的檢查和取消會阻止應用程序關閉任何其他工作簿。這裏的關鍵是ref bool cancel參數(cancel=false允許工作簿(默認)正常關閉,cancel=true防止關閉工作簿)

  • VS 2005 VSTO SE

    +1

    只是爲了確保我正確地理解你的問題,這是你心目中的場景:用戶文件A,B,C開>關閉的Excel(退出Excel)>的回答是肯定要關閉,沒有到文件B. 你目前有什麼:Excel取消關閉A和B和C. 你想要什麼:Excel關閉A,保持B打開,並繼續詢問C是否應該關閉。 我能正確理解你的問題嗎?即您的問題是當用戶退出Excel時,您希望能夠關閉可以關閉的文件,並且只保留需要驗證的文件。 – Mathias 2010-04-07 18:50:28

    +0

    另外我開始玩這個遊戲,並且2種方法(在應用程序級別或工作簿級別關閉的工作簿)在我的機器上的行爲方式完全相同。 – Mathias 2010-04-07 18:53:39

    +0

    @mathias - 確切地說,我需要進一步更新問題,因爲我設法實現了你所描述的 – Ahmad 2010-04-08 05:14:19

    回答

    6

    應用級WorkbookBeforeClose是使用一個。問題在於,當調用WorkbookBeforeClose時,文件未被保存導致不穩定的行爲。如果不是,Save事件將會啓動,並且您現在已經有效地丟失了事件,因爲它已經發生。這裏有一些幫助解決這個問題的VBA代碼。

    Private Sub Workbook_BeforeClose(Cancel As Boolean) 
        If Not Me.Saved Then 
         NotSavedPrompt = Me.Name & " has not been saved. Would you like to save now?" 
         SaveYesNo = MsgBox(NotSavedPrompt, vbQuestion + vbYesNoCancel) 
         Select Case SaveYesNo 
          Case vbYes 
           Me.Save 
          Case vbNo 
           Me.Saved = True 
          Case vbCancel 
           Cancel = True 
           Exit Sub 
          End Select 
        End If 
        Call MyRoutine() //'this should be your sub that does what you want 
    End Sub 
    
    +0

    艾莫迄今爲止最好的答案,涵蓋了我的大部分問題。 – Ahmad 2010-04-08 18:33:42

    +0

    @Ahmad:謝謝,讓我知道如果你有任何進一步的問題或疑慮。 – 2010-04-09 01:48:50

    +0

    我剛剛意識到,我的C#方法簽名看起來不同於您的Application_WorkbookBeforeClose(Xl.Workbook wb,ref bool cancel)' - 您確定這是您的代碼中的應用程序級事件方法嗎? – Ahmad 2010-04-09 09:17:03

    3

    既然你正在運行用這種方法解決問題,Excel可能不會讓你做你需要的,也許你可以考慮另一種方法來解決整體問題。

    您可以根據是否有人驗證了這些數字,將其標記爲「已驗證/未驗證」的工作簿?根據工作簿的實際使用方式(不清楚問題),將其顯示爲未驗證的方式可能會有所不同...(可視化)將背景顏色設置爲淺色的紅色,或者(編程式)將使用的名稱範圍指向一個空白區域,以便其他插件/宏不會找到數據。

    要驗證工作簿的用戶需要單擊按鈕(在工作簿或工具欄中)以指示他們已驗證它。然後,您的代碼將撤銷上述更改並設置一個標誌,指示該工作簿已被驗證。這可能位於書中某個隱藏的單元格中,也可能位於VBA模塊的屬性中。

    要重述...打開,請檢查旗幟。如果未設置,請將工作簿更改爲未驗證。如果已設置,則不需要更改。當用戶驗證工作簿時,設置標誌並永久保存。

    希望這有助於!

    +0

    請讓我知道我在哪裏表明我遇到問題 - 我可以澄清更多的問題.. – Ahmad 2010-04-04 06:02:00

    +0

    嗯..我喜歡驗證/未驗證狀態的想法(這可能是我未來可能的事情)。我正在考慮一種儀表板樣式方法(臨時工作簿),該方法按工作簿/每個工作表進行細分,以獲得完整的狀態概覽,而不是工作簿標記。然而,我不能在工作簿中添加/修改任何內容,因爲這些是規定的格式,我可以在保存之前刪除或返回到原始狀態,但我不喜歡。 – Ahmad 2010-04-04 06:08:41

    +0

    對於「狀態」,您可以將該值保存到文件的VBA屬性中。或者添加一個隱藏的工作表。或者給特定單元格添加註釋... – 2010-04-05 04:22:16

    1
    1. 我是否正確使用WorkbookBeforeClose事件,這是有效的&有效地利用事件的?

      我找不到任何更好的事件來使用。但是,我認爲另一個辦法是有一個使用WorkbookBeforeSave事件

    2. 我應該使用應用程序級事件 或文檔級別的事件 Save&Close功能?

      在寫這篇文章時,我會說是。由於我無法使用我擁有的工具創建文檔級外接程序,因此這是可用的最佳解決方案。如果可用的工具是 ,我將修改相關文件的_AssemblyName_AssemblyLocation文檔屬性。但是,我會通過使用模板並根據需要保存文件來更改解決方案策略。另外,在保存之前,如果沒有充分探索這些,可以添加/刪除正確的文檔屬性。文檔級事件將非常適合使用上述方法。

    3. 上面描述的行爲是否正常?

      是的,但是爲什麼?由於插件掛接到應用程序級別的事件中,事件的檢查和取消會阻止應用程序關閉任何其他工作簿。這裏的關鍵是ref bool取消參數(取消= false允許正常關閉工作簿(默認),取消= true可防止工作簿關閉)。如果我在這裏錯了,請告訴我。在附加

      使用一個工作簿事件時,見上面的替代方法和使用不同的事件的答案

    4. 任何其他建議都歡迎。

    相關問題