2017-02-10 237 views
3

我試圖在工作表(Excel)被刪除時觸發一個宏。 自2010年以來,有不同的刪除事件:刪除工作表/圖表事件VBA

應用程序級別:Application.SheetBeforeDelete事件。

工作簿級別:Workbook.SheetBeforeDelete事件。

工作表級別:Worksheet.BeforeDelete事件。

作爲初學者,我無法使用最後兩個,但是我嘗試應用第一個。

Private Sub Workbook_SheetBeforeDelete(ByVal Sh As Object) 
Call Macro 
End Sub 

這對工作表很好,但它不適用於圖表(僅包含圖表的工作表)。

我的目標是調整我的計數器並可能重命名工作表,因爲我的工作表被命名爲Sheetname(1),..(2)..並且用戶經常刪除工作表。

我搜索了很多,但我找不到任何可以遵循的例子。

任何幫助將不勝感激。

+0

我懷疑這是一個錯誤。當然,似乎對我來說。 – Rory

回答

2

這看起來像是一個實施監督,這個事件應該根據設計實施。實際上,Sheets系列是WorksheetsCharts系列的集合。由於事件的名稱是Workbook_SheetBeforeDelete(不是Workbook_WorksheetBeforeDelete),常識意味着該事件應適用於所有Sheets,即WorksheetsCharts

請注意,其他事件(如Workbook_SheetDeactivate)是針對圖表和工作表引發的。這確認了錯誤,但也提出了利用Workbook_SheetDeactivate事件的解決方法。

我們可以在ThisWorkbook代碼模塊中添加兩個程序。 checkChartDelete()檢查圖表是否已被刪除並啓動適當的操作。它需要通過Application.OnTime來調用,所以它通過一個靜態變量chartNameToCheck得到它的參數。

' Code Module ThisWorkbook 
Option Explicit 
Private chartNameToCheck As String 
Private Sub checkChartDelete() 
    On Error Resume Next 
    Dim x: Set x = Sheets(chartNameToCheck) 
    If Err.Number <> 0 Then 
     '********************************************** 
     ' call or do here the action on chart deleted ' 
     '********************************************** 
     MsgBox "chart deleted: " & chartNameToCheck 
    End If 
    chartNameToCheck = "" 
End Sub 

Private Sub Workbook_SheetDeactivate(ByVal Sh As Object) 
    If TypeName(Sh) <> "Chart" Then Exit Sub 
    chartNameToCheck = Sh.name 
    Application.OnTime Now, "ThisWorkbook.checkChartDelete" 
End Sub 
+0

謝謝你的解釋和代碼,它完美的作品。 – Bambuchka

+0

我注意到,如果Sub chartNameToCheck位於另一個模塊中,則不可能使用變量chartNameToCheck,有沒有辦法解決這個問題? – Bambuchka

+1

@Bambuchka'chartNameToCheck'靜態變量和'checkChartDelete'例程都可以移動到標準代碼模塊。他們需要公開(事實已經如此,儘管他們可能更擅長在WB中私有),並且應該將改進的調用改爲這個Application.OnTime現在,「checkChartDelete」(移除ThisWorkbook.) –