Закрыть и сохранить книгу с помощью макроса без запуска событий beforesave - PullRequest
0 голосов
/ 24 января 2019

У меня есть список книг, которые следуют одному и тому же шаблону, и у всех есть событие макроса «beforesave», которое в основном создает логин сохранения на листах, перечисляя время и идентификатор пользователя от того, кто сохраняет книгу.

Так что иногда мне нужно изменить формулу во всех книгах, и, поскольку закрытие и сохранение каждой из них занимает около минуты, я создал макрос, который открывает все из них, изменяет то, что мне нужно, изменилось,и закрывает, сохраняя их.Это сэкономило бы мне значительное количество времени, так как в целом этот процесс занимает около 30 минут моего времени и много скуки.

Проблема в том, что когда макрос пытается закрыть и сохранить книгусобытие 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 голосов
/ 25 января 2019

Добро пожаловать на SO. Ответ на заголовок слишком прост, если вы можете выполнить задание обновления, запустив какие-либо события в книгах wbPaste. Просто добавьте Application.EnableEvents = False перед сохранением файла и сделайте его верным после завершения сохранения.

Также, основываясь на замечаниях @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

Теперь вы можете представить простую ветвь в BeforeSave событиях рабочих книг wbPaste, таких как

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...