Объединение настроек VBA и уровня документов

Код Visual Basic для приложений (VBA) можно использовать в документе, который является частью настройки на уровне документа для Microsoft Office Word или Microsoft Office Excel. Код VBA можно вызывать в документе из сборки настройки, или проект можно настроить таким образом, чтобы позволить коду VBA в документе вызывать код в сборке настройки.

Область применения. Сведения в этом разделе относятся к проектам уровня документа для Excel и Word. Дополнительные сведения см. в разделе "Функции", доступные по Приложение Office ликации и типу проекта.

Поведение кода VBA в настройке уровня документа

При открытии проекта в Visual Studio документ открывается в режиме конструктора. Код VBA не выполняется, если документ находится в режиме конструктора, поэтому можно работать над документом и кодом без выполнения кода VBA.

При запуске решения обработчики событий в VBA и сборке настройки получают события, возникающие в документе, и выполняются оба набора кода. Заранее невозможно определить, какой из кодов будет выполнен раньше. Это необходимо определить путем тестирования в каждом конкретном случае. Если два набора кода тщательно не скоординированы и не протестированы, можно получить неожиданные результаты.

Вызов кода VBA из сборки настройки

В документах Word можно вызывать макросы, а в книгах Excel — функции и макросы. Для этого используйте один из следующих методов.

  • Для Word вызовите Run метод Application класса.

  • Для Excel необходимо вызвать метод Run класса Application .

    Для каждого метода первый параметр определяет имя макроса или функции, которую необходимо вызвать, а оставшиеся необязательные параметры указывают параметры, передаваемые в макрос или функцию. Первый параметр может иметь различные форматы для Word и Excel:

  • Для Word первый параметр является строкой, которая может быть любой комбинацией из имен шаблона, модуля и макроса. Если указать имя документа, код сможет выполнять макросы только в документах, относящихся к текущему контексту, а не любые макросы в любом документе.

  • Для Excel первый параметр может быть строкой, которая указывает имя макроса, объектом Range , указывающим, где находится функция, или идентификатором регистра для зарегистрированной функции DLL (XLL). Если передается строка, она строка будет оцениваться в контексте активного листа.

    В следующем примере кода показано, как вызвать макрос с именем MyMacro из проекта на уровне документа для Excel. В этом примере предполагается, что MyMacro определен в Sheet1.

Globals.Sheet1.Application.Run("MyMacro", missing, missing, missing,
    missing, missing, missing, missing, missing, missing, missing,
    missing, missing, missing, missing, missing, missing, missing,
    missing, missing, missing, missing, missing, missing, missing,
    missing, missing, missing, missing, missing, missing);

Примечание.

Сведения об использовании глобальной missing переменной вместо необязательных параметров в Visual C#см. в статье "Написание кода в решениях Office".

Вызов кода в настройках уровня документа из VBA

Проект на уровне документа для Word или Excel можно настроить таким образом, чтобы код Visual Basic для приложений (VBA) в документе мог вызывать код в сборке настройки. Это полезно в следующих случаях:

  • Необходимо расширить существующий код VBA в документе с помощью функций в настройке на уровне документа, которая связана с тем же документом.

  • Службы, разрабатываемые в настройке на уровне документа, необходимо сделать доступными для конечных пользователей, которые могут получать доступ к этим службам, путем написания кода VBA в документе.

    Средства разработки Office в Visual Studio предоставляют аналогичную функцию для надстроек VSTO. При разработке надстройки VSTO можно вызвать код в надстройке VSTO из других решений Microsoft Office. Дополнительные сведения см. в разделе "Код вызова" в надстройках VSTO из других решений Office.

Примечание.

Эту функцию нельзя использовать в проектах шаблонов Word. Ее можно использовать только в проектах документов Word, книг Excel или шаблонов Excel.

Requirements

