Llamar a código en complementos de nivel de aplicación desde otras soluciones de Office

Puede exponer un objeto del complemento a otras soluciones, incluidas otras soluciones de Microsoft Office. Esto resulta útil si el complemento proporciona un servicio que desea habilitar para que lo usen otras soluciones. Por ejemplo, si tiene un complemento para Microsoft Office Excel que realiza cálculos en datos financieros de un servicio Web, otras soluciones pueden realizar estos cálculos mediante una llamada en tiempo de ejecución al complemento de Excel.

Se aplica a: la información de este tema se aplica a los proyectos de nivel de aplicación para Microsoft Office 2010 y 2007 Microsoft Office System. Para obtener más información, vea Características disponibles por aplicación y tipo de proyecto de Office.

Este proceso tiene dos pasos principales:

  • En su complemento, exponer un objeto a otras soluciones.

  • En otra solución, obtener acceso al objeto expuesto por el complemento y llamar a los miembros del objeto.

Tipos de soluciones que pueden llamar al código de un complemento

Puede exponer un objeto del complemento a los siguientes tipos de soluciones:

  • Código de Visual Basic para Aplicaciones (VBA) en un documento que se carga en el mismo proceso de la aplicación que el complemento.

  • Personalizaciones de nivel de documento que se cargan en el mismo proceso de aplicación que el complemento.

  • Otros complementos creados mediante las plantillas de proyecto de Office en Visual Studio.

  • Complementos COM (es decir, complementos que implementan directamente la interfaz IDTExtensibility2).

  • Cualquier solución que se ejecute en un proceso diferente que su complemento (estos tipos de soluciones también se denominan clientes fuera de proceso). Se incluyen, entre otras, las aplicaciones que automatizan una aplicación de Office, como una aplicación de consola o Windows Forms, y los complementos que se cargan en un proceso diferente.

Exponer objetos a otras soluciones

Para exponer un objeto del complemento a otras soluciones, realice los pasos siguientes en el complemento:

  1. Defina una clase que desee exponer a otras soluciones.

  2. Invalide el método RequestComAddInAutomationService en la clase ThisAddIn. Devuelva una instancia de la clase que desea exponer a otras soluciones.

Definir la clase que desee exponer a otras soluciones

Como mínimo, la clase que desea exponer debe ser pública, debe tener el atributo ComVisibleAttribute establecido en true y debe exponer la interfaz IDispatch.

Para exponer la interfaz IDispatch recomendamos que siga estos pasos:

  1. Defina una interfaz que declare los miembros que desea exponer a otras soluciones. Puede definir esta interfaz en el proyecto de complemento. Sin embargo, puede definir esta interfaz en un proyecto de biblioteca de clases independiente si desea exponer la clase a soluciones que no son de VBA, de modo que las soluciones que llamen al complemento puedan hacer referencia a la interfaz sin hacer referencia al proyecto de complemento.

  2. Aplique el atributo ComVisibleAttribute a esta interfaz, y establézcalo en true.

  3. Modifique la clase para implementar esta interfaz.

  4. Aplique el atributo ClassInterfaceAttribute a la clase y establézcalo en el valor None de la enumeración ClassInterfaceType.

  5. Si desea exponer la clase a clientes fuera de proceso, también puede que tenga que hacer lo siguiente:

    • Derive la clase de StandardOleMarshalObject. Para obtener más información, vea Exponer clases a clientes fuera de proceso.

    • Establezca la propiedad Registrar para interoperabilidad COM en el proyecto en el que defina la interfaz. Esto solo es necesario si desea permitir que los clientes utilicen el enlace anticipado para llamar al complemento. Para obtener más información, vea Cómo: Registrar un componente para interoperabilidad COM.

En el ejemplo de código siguiente se muestra una clase AddInUtilities con un método ImportData al que pueden llamar otras soluciones. Para consultar este código en el contexto de un tutorial mayor, vea Tutorial: Llamar a código de VBA en un complemento de nivel de aplicación.

<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";
        }
    }
}

Exponer clases a VBA

Cuando realiza los pasos indicados anteriormente, el código de VBA solo puede llamar a los métodos declarados en la interfaz. El código de VBA no puede llamar a cualquier otro método de la clase, ni siquiera los métodos que la clase obtiene de clases base como Object.

También puede exponer la interfaz IDispatch estableciendo el atributo ClassInterfaceAttribute en el valor AutoDispatch o AutoDual de la enumeración ClassInterfaceType. Si lo hace, no tiene que declarar los métodos en una interfaz independiente. Sin embargo, el código de VBA puede llamar a cualquier método público y no estático de la clase, incluso a los métodos obtenidos de clases base como Object. Además, los clientes fuera de proceso que utilizan el enlace anticipado no pueden llamar a la clase.

