通过宏关闭并保存工作簿,而无需运行“ beforesave”事件

时间:2019-01-24 15:12:10

标签: excel vba

我有一个遵循相同模板的工作簿列表,并且所有工作簿都有一个宏“ beforesave”事件,该事件基本上会在工作表上创建一个保存登录,列出保存该工作簿的人的时间和用户ID

因此有时我需要在所有工作簿中更改一个公式,由于大约需要一分钟时间才能手动关闭和保存每个工作簿,因此我创建了一个宏,该宏可以打开所有它们的更改并关闭保存的内容。 。这将为我节省大量时间,因为此过程总共要花费我大约30分钟的时间,并且会感到无聊。

问题是:当宏尝试关闭并保存工作簿时,“ beforesave”事件无法正常运行,结果工作簿也无法使用宏进行保存和关闭。由于某种原因,该事件似乎在宏中被跳过了...

要解决此问题,我想运行此宏以在所有工作簿中进行所有更改,请跳过beforesave事件(如有必要),并最终保存并关闭它们。

请帮助?

尝试逐行运行宏,并在到达事件部分时调用它,但由于某种原因,它停留在同一工作表中,而不是进入日志工作表,并将错误的日志信息写入结果。无论如何,逐行运行对我来说显然是行不通的,因为它基本上与手动进行此过程相同。

Sub DoStuff()
    Dim Row As Integer
    Dim Col As Integer
    Dim wbCopy As Workbook
    Dim wbPaste As Workbook
    Dim wbBP As Workbook

    For Col = 4 To 4
        ThisWorkbook.Activate
        Set wbBP = Workbooks.Open(Cells(1, Col), False)
        ThisWorkbook.Activate
        Set wbCopy = Workbooks.Open(Cells(2, Col), False, True)

        For Row = 3 To 19
            ThisWorkbook.Activate
            SetAttr Cells(Row, Col), vbNormal
            Set wbPaste = Workbooks.Open(Cells(Row, Col), False)
            wbCopy.Activate
                Sheets("Base").Activate
                Range("A7:EQ500").AutoFilter
            wbPaste.Activate
                Sheets("Base").Activate
                Range("A7:EQ500").AutoFilter
            wbCopy.Activate
                Sheets("Base").Activate
                Range("AL8:AS8").Copy
            wbPaste.Activate
                Sheets("Base").Activate
                Range("AL8:AS" & Cells(Rows.Count, 1).End(xlUp).Row).PasteSpecial xlPasteFormulas
                Application.CutCopyMode = False
            wbPaste.Close True
            ThisWorkbook.Activate
            SetAttr Cells(Row, Col), vbReadOnly
        Next Row
        wbCopy.Close False
        wbBP.Close False
    Next Col

End Sub

运行宏以执行所需的更改,并正确保存和关闭所有涉及的工作簿。

1 个答案:

答案 0 :(得分:0)

欢迎来到SO。如果可以执行wbPaste工作簿中的所有事件来执行更新作业,则标题的答案太简单了。只需在保存文件之前添加Application.EnableEvents = False,然后在保存完成后将其设置为true。

同样,根据@Mathieu Guindon的评论,您的帖子对您​​的确切要求以及对Activate的无意使用感到困惑,我只是对您的代码进行了一些重组,以避免在更新期间运行任何事件。

Sub DoStuff()
    Dim Row As Integer
    Dim Col As Integer
    Dim wbCopy As Workbook
    Dim wbPaste As Workbook
    Dim wbBP As Workbook

‘Worksheet name “FileList” used for trial . May please change to yours  or use activesheet 
 With ThisWorkbook.Worksheets("FileList")    
       For Col = 4 To 4
       ‘Could not understand why wbBP opened, it is not used anywhere in the code 
       Set wbBP = Workbooks.Open(.Cells(1, Col), False)
        Set wbCopy = Workbooks.Open(.Cells(2, Col), False, True)

       ‘ This will disable any events including ‘BeforeSave’ events
        Application.EnableEvents = False
       ‘Disabling  ScreenUpdating  will increase efficiency if large files used
        Application.ScreenUpdating = False

          For Row = 3 To 19
            SetAttr .Cells(Row, Col), vbNormal           ‘ failed to understand use of SetAttr
            Set wbPaste = Workbooks.Open(.Cells(Row, Col), False)
            wbCopy.Sheets("Base").Range("A7:EQ500").AutoFilter
            wbPaste.Sheets("Base").Range("A7:EQ500").AutoFilter
            wbCopy.Sheets("Base").Range("AL8:AS8").Copy
            wbPaste.Sheets("Base").Range("AL8:AS" & Cells(Rows.Count , 1).End(xlUp).Row).PasteSpecial xlPasteFormulas
            Application.CutCopyMode = False
            wbPaste.Close True
            SetAttr .Cells(Row, Col), vbReadOnly
        Next Row
        Application.EnableEvents = True
        Application.ScreenUpdating = True
        wbCopy.Close False
        wbBP.Close False
    Next Col
    End With
End Sub

如果您要在wbPaste工作簿中运行其他事件,并且仅打算避免仅运行BeforeSave事件或该事件中的部分代码,而您有权修改事件代码,那么您可以可以根据我的评论通过检查单元格的值来在'BeforeSave'事件代码中引入一个分支。如果担心用户不小心修改/删除了单元格值,最好引入一个“ CustomDocumentProperties”

您可以选择从所有wbPaste工作簿的文档面板中添加和设置自定义文档属性。我希望通过一次性运行代码

来介绍自定义文档属性BeforeSaveCheck'
Sub testOnce()
    Dim Row As Integer
    Dim Col As Integer
    Dim wbPaste As Workbook
    Col = 4

    With ThisWorkbook.Worksheets("FileList")
        Application.EnableEvents = False
        'Application.ScreenUpdating = False
        For Row = 3 To 19
            SetAttr .Cells(Row, Col), vbNormal
            Set wbPaste = Workbooks.Open(.Cells(Row, Col), False)
            wbPaste.CustomDocumentProperties.Add Name:="BeforeSaveCheck", LinkToContent:=False, Type:=msoPropertyTypeBoolean, Value:=True
            wbPaste.Close True
            SetAttr .Cells(Row, Col), vbReadOnly
        Next Row
        Application.EnableEvents = True
        'Application.ScreenUpdating = True
    End With

End Sub

现在您可以在wbPaste工作簿之类的BeforeSave事件中引入一个简单分支

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)

If ThisWorkbook.CustomDocumentProperties("BeforeSaveCheck") Then
‘’’’’’’’’’’’’
‘The code section you want to bypass while updating with macro
‘’’’’’’’’’’’
End If

End Sub

并在打开事件时将属性设置为True

Private Sub Workbook_Open()
ThisWorkbook.CustomDocumentProperties("BeforeSaveCheck") = True
End Sub

最后在sub dostuff中 删除行

   Application.EnableEvents = False
   Application.EnableEvents = True

并添加行

ThisWorkbook.CustomDocumentProperties("BeforeSaveCheck") = False
wbPaste.Close True