Перед обеспечением для кода VBA возможности вызывать сборку настройки убедитесь, что проект соответствует следующим требованиям:

  • Документ должен иметь одно из следующих расширений имени файла:

    • Для Word: .docm или .doc

    • Для Excel: .xlsm, .xltm, .xls или .xlt

  • Документ должен уже содержать проект VBA, который содержит в себе код VBA.

  • Для кода VBA в документе должна существовать возможность работы без вывода запросов пользователю на включение макросов. Чтобы разрешить выполнение кода VBA, расположение проекта Office можно добавить в список надежных расположений в параметрах Центра управления безопасностью для Word или Excel.

  • Проект Office должен содержать по крайней мере один общий класс с одним или несколькими общими членами, которые вы предоставляете коду VBA.

    Коду VBA можно предоставлять методы, свойства и события. Предоставляемым классом может быть класс ведущего элемента (например, ThisDocument для Word или ThisWorkbook и Sheet1 для Excel) или другой класс, определенный в проекте. Дополнительные сведения о элементах узла см. в обзоре элементов узла и элементов управления узлами.

Включение вызова кода VBA в сборку настройки

Для предоставления членов в сборке настройки коду VBA в документе можно использовать два способа:

  • Члены класса элементов узла можно предоставить в проекте Visual Basic для VBA. Для этого установите для свойства EnableVbaCallers ведущего элемента значение True в окне Свойства , когда ведущий элемент (то есть, документ, лист или книга) открыт в конструкторе. Visual Studio автоматически выполнит все необходимые действия, чтобы код VBA мог вызывать члены класса.

  • Участники любого общедоступного класса в проекте Visual C# или члены в классе элементов, отличном от узла, в проекте Visual Basic, можно предоставить VBA. Этот параметр расширяет возможность выбора классов, которые можно предоставить коду VBA, но это также потребует выполнения дополнительных действий вручную.

    Для этого необходимо выполнить следующие основные шаги:

    1. Предоставьте класс для COM.

    2. Переопределите метод GetAutomationObject класса ведущего элемента в своем проекте для возврата экземпляра класса, который вы предоставляете коду VBA.

    3. Для свойства ReferenceAssemblyFromVbaProject любого класса ведущего элемента в проекте установите значение True. Это внедряет библиотеку типов сборки настройки в саму сборку и добавляет ссылку на библиотеку типов в проект VBA в документе.

    Подробные инструкции см. в статье "Практическое руководство. Предоставление кода VBA в проекте Visual Basic и практическое руководство. Предоставление кода VBA в проекте Visual C#.

    Свойства EnableVbaCallers и ReferenceAssemblyFromVbaProject доступны в окне Свойства только во время разработки. Они не могут использоваться во время выполнения. Чтобы просмотреть свойства, откройте конструктор для элемента узла в Visual Studio. Дополнительные сведения о конкретных задачах, выполняемых Visual Studio при задании этих свойств, см. в разделе "Задачи", выполняемые свойствами элемента узла.

Примечание.

Если книга или документ еще не содержит кода VBA, или код VBA в документе не является доверенным для выполнения, при установке для свойства EnableVbaCallers или ReferenceAssemblyFromVbaProject значения Trueвы получите сообщение об ошибке. Это происходит потому, что в данной ситуации Visual Studio не может изменить проект VBA в документе.

Использование членов в коде VBA для вызова в сборку настройки

После настройки своего проекта для обеспечения для кода VBA возможности вызывать сборку настройки Visual Studio добавляет в проект VBA в документе следующие члены:

  • Для всех проектов Visual Studio добавляет глобальный метод с именем GetManagedClass.

  • Для проектов Visual Basic, в которых вы предоставляете члены класса элементов узла с помощью свойства EnableVbaCallers, Visual Studio также добавляет свойство с именем ThisDocumentCallVSTOAssembly , или ThisWorkbookSheet1Sheet2Sheet3 модуль в проекте VBA.

    Для доступа к открытым членам класса, который вы предоставляете коду VBA в проекте, можно использовать свойство CallVSTOAssembly или метод GetManagedClass .

Примечание.

Во время разработки и развертывания решения существуют несколько различных копий документа, в которые можно добавить код VBA. Дополнительные сведения см. в руководстве по добавлению кода VBA в документ.

