Обе книги «зависают» при обновлении первого (xlsm), пока открыта вторая (xlsx) - PullRequest
0 голосов
/ 31 октября 2018

Проблема

У меня есть рабочая книга (A), которая содержит некоторые макросы, а также связана с другим Excel-файлом (источником данных). Рабочая книга работает отлично и без проблем, если у меня есть только эта отдельная рабочая книга. Если я открою другой случайный xlsx-файл, то все сначала будет нормально. Но как только я делаю какие-либо обновления (например, нажимая F2 в пустой ячейке и затем вводя) в книгу A, обе книги, кажется, зависают. Я все еще могу закрыть рабочие книги в обычной процедуре, и макро-кнопка в рабочей книге A работает нормально (и запустит макрос), но я не могу изменить вкладки в wb A, и вкладки во второй рабочей книге исчезают. Я вижу курсор, но зеленая рамка / рамка Excel вокруг ячеек-мишеней исчезла в обеих книгах. Я также не могу обновить ни одну из ячеек в книгах ...

Что я пробовал

Я пытался;

  • удалить все соединения с источниками данных

  • удалить все макросы (один за другим, но проблема все еще существует без макросов в wb A ...)

  • просмотреть макросы, чтобы выяснить, не вызывают ли они какие-либо ошибки (чего, насколько я вижу, нет)

  • два других xlsm-файла (не связанных с wb A) не вызывают этот тип ошибки

  • я пытался использовать application.ScreenUpdating = False, .EnableEvents = False, .Calculation = xlCalculationManual и возвращать им исходные значения в конце.

Код

-Range ("B4") - это выпадающий список без пробелов. Следующий макрос лежит в Листе 1:

Sub Worksheet_Change(ByVal Target As Range)

    On Error GoTo ApplicationON:
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False

    If Intersect(Target, Range("B4")) Is Nothing Then Exit Sub
       Call conditionalFormatting.conditionalFormatting

ApplicationON:
    On Error Resume Next
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    Application.EnableEvents = True

End Sub

- Следующий макрос находится в модуле, называемом «условное форматирование»:

Sub conditionalFormatting()

    On Error GoTo ApplicationON:
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False

    Dim DASHBOARD   As Worksheet
    Dim rng1        As Range
    Dim rng2        As Range
    Dim cel         As Range
    Dim col1        As Integer
    Dim col2        As Integer

    Set DASHBOARD = Sheets("DASHBOARD")
    Set rng1 = Range("R15:R45")
    Set rng2 = Range("R15:Z45")
    col1 = 18
    col2 = 26

    With rng2
        .Cells.Font.Bold = False
        .Cells.Font.Italic = False
        .Cells.Font.Size = 11
    End With

    For Each cel In rng1
        Select Case cel.Value

        Case _
        "Case1", _
        "Case2"
            Range(Cells(cel.Row, col1), Cells(cel.Row, col2)).Font.Bold = True

        Case _
        "Case3", _
        "Case4"
           Range(Cells(cel.Row, col1), Cells(cel.Row, col2)).Font.Size = 8

        Case _
        "Case5", _
        "Case6"
           Range(Cells(cel.Row, col1), Cells(cel.Row, col2)).Font.Italic = True

       End Select
    Next  

ApplicationON:
    On Error Resume Next
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    Application.EnableEvents = True 

End Sub

- Следующий макрос находится в модуле с именем «ExportToPDF» и имеет кнопку на рабочем листе «DASHBOARD» (sheet1):

Sub ExportToPDF()

    On Error GoTo ApplicationON:
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False

    Dim pt As Range

    dateStamp = Format(Now(), "yyyymmdd\_hhmm")
    workbookPath = ActiveWorkbook.Path & "\"
    workbookName = ActiveWorkbook.Name
    file_Name = dateStamp & "_" & Sheets("DASHBOARD").Range("A1") & ".pdf"
    filePath = workbookPath & file_Name

    With Worksheets("DASHBOARD").PageSetup
    .PrintArea = "A6:O42"
    .Orientation = xlLandscape
    End With

    Set pt = 
  Worksheets("DASHBOARD").Range(Worksheets("DASHBOARD").PageSetup.PrintArea)

    pt.ExportAsFixedFormat _
        Type:=xlTypePDF, _
        Filename:=filePath, _
        Quality:=xlQualityStandard, _
        IncludeDocProperties:=True, _
        IgnorePrintAreas:=False, _
        OpenAfterPublish:=True

    MsgBox "PDF file has been created: " _
          & filePath

