Excel宏在personal.xls中运行,但不在任何其他工作簿中运行

时间:2014-08-16 15:20:45

标签: excel vba excel-vba

我已在我的c:\program files (x86)\microsoft office\office11\xlstart\personal.xls中放置了以下宏:

Option Explicit

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
' http://stackoverflow.com/questions/15267796/macro-to-make-a-backup-while-saving-a-file
' http://office.microsoft.com/en-us/excel-help/deploy-your-excel-macros-from-a-central-file-HA001087296.aspx

  Dim BackupName As String

  MsgBox "ActiveWorkbook.Name: " & ActiveWorkbook.Name   'For debugging
  BackupName = ActiveWorkbook.Name
  BackupName = Mid(BackupName, 1, InStrRev(BackupName, ".")) & "bak"
'For testing    BackupName = "D:\temp\" & BackupName    'For testing
  BackupName = ActiveWorkbook.Path & "\" & BackupName

  ActiveWorkbook.SaveCopyAs BackupName
End Sub

根据我的理解(例如上面提到的第二个链接),这应该在每次保存任何工作表时运行,但这不会发生。
仅当我(编辑并)保存personal.xls时,才会看到MsgBoxpersonal.bak文件出现。

我忘了什么?

(运行W7 64位和Office 2003)。

1 个答案:

答案 0 :(得分:1)

我在评论中提到,你所拥有的是一个工作簿级别的事件过程。这与“宏”略有不同(您的公共宏可用于任何打开的工作簿,但工作表或工作簿级事件不会响应其他工作簿事件)。您需要的是捕获应用程序级事件

我还没有完全测试过这个,但我做了一些简单的测试,它似乎工作,(我移植了一些代码,我在PowerPoint中使用它来捕获应用程序级事件)。试一试,看看它是否适合你。

首先创建一个类对象来处理事件。

在您的Personal.XLS中,添加一个类模块并将其命名为cEventClass(您可以将其命名为您想要的名称,但如果您使用与我相同的命名约定,则更容易按照我的示例使用)。

在此类模块中,输入以下代码:

Option Explicit
Public WithEvents XLEvent As Application


Private Sub XLEvent_WorkbookBeforeSave(ByVal Wb As Workbook, ByVal SaveAsUI As Boolean, Cancel As Boolean)

'This is just my test, you can place your own code (modified as needed) here:
MsgBox "BeforeSave " & Wb.Name

End Sub

我们现在已经建立了捕获应用程序级事件的方法,我们可以在VBE的下拉列表中看到这些可用选项:

enter image description here

下一步,实例化此类的实例。

执行此操作的最佳位置可能是在Personal.XLS Workbook_Open过程中。你可以把它放在另一个sub中并按需调用它等,但是如果你把它放在这个事件处理程序中,我认为它应该可以工作。

添加一个普通的代码模块(这不能放在一个对象或类模块中),执行此操作:

Public cXLEvents As New cEventClass

添加一些代码以自动实例化类

在Personal.XLS的Workbook_Open过程中,执行以下操作:

Option Explicit

Private Sub Workbook_Open()
    'Add this line in addition to any other code you might already have in this procedure
    Set cXLEvents.XLEvent = Application

End Sub

现在,请坐下来让处理程序完成其工作!

现在,当您去保存任何工作簿(不限于Personal.XLS)时,应用程序事件处理程序应该选择它,如我的示例所验证的那样:

enter image description here

注意我认为如果您正在调试并且“结束”运行时,这将无效;这会杀死cXLEvents,因此事件处理程序将基本上被“关闭”,所以你需要重新实例化它。