Вызов кода в надстройках уровня приложения из других решений Office
Можно предоставить другим решениям, включая другие решения Microsoft Office, доступ к объекту в вашей надстройке.Это может понадобиться в тех случаях, когда надстройка предоставляет службу, которую необходимо использовать в других решениях.Например, если надстройка для Microsoft Office Excel выполняет вычисления финансовых данных из веб-службы, то другие решения смогут выполнять такие вычисления путем вызова этой надстройки в Excel во время выполнения.
Применение. Сведения этого раздела применяются к проектам уровня приложения для Microsoft Office 2013 Preview и Microsoft Office 2010. Дополнительные сведения см. в разделе Доступность функций по типам приложений Office и проектов.
Этот процесс включает в себя два основных этапа.
В своей надстройке предоставьте другим решениям доступ к объекту.
В другом решении обратитесь к объекту, доступ к которому предоставлен вашей надстройкой, и вызовите членов данного объекта.
Типы решений, способные вызывать код в надстройке
Объекты в надстройке можно предоставлять указанным ниже типам решений.
VBA-код в документе, загруженный в тот же процесс приложения, что и надстройка.
Настройки уровня документа, загруженные в тот же процесс приложения, что и ваша надстройка.
Другие надстройки, созданные с помощью шаблонов проектов Office в Visual Studio.
Надстройки модели COM (то есть надстройки, реализующие интерфейс IDTExtensibility2 напрямую).
Любые решения, выполняющиеся в процессе, отличном от процесса вашей надстройки (решения такого типа также называются внепроцессными клиентами).Сюда входят приложения, автоматизирующие приложение Office, такие как Windows Forms и консольное приложение, а также надстройки, загруженные в другой процесс.
Предоставление объектов другим решениям
Чтобы предоставить другим решениям доступ к объекту в своей надстройке, выполните в своей надстройке следующие действия:
Определите класс, к которому требуется предоставить доступ из других решений.
Переопределите метод RequestComAddInAutomationService в классе ThisAddIn.Возвратите экземпляр класса, который требуется предоставить другим решениям.
Определение класса, который требуется предоставить другим решениям
Как минимум, предоставляемый класс должен быть открытым, иметь для атрибута ComVisibleAttribute заданное значение true и предоставлять интерфейс IDispatch.
Для предоставления интерфейса IDispatch рекомендуется выполнить следующие шаги.
Определите интерфейс, объявляющий члены, которые требуется предоставить другим решениям.Этот интерфейс можно определить в проекте надстройки.Однако если требуется предоставить класс решениям, не поддерживающим VBA, имеет смысл определить этот интерфейс в отдельном проекте библиотеки классов, чтобы решения, в которых вызывается эта надстройка, могли ссылаться на интерфейс, не ссылаясь на проект надстройки.
Примените к этому интерфейсу атрибут ComVisibleAttribute и задайте для этого атрибута значение true.
Измените свой класс, чтобы реализовать этот интерфейс.
Примените атрибут ClassInterfaceAttribute к классу и задайте для этого атрибута значение None перечисления ClassInterfaceType.
Если требуется предоставить класс клиентам вне процесса, может потребоваться выполнить следующие действия.
Необходимо унаследовать класс от StandardOleMarshalObject.Дополнительные сведения см. в разделе Предоставление классов клиентам вне процесса.
Задайте значение для свойства Регистрация для COM-взаимодействия в проекте, в котором определен интерфейс.Это необходимо только в том случае, если требуется разрешить клиентам использовать для вызова надстройки раннее связывание.Дополнительные сведения см. в разделе Управление свойствами компиляции.
В следующем примере кода демонстрируется класс AddInUtilities с методом ImportData, который может вызываться другими решениями.Чтобы просмотреть этот код в контексте полного руководства, см. раздел Пошаговое руководство. Вызов кода из VBA в настройках на уровне приложения.
<ComVisible(True)> _
Public Interface IAddInUtilities
Sub ImportData()
End Interface
<ComVisible(True)> _
<ClassInterface(ClassInterfaceType.None)> _
Public Class AddInUtilities
Implements IAddInUtilities
' This method tries to write a string to cell A1 in the active worksheet.
Public Sub ImportData() Implements IAddInUtilities.ImportData
Dim activeWorksheet As Excel.Worksheet = Globals.ThisAddIn.Application.ActiveSheet
If activeWorksheet IsNot Nothing Then
Dim range1 As Excel.Range = activeWorksheet.Range("A1")
range1.Value2 = "This is my data"
End If
End Sub
End Class
[ComVisible(true)]
public interface IAddInUtilities
{
void ImportData();
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class AddInUtilities : IAddInUtilities
{
// This method tries to write a string to cell A1 in the active worksheet.
public void ImportData()
{
Excel.Worksheet activeWorksheet = Globals.ThisAddIn.Application.ActiveSheet as Excel.Worksheet;
if (activeWorksheet != null)
{
Excel.Range range1 = activeWorksheet.get_Range("A1", System.Type.Missing);
range1.Value2 = "This is my data";
}
}
}
Предоставление классов VBA
При выполнении описанных выше действий код VBA может вызывать только методы, объявленные в этом интерфейсе.Код VBA не может вызывать никакие другие методы вашего класса, включая методы, которые ваш класс получает из базовых классов, таких как Object.
Интерфейс IDispatch можно также предоставить, задав для атрибута ClassInterfaceAttribute значение AutoDispatch или AutoDual перечисления ClassInterfaceType.В таком случае не требуется объявлять методы в отдельном интерфейсе.Однако код VBA может вызывать любые открытые и нестатические методы вашего класса, включая методы, полученные из базовых классов, таких как Object.Кроме того, внепроцессные клиенты, использующие раннее связывание, не могут вызывать соответствующий класс.
Предоставление классов клиентам вне процесса
Если требуется предоставить класс в надстройке внепроцессным клиентам, необходимо унаследовать класс от StandardOleMarshalObject, чтобы убедиться, что внепроцессные клиенты могут вызывать предоставленный объект надстройки.В противном случае попытки получить экземпляр вашего предоставленного объекта во внепроцессном клиенте могут завершаться неожиданным сбоем.
Это связано с тем, что все вызовы объектной модели приложения Office должны выполняться в основном потоке пользовательского интерфейса, а вызовы вашего объекта из внепроцессного клиента будут поступать в произвольном потоке RPC (удаленный вызов процедуры).Механизм COM-маршалирования в платформе .NET Framework не будет переключать потоки, а будет пытаться маршалировать вызов вашего объекта по входящему потоку RPC вместо основного потока пользовательского интерфейса.Если ваш объект является экземпляром класса, производного от класса StandardOleMarshalObject, входящие вызовы вашего объекта автоматически маршалируются в поток, в котором был создан предоставляемый объект, и этот поток будет основным потоком пользовательского интерфейса ведущего приложения.
Дополнительные сведения об использовании потоков в решениях Office см. в разделе Поддержка потока в Office.
Переопределение метода RequestComAddInAutomationService
В следующем примере кода показано переопределение метода RequestComAddInAutomationService в классе ThisAddIn соответствующей надстройки.В этом примере предполагается, что определен класс с именем AddInUtilities, к которому требуется предоставить доступ из других решений.Чтобы просмотреть этот код в контексте полного руководства, см. раздел Пошаговое руководство. Вызов кода из VBA в настройках на уровне приложения.
Private utilities As AddInUtilities
Protected Overrides Function RequestComAddInAutomationService() As Object
If utilities Is Nothing Then
utilities = New AddInUtilities()
End If
Return utilities
End Function
private AddInUtilities utilities;
protected override object RequestComAddInAutomationService()
{
if (utilities == null)
utilities = new AddInUtilities();
return utilities;
}
После загрузки надстройки среда выполнения Visual Studio Tools for Office (cреда выполнения) вызывает метод RequestComAddInAutomationService.Среда выполнения назначает возвращаемый объект свойству Object объекта COMAddIn, представляющего надстройку.Этот объект COMAddIn доступен другим решениям Office и решением, автоматизирующим Office.
Доступ к объектам из других решений
Чтобы вызвать предоставленный объект в вашей надстройке, выполните следующие действия в клиентском решении:
Получите объект COMAddIn, представляющий предоставленную настройку.Клиенты могут обращаться ко всем доступным надстройкам с помощью свойства Application.COMAddIns в объектной модели главного приложения Office.
Обратитесь к свойству Object объекта COMAddIn.Это свойство возвращает предоставленный объект из надстройки.
Вызовите членов предоставленного объекта.
Способы использования возвращаемого значения свойства COMAddIn.Object для клиентов VBA и прочих клиентов различаются.Для внепроцессных клиентов требуется дополнительный код для предотвращения возможного состояния гонки.
Доступ к объектам из решений VBA
В следующем примере кода показано использование VBA для вызова метода, предоставляемого надстройкой.Этот макрос VBA вызывает метод с именем ImportData, определенный в надстройке с именем ExcelImportData.Чтобы просмотреть этот код в контексте полного руководства, см. раздел Пошаговое руководство. Вызов кода из VBA в настройках на уровне приложения.
Sub CallVSTOMethod()
Dim addIn As COMAddIn
Dim automationObject As Object
Set addIn = Application.COMAddIns("ExcelImportData")
Set automationObject = addIn.Object
automationObject.ImportData
End Sub
Доступ к объектам из решений, не являющихся решениями VBA
В решениях, не являющихся решениями VBA, необходимо привести значение свойства COMAddIn.Object к реализуемому им интерфейсу, после чего можно вызывать предоставленные методы для объекта интерфейса.В следующем примере кода показан вызов метода ImportData из другой надстройки, созданной с использованием средств разработчика Office в Visual Studio.
Dim addIn As Office.COMAddIn = Globals.ThisAddIn.Application.COMAddIns.Item("ExcelImportData")
Dim utilities As ExcelImportData.IAddInUtilities = TryCast( _
addIn.Object, ExcelImportData.IAddInUtilities)
utilities.ImportData()
object addInName = "ExcelImportData";
Office.COMAddIn addIn = Globals.ThisAddIn.Application.COMAddIns.Item(ref addInName);
ExcelImportData.IAddInUtilities utilities = (ExcelImportData.IAddInUtilities)addIn.Object;
utilities.ImportData();
Если в этом примере попытаться привести значение свойства COMAddIn.Object к классу AddInUtilities, а не интерфейсу IAddInUtilities, в коде будет создано исключение InvalidCastException.
См. также
Задачи
Пошаговое руководство. Вызов кода из VBA в настройках на уровне приложения
Практическое руководство. Создание проектов Office в Visual Studio
Основные понятия
Архитектура надстроек уровня приложения
Настройка функций пользовательского интерфейса с помощью интерфейсов расширяемости