Использование свойства CallVSTOAssembly в проекте Visual Basic

Для доступа к открытым членам, которые вы добавили в класс ведущего элемента, используйте свойство CallVSTOAssembly . Например, следующий макрос VBA вызывает метод с именем MyVSTOMethod , который определен в классе Sheet1 в проекте книги Excel.

Sub MyMacro()
    Sheet1.CallVSTOAssembly.MyVSTOMethod()
End Sub

Это свойство является более удобным способом вызова сборки настройки, чем использование метода GetManagedClass напрямую. CallVSTOAssembly возвращает объект, представляющий класс ведущего элемента, который вы предоставили коду VBA. Члены и параметры метода возвращенного объекта отображаются в IntelliSense.

Свойство CallVSTOAssembly имеет объявление, похожее на следующий код. Данный код предполагает, что вы предоставили коду VBA класс ведущего элемента Sheet1 в проекте книги Excel с именем ExcelWorkbook1 .

Property Get CallVSTOAssembly() As ExcelWorkbook1.Sheet1
    Set CallVSTOAssembly = GetManagedClass(Me)
End Property

Использование метода GetManagedClass

Чтобы использовать глобальный метод GetManagedClass , передайте объект VBA, соответствующий классу ведущего элемента, который содержит переопределенный метод GetAutomationObject . Затем для доступа к классу, который вы предоставляете коду VBA, используйте возвращенный объект.

Например, следующий макрос VBA вызывает метод с именем MyVSTOMethod , который определен в классе ведущего элемента Sheet1 в проекте книги Excel с именем ExcelWorkbook1.

Sub CallVSTOMethod
    Dim VSTOSheet1 As ExcelWorkbook1.Sheet1
    Set VSTOSheet1 = GetManagedClass(Sheet1)
    VSTOSheet1.MyVSTOMethod
End Sub

Метод GetManagedClass имеет следующее объявление:

GetManagedClass(pdispInteropObject Object) As Object

Этот метод возвращает объект, представляющий класс, который вы предоставили коду VBA. Члены и параметры метода возвращенного объекта отображаются в IntelliSense.

Рекомендации по добавлению кода VBA в документ

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

В ходе разработки и тестирования решения можно писать код VBA в документе, который открывается при отладке или запуске проекта в Visual Studio (то есть, документе в выходной папке сборки). Тем не менее, любой код VBA, добавляемый в этот документ, будут перезаписан в следующий раз при сборке проекта, так как Visual Studio заменяет документ в выходной папке сборки копией документа из главной папки проекта.

Если необходимо сохранить код VBA, добавляемый в документ при отладке или выполнении решения, скопируйте код VBA в документ в папке проекта. Дополнительные сведения о процессе сборки см. в разделе "Создание решений office".

Когда вы готовы к развертыванию решения, существует три основных расположения документа, куда можно добавлять код VBA.

В папке проекта на компьютере разработки

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

Если документ открыт в конструкторе, то добавлять код VBA в него нельзя. Сначала необходимо закрыть документ в конструкторе, а затем открыть его непосредственно в Word или Excel.

Внимание

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

В папке публикации или установки

В некоторых случаях может быть необходимо добавление кода VBA в документ в папке публикации или папке установки. Например, этот вариант можно выбрать, если код VBA создан и протестирован другим разработчиком на компьютере, на котором Visual Studio не установлен.

Если пользователи устанавливают решение непосредственно из папки публикации, код VBA необходимо добавлять в документ при каждой публикации решения. Visual Studio перезаписывает документ в папке публикации в ходе публикации решения.

Если пользователи устанавливают решение из папки установки, отличной от папки публикации, то добавления кода VBA в документ при каждой публикации решения можно избежать. Если обновление публикации готово для перемещения из папки публикации в папку установки, скопируйте все файлы в папку установки, кроме самого документа.

На компьютере конечного пользователя