ApplicationON:
    On Error Resume Next
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    Application.EnableEvents = True 

End Sub

После некоторых дополнительных испытаний

Кажется, это связано с циклом и модулем Workbook_change + мой выпадающий список, который не содержит пустых значений. Но все же странно, что он прекрасно работает без других открытых wb, но становится проблемой только при открытии дополнительного wb. Не могу увидеть, что код работает, когда оба wbs зависает ...

1) сделал копию и удалил соединения данных (чтобы это не мешало), сохранив и закрыв рабочую книгу

2) Открытие рабочей книги (без каких-либо ошибок и инструкций приложения) без внесения каких-либо изменений / обновлений в электронные таблицы и открытие второго файла (slsx) - возникает ошибка

3) Открытие рабочей книги (без каких-либо ошибок и указаний на приложения) и запись "= 1 + 1" в случайную пустую ячейку, а также открытие второго файла (slsx) - возникает ошибка

4) Открытие рабочей книги (без каких-либо операторов errorHandling и application-Statement) и однократное изменение выпадающего списка (вызов макроса worksheet_change), а также открытие второго файла (slsx) - возникает ошибка

5) Открытие рабочей книги (в исходном состоянии после публикации) без внесения каких-либо изменений / обновлений в электронные таблицы и открытие второго файла (slsx) - возникает ошибка

6) Открытие рабочей книги (в исходном состоянии после публикации) и запись «= 1 + 1» в случайную пустую ячейку и открытие второго файла (slsx) - ошибка не возникает

7) Открытие рабочей книги (в исходном состоянии после публикации) и однократное изменение раскрывающегося списка (вызов макроса worksheet_change) и открытие второго файла (slsx) - возникает ошибка

8) Если я вставляю пустое значение в раскрывающийся список (книга в исходном состоянии как опубликованная), выбираю пустое значение и открываю второй файл (slsx) - ошибка не возникает

9) Выбор значения в выпадающем списке - ошибка

8) Удаление модулей ExportToPDF- и условного форматирования, включая предлагаемую настройку для модуля Worksheet_change (т.е. удаление кода из sheet1 и вставка его в модуль).

  • 8.1 просто открыть второй файл, не внося изменений в xlsm, и иметь значение в раскрывающемся списке - возникает ошибка
  • 8.2, набрав 1 + 1 в случайной пустой ячейке - возникает ошибка
  • 8.3 изменение выпадающего списка один раз (на другое значение) - ошибка
  • 8.4 изменение раскрывающегося списка пустым - ошибка не возникает

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

Похоже, произошла загадочная ошибка с Excel-файлом. Я восстановил приборную панель, и она работала, как и ожидалось. Чтобы быть в безопасности, я пропустил код «Workbook_change», связанный с фильтром, и просто использовал вместо этого простую кнопку для выполнения кода. Спасибо за вклад каждого.

0 голосов
/ 31 октября 2018

Если вы вызываете ошибку в любой этих функций, вы устанавливаете Application.EnableEvents = True. Итак ... Если они вызваны вызовом, исходящим из обработчика события, вы теряете защиту от повторного входа. Вы также безоговорочно делаете это на вершине всего:

Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False

Это пахнет грубо-культовым поведением . Вы должны выполнять эту работу только там, где это необходимо, и рядом с местом там, где это необходимо. Какой бы прирост производительности вы ни думали, получая это, вероятно, просто иллюзорно. Фактически, многократное возмущение состоянием Application, вероятно, приносит больше вреда , чем пользы с точки зрения производительности.

Решение состоит в том, чтобы не полагаться на Excel для защиты повторного входа в ваш обработчик событий - сделайте это вручную:

Private reentryFlag As Boolean    'Module level

Sub Worksheet_Change(ByVal Target As Range)
    If reentryFlag Then Exit Sub
    reentryFlag = True

    On Error GoTo Handler
    If Intersect(Target, Range("B4")) Is Nothing Then Exit Sub

    conditionalFormatting.conditionalFormatting
Handler:
    reentryFlag = False
End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...