以编程方式添加工作簿事件并保存

时间:2016-06-02 21:47:25

标签: excel vba excel-vba

我在电子表格中有一个excel文件列表。我想循环遍历它们并为每个添加工作表事件。保存它,关闭它然后继续下一个。问题是,当我重新打开(手动)工作簿时,代码就消失了。

在每个循环中:

Set xl = Workbooks.Open(filepath)
addCode xl 'subroutine to add code
xl.Save
xl.Close SaveChanges:=False

addCode子例程是:

Sub addCode(book As Excel.Workbook)
     acsh = book.ActiveSheet.CodeName
     startline = book.VBProject.VBComponents(acsh).CodeModule.CreateEventProc("SelectionChange", "Worksheet") + 1
     book.VBProject.VBComponents(acsh).CodeModule.InsertLines startline, codetoadd
End Sub

如果我注释掉xl.Close代码在工作簿中并且有效。我可以手动保存并关闭文件,代码仍然存在。我在xl.save和xl.close之间添加了一个断点,并制作了该文件的副本。代码完成后,两者都没有更改。我尝试过使用xl.saveas和xl.close SaveChanges:= True。所有都有相同的结果。

我使用Excel 2013,我告诉excel信任对VBA对象模型的访问。我尝试过使用XLS文件和XLSM文件。显然XLSX不起作用。

1 个答案:

答案 0 :(得分:2)

以下是一些在Excel 2010上为我工作的示例代码。我对您的示例代码所做的更改是:

  • 使用.xlsm作为目标工作簿 - 我知道你说你已经这样做了。

  • 引用AddCode子中的特定工作表,而不是从ActiveSheet中选取工作表名称。

  • 根据Ralph的评论设置工作簿脏状态

  • 关闭目标工作簿时不要设置SaveChanges标志

除此之外,我的版本非常类似于你的版本。我认为这是wb.Saved = False行,即肮脏的旗帜。我尝试在SaveAs上使用VBProject方法,认为它与在VBA编辑器本身中点击保存按钮相同。但是,这只会产生无用的错误。

以下是示例代码:

Option Explicit

Sub Test()

    Dim wbTarget As Workbook
    Dim strCode As String

    ' get target workbook
    Set wbTarget = Workbooks.Open("\\server\path\Book3.xlsm")

    ' test setting code to worksheet change
    strCode = "Debug.Print ""Sheet selection changed to: "" & Target.Address"
    AddWorksheetChangeCode wbTarget, "Sheet1", strCode

    ' test saving the target workbook
    With wbTarget
        ' set book to dirty to force the save
        .Saved = False
        .Save
        .Close
    End With

End Sub

Sub AddWorksheetChangeCode(ByRef wb As Workbook, strWorksheetName As String, strCode As String)

    Dim intInsertLine As Integer

    ' create stub for event and get line to insert
    intInsertLine = wb.VBProject.VBComponents(strWorksheetName).CodeModule.CreateEventProc("SelectionChange", "Worksheet") + 1

    ' add event logic
    wb.VBProject.VBComponents(strWorksheetName).CodeModule.InsertLines intInsertLine, strCode

End Sub