Если конечные пользователи являются разработчиками VBA, вызывающими службы, которые вы указываете в настройке на уровне документа, им можно сообщить способ вызова кода с помощью свойства CallVSTOAssembly или метода GetManagedClass в их копиях документа. При публикации обновлений решения код VBA в документе на компьютере конечного пользователя не будет перезаписан, так как документ не изменяется при публикации обновлений.

Задачи, выполняемые свойствами элемента узла

Когда вы используете свойства EnableVbaCallers и ReferenceAssemblyFromVbaProject , Visual Studio выполняет различные наборы задач.

EnableVbaCallers

Если для свойства EnableVbaCallers ведущего элемента установить значение True в проекте Visual Basic, то Visual Studio выполняет следующие задачи:

  1. Добавляет атрибуты ComClassAttribute и ComVisibleAttribute в класс ведущего элемента.

  2. Переопределяет метод GetAutomationObject класса ведущего элемента.

  3. Устанавливает для свойства ReferenceAssemblyFromVbaProject ведущего элемента значение True.

    Если для свойства EnableVbaCallers снова установить значение False, Visual Studio выполняет следующие задачи:

  4. Удаляет атрибуты ComClassAttribute и ComVisibleAttribute из класса ThisDocument .

  5. Удаляет метод GetAutomationObject из класса ведущего элемента.

    Примечание.

    Visual Studio не задает автоматически для свойства ReferenceAssemblyFromVbaProject значение False. Для этого свойства значение False можно установить вручную с помощью окна Свойства .

ReferenceAssemblyFromVbaProject

Если для свойства ReferenceAssemblyFromVbaProject любого ведущего элемента в проекте Visual Basic или Visual C# установлено значение True, Visual Studio выполняет следующие задачи:

  1. Создает библиотеку типов для сборки настройки и внедряет библиотеку типов в сборку.

  2. Добавляет ссылку на следующие библиотеки типов в проекте VBA в документе:

    • Библиотека типов для сборки настройки.

    • Инструменты Microsoft Visual Studio для библиотеки типов Office Execution Engine 9.0. Эта библиотека типов включена в среду выполнения набор средств Visual Studio для Office.

    Если для свойства ReferenceAssemblyFromVbaProject снова установить значение False, Visual Studio выполняет следующие задачи:

  3. Удаляет ссылки на библиотеку типов из проекта VBA в документе.

  4. Удаляет внедренные библиотеки типов из сборки.

Устранение неполадок

Ниже перечислены некоторые распространенные ошибки и предложения по их устранению.

Ошибка Предложение
После задания свойства EnableVbaCallers или ReferenceAssemblyFromVbaProject появляется сообщение об ошибке, указывающее, что документ не содержит проект VBA, или что у вас нет разрешения на доступ к проекту VBA в документе. Убедитесь, что документ в проекте содержит по крайней мере один макрос VBA, что проекту VBA задан достаточный уровень доверия для выполнения, и что проект VBA не защищен с помощью пароля.
После задания свойства EnableVbaCallers или ReferenceAssemblyFromVbaProject появляется сообщение об ошибке, указывающее, что объявление GuidAttribute отсутствует или повреждено. Убедитесь, что GuidAttribute объявление находится в файле AssemblyInfo.cs или AssemblyInfo.vb в проекте, а этот атрибут имеет допустимый GUID.
После задания свойства EnableVbaCallers или ReferenceAssemblyFromVbaProject появляется сообщение об ошибке, указывающее, что номер версии, указанный в AssemblyVersionAttribute , не является допустимым. Убедитесь, что AssemblyVersionAttribute объявление в файле AssemblyInfo.cs или AssemblyInfo.vb в проекте имеет допустимый номер версии сборки. Сведения о номерах версий сборки см. в классе AssemblyVersionAttribute .
После переименования сборки настройки код VBA, вызывающий эту сборку, перестает работать. Если изменить имя сборки настройки после его предоставления коду VBA, то связь между проектом VBA в документе и сборкой настройки будет нарушена. Чтобы устранить эту проблему, задайте для свойства ReferenceFromVbaAssembly в своем проекте значение False , а потом снова True, и замените все ссылки на старое имя сборки в коде VBA новым именем сборки.