Exponer clases a clientes fuera de proceso

Si desea exponer una clase en el complemento a clientes fuera de proceso, debe derivar la clase de StandardOleMarshalObject para garantizar que los clientes fuera de proceso pueden llamar al objeto de complemento expuesto. De lo contrario, podría producirse un error inesperado al intentar obtener una instancia del objeto expuesto en un cliente fuera de proceso.

Esto se debe a que todas las llamadas al modelo de objetos de una aplicación de Office se deben realizar en el subproceso de la interfaz de usuario principal, pero las llamadas de un cliente fuera de proceso al objeto llegarán en un subproceso RPC (llamada a procedimiento remoto) arbitrario. El mecanismo de cálculo de referencias COM de .NET Framework no intercambiará los subprocesos e intentará calcular las referencias de la llamada al objeto en el subproceso RPC de entrada en lugar del subproceso de la interfaz de usuario principal. Si el objeto es una instancia de una clase que deriva de StandardOleMarshalObject, las referencias a las llamadas entrantes al objeto se calculan automáticamente en el subproceso donde se creó el objeto expuesto, que será el subproceso de la interfaz de usuario principal de la aplicación host.

Para obtener más información sobre el uso de subprocesos en soluciones de Office, vea Compatibilidad del subprocesamiento en Office.

Invalidar el método RequestComAddInAutomationService

En el ejemplo de código siguiente se muestra cómo invalidar RequestComAddInAutomationService en la clase ThisAddIn en el complemento. En este ejemplo se supone que ha definido una clase denominada AddInUtilities que desea exponer a otras soluciones. Para consultar este código en el contexto de un tutorial mayor, vea Tutorial: Llamar a código de VBA en un complemento de nivel de aplicación.

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;
}

Cuando se carga el complemento, Motor en tiempo de ejecución de Microsoft Visual Studio Tools para Office llama al método RequestComAddInAutomationService. El motor en tiempo de ejecución asigna el objeto devuelto a la propiedad Object de un objeto COMAddIn que representa el complemento. Este objeto COMAddIn está disponible para otras soluciones de Office y para las soluciones que automatizan Office.

Obtener acceso a objetos desde otras soluciones

Para llamar al objeto expuesto en el complemento, siga estos pasos en la solución cliente:

  1. Obtenga el objeto COMAddIn que representa el complemento expuesto. Los clientes pueden obtener acceso a todos los complementos disponibles mediante la propiedad Application.COMAddIns del modelo de objetos de la aplicación host de Office.

  2. Obtenga acceso a la propiedad Object del objeto COMAddIn. Esta propiedad devuelve el objeto expuesto desde el complemento.

  3. Llame a los miembros del objeto expuesto.

La manera en que se usa el valor devuelto de la propiedad COMAddIn.Object es diferente para clientes de VBA y clientes no VBA. En el caso de los clientes fuera de proceso, se requiere código adicional para evitar una posible condición de carrera.

Obtener acceso a objetos desde soluciones de VBA

En el siguiente ejemplo de código se muestra cómo usar VBA para llamar a un método expuesto por un complemento. Esta macro de VBA llama a un método denominado ImportData que se define en un complemento con el nombre ExcelImportData. Para consultar este código en el contexto de un tutorial mayor, vea Tutorial: Llamar a código de VBA en un complemento de nivel de aplicación.

Sub CallVSTOMethod()
    Dim addIn As COMAddIn
    Dim automationObject As Object
    Set addIn = Application.COMAddIns("ExcelImportData")
    Set automationObject = addIn.Object
    automationObject.ImportData
End Sub

Obtener acceso a objetos desde soluciones que no son de VBA

En una solución que no sea de VBA debe convertir el valor de la propiedad COMAddIn.Object en la interfaz que implementa y, a continuación, puede llamar a los métodos expuestos en el objeto de interfaz. En el ejemplo de código siguiente se muestra cómo llamar al método ImportData desde un complemento diferente creado con las herramientas para desarrollador de Office en 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();

En este ejemplo, si intenta convertir el valor de la propiedad COMAddIn.Object en la clase AddInUtilities en lugar de en la interfaz IAddInUtilities, el código producirá una excepción InvalidCastException.

Vea también

Tareas

Tutorial: Llamar a código de VBA en un complemento de nivel de aplicación

Cómo: Crear proyectos de Office en Visual Studio

Conceptos

Personalizar características de la interfaz de usuario mediante interfaces de extensibilidad

Arquitectura de los complementos de nivel de aplicación

Otros recursos

Programar complementos de nivel de aplicación

Desarrollar soluciones de Office

Historial de cambios

Fecha

Historial

Motivo

Septiembre de 2010

Se ha mejorado la organización del contenido y quitado información redundante.

Mejora de la información.