Может ли наличие нескольких открытых экземпляров Excel вызывать проблемы с VBA? - PullRequest
1 голос
/ 26 июня 2019

У меня есть код в книге A, который открывается и выполняет какие-то действия с книгой B. Код работает нормально, когда рабочая книга A и B являются единственными открытыми файлами Excel (или если рабочая книга A является единственным открытым файлом). Однако, если я открою какую-либо дополнительную книгу (назовите ее книгой C), макрос не будет работать правильно. Это не вызывает сообщение об ошибке, оно просто запускается до завершения без выполнения каких-либо «вещей», которые он должен делать (материал в основном находит вещи в рабочей книге B и вставляет их в рабочую книгу A).

FWIW, я сделал следующий простой эксперимент:

  1. Открыть все 3 рабочие книги (A, B и C)
  2. выберите рабочую книгу C, чтобы она была активной, а переднее окно
  3. запустите код workbookB.sheet1.activate (это не дословно, я знаю, что этот код, как написано, не будет работать)

Когда я выполняю описанный выше тест, он даже не делает рабочую книгу B активной книгой. Опять же, это не заставляет Excel выдавать сообщение об ошибке, оно просто запускается и оставляет рабочую книгу C активной книгой.

Редактировать: я проверял больше, приведенный ниже код должен изменить значение ячейки в книге B, но вместо этого помещает значение в книгу C. Я очень запутался, так как на книгу C никоим образом не ссылаются ( модуль находится в рабочей тетради А)

Sub test()
    Dim wb As Workbook
    Set wb = Workbooks.Open("U:\workbookB.xlsx")
    wb.Worksheets("ED").Range("Z1").Value = "TEST"
End Sub

Редактировать 2. Проблема возникала, когда Рабочая тетрадь A и B были открыты в течение нескольких часов, а Рабочая тетрадь C была открыта недавно. Я закрыл книгу B, затем повторно запустил код, и он работает правильно. Это наводит меня на мысль, что существует некая проблема с несколькими случаями открытия Excel. Хоть это и маловероятно, но мне все же любопытно, есть ли у кого-нибудь какой-нибудь способ, которым я мог бы обойти это в качестве меры предосторожности? Спасибо!

Ответы [ 2 ]

3 голосов
/ 27 июня 2019

Существует небольшая ошибка (я стесняюсь называть ее так, но вот как это выглядит), на которую нужно обратить внимание.

Если книгу вы пытаетесь открыть с помощью кода уже открыт , иногда вы можете увидеть непредвиденное поведение (например, возвращаемое значение из Workbooks.Open() присваивается ThisWorkbook вместо ожидаемого файла).

Например, запускается приведенный ниже кодв «Tester.xlsm» и открывает «EmptyTest.xlsx», но , если этот файл уже открыт, вызову Workbooks.Open не удается правильно назначить переменную wb, и он в итоге указывает на «Tester».XLSM ".Это может вызвать проблемы.

Для репликации

  • открыть Excel
  • открыть "EmptyTest.xlsx"
  • открыть "Tester.xlsm"
  • запустить "Tester" sub

Код теста:

Sub Tester()

    Dim wb As Workbook

    'with "EmptyTest" already open
    Set wb = Workbooks.Open("C:\Tester\EmptyTest.xlsx")
    Debug.Print wb.Name '>> Tester.xlsm  -  oops!

    'close"EmptyTest" before proceeding
    Workbooks("EmptyTest.xlsx").Close False

    'with  "EmptyTest" closed
    Set wb = Workbooks.Open("C:\Tester\EmptyTest.xlsx")
    Debug.Print wb.Name '>>EmptyTest.xlsx - OK

End Sub

Полностью воспроизводимый в моей системе (win10 / Office 365)

0 голосов
/ 27 июня 2019

Я думаю, что ваша проблема в том, что вы открываете Рабочая тетрадь B. Вы утверждаете, что если вы закроете и снова откроете ее, она будет работать.

Таким образом, любые изменения, внесенные вами в рабочую книгу B, будут потеряны, так как при этом откроется исходная рабочая книга. (Автосохранение фактически не сохраняет рабочую книгу, а сохраняет отдельную копию.)

Вместо этого вам нужно проверить, является ли рабочая книга уже открытой, и заново открыть ее, только если она еще не открыта.

(очень грубый код)

Sub test()
    Dim wb As Workbook
    For Each wb In ThisWorkbook.Application.Workbooks
        If wb.Path & "\" & wb.Name = "U:\workbookB.xlsx" Then Exit For
    Next
    If wb.Path & "\" & wb.Name <> "U:\workbookB.xlsx" Then Set wb = ThisWorkbook.Application.Workbooks.Open("U:\workbookB.xlsx")
    wb.Worksheets("ED").Range("Z1").Value = "TEST"
End Sub

Но (как уже говорили другие) вам действительно следует убедиться, что другие экземпляры Excel не запущены, и учесть их также.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...