Поделиться через


Объединение 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.

Требования

Прежде чем включить возможность вызова кода 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 класса элемента host в вашем проекте, чтобы вернуть экземпляр класса, который вы предоставляете для 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 также добавляет свойство с именем CallVSTOAssembly в модуль ThisDocument, ThisWorkbook, Sheet1, Sheet2 или Sheet3 в проекте VBA.

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

Замечание

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

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

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

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

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

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

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.

Caution

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

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

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

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

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

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

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

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

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

EnableVbaCallers

При задании свойства EnableVbaCallers хост-элемента в проекте 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 Tools for Office Execution Engine 9.0. Эта библиотека типов включена в среду выполнения Visual Studio Tools для Office.

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

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

  4. Он удаляет внедренную библиотеку типов из сборки.

Troubleshoot

В следующей таблице перечислены некоторые распространенные ошибки и предложения по устранению ошибок.

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