Combinación de personalizaciones de VBA y de nivel de documento

Puede utilizar código de Visual Basic para Aplicaciones (VBA) en un documento que forme parte de una personalización de nivel de documento de Microsoft Office Word o Microsoft Office Excel. Puede llamar a código VBA del documento desde el ensamblado de personalización o puede configurar el proyecto de modo que permita que el código VBA del documento llame a código del ensamblado de personalización.

Se aplica a: la información de este tema se aplica a proyectos de nivel de documento para Excel y Word. Para obtener más información, consulte Características disponibles por aplicación de Office lication y tipo de proyecto.

Comportamiento del código VBA en una personalización de nivel de documento

Al abrir el proyecto en Visual Studio, el documento se abre en modo de diseño. El código VBA no se ejecuta si el documento está en modo de diseño, así que puede trabajar en el documento y el código sin ejecutar el código VBA.

Al ejecutar la solución, los controladores de eventos de VBA y el ensamblado de personalización recopilan los eventos que se producen en el documento y ambos conjuntos de código se ejecutan. No se puede determinar de antemano qué código se ejecutará antes que el otro; se debe determinar mediante pruebas en cada caso individual. Puede obtener resultados inesperados si los dos conjuntos de código no se han coordinado y probado cuidadosamente.

Llamada al código VBA desde el ensamblado de personalización

Puede llamar a macros en documentos de Word y a funciones y macros en libros de Excel. Para ello, use uno de los siguientes métodos:

  • Para Word, llame al Run método de la Application clase .

  • En Excel, llame al método Run de la clase Application .

    En cada método, el primer parámetro identifica al nombre de la macro o función a la que desea llamar; los parámetros opcionales restantes especifican los parámetros que se van a pasar a la macro o función. El primer parámetro puede tener formatos diferentes para Word y Excel:

  • En Word, el primer parámetro es una cadena que puede ser cualquier combinación de nombre de plantilla, módulo y macro. Si especifica el nombre del documento, el código solo puede ejecutar macros en documentos relacionados con el contexto actual, no cualquier macro en cualquier documento.

  • En Excel, el primer parámetro puede ser una cadena que especifique el nombre de la macro, un Range que indique dónde está la función o un identificador de registro de una función DLL (XLL) registrada. Si pasa una cadena, esta se evaluará en el contexto de la hoja activa.

    En el ejemplo de código siguiente se muestra cómo llamar a una macro denominada MyMacro desde un proyecto de nivel de documento para Excel. En este ejemplo se da por supuesto que MyMacro se define en 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);

Nota:

Para obtener información sobre el uso de la variable global missing en lugar de parámetros opcionales en Visual C#, vea Escribir código en soluciones de Office.

Llamar al código en personalizaciones de nivel de documento desde VBA

Puede configurar un proyecto de nivel de documento para Word o Excel de modo que código de Visual Basic para Aplicaciones (VBA) del documento pueda llamar a código del ensamblado de personalización. Esto es útil en los siguientes escenarios:

  • Desea ampliar el código VBA existente en un documento mediante las características de una personalización de nivel de documento que está asociada con el mismo documento.

  • Desea que los servicios que desarrolla en una personalización de nivel de documento estén disponibles para los usuarios finales que pueden obtener acceso a los servicios al escribir código VBA en el documento.

    Las herramientas de desarrollo de Office en Visual Studio proporcionan una característica similar para los complementos de VSTO. Si va a desarrollar un complemento de VSTO, puede llamar al código en el complemento de VSTO desde otras soluciones de Microsoft Office. Para obtener más información, vea Llamar al código en complementos de VSTO desde otras soluciones de Office.

Nota:

Esta característica no se puede utilizar en proyectos de plantilla de Word. Se puede usar únicamente en proyectos de plantilla de Excel, libro de Excel o documento de Word.

Requisitos

Para habilitar código VBA para llamar al ensamblado de personalización, el proyecto debe cumplir los siguientes requisitos:

  • El documento debe tener una de las siguientes extensiones de nombre de archivo:

    • Para Word: .docm o .doc

    • Para Excel: .xlsm, .xltm, .xls o .xlt

  • El documento ya debe contener un proyecto de VBA con código VBA.

  • Se debe permitir que el código VBA del documento se ejecute sin pedir al usuario que habilite macros. Puede confiar en la ejecución de código VBA si agrega la ubicación del proyecto de Office a la lista de ubicaciones de confianza en la configuración del Centro de confianza de Word o Excel.

  • El proyecto de Office debe contener al menos una clase pública que contenga uno o más miembros públicos que esté exponiendo a VBA.

    Puede exponer métodos, propiedades y eventos a VBA. La clase que exponga puede ser una clase de elemento host (como ThisDocument para Word o ThisWorkbook y Sheet1 para Excel) u otra clase que defina en el proyecto. Para obtener más información sobre los elementos host, consulte Información general sobre los elementos host y los controles host.

Habilitación del código VBA para llamar al ensamblado de personalización

Hay dos maneras diferentes de exponer a los miembros de un ensamblado de personalización a código VBA en el documento:

  • Puede exponer miembros de una clase de elemento host en un proyecto de Visual Basic a VBA. Para ello, establezca la propiedad EnableVbaCallers del elemento host en True en la ventana Propiedades mientras el elemento host (es decir, el documento, la hoja de cálculo o el libro) está abierto en el diseñador. Visual Studio realiza automáticamente todo el trabajo necesario para permitir que el código VBA llame a los miembros de la clase.

  • Puede exponer miembros en cualquier clase pública de un proyecto de Visual C# o miembros de una clase de elemento que no sea host de un proyecto de Visual Basic a VBA. Esta opción le da más libertad para elegir qué clases expone a VBA, pero también exige más pasos manuales.

    Para ello, debe realizar los pasos principales siguientes:

    1. Exponer la clase a COM.

    2. Reemplazar el método GetAutomationObject de una clase de elemento host del proyecto para devolver una instancia de la clase que está exponiendo a VBA.

    3. Establecer la propiedad ReferenceAssemblyFromVbaProject de cualquier clase de elemento host del proyecto en True. Esto incrusta la biblioteca de tipos del ensamblado de personalización en el ensamblado y agrega una referencia a la biblioteca de tipos al proyecto de VBA del documento.

    Para obtener instrucciones detalladas, vea Cómo: Exponer código a VBA en un proyecto de Visual Basic y Cómo: Exponer código a VBA en un proyecto de Visual C#.

    Las propiedades EnableVbaCallers y ReferenceAssemblyFromVbaProject solo están disponibles en la ventana Propiedades en tiempo de diseño; no se pueden utilizar en tiempo de ejecución. Para ver las propiedades, abra el diseñador de un elemento host en Visual Studio. Para obtener más información sobre las tareas específicas que realiza Visual Studio al establecer estas propiedades, vea Tareas realizadas por las propiedades del elemento host.

Nota:

Si el documento o libro aún no contiene código VBA o si el código VBA del documento no es de confianza para ejecutar, recibirá un mensaje de error al establecer la propiedad EnableVbaCallers o ReferenceAssemblyFromVbaProject en True. Esto se debe a que Visual Studio no puede modificar el proyecto de VBA del documento en esta situación.

Uso de miembros en código VBA para llamar al ensamblado de personalización

Después de configurar el proyecto para que el código VBA pueda llamar al ensamblado de personalización, Visual Studio agrega los miembros siguientes al proyecto de VBA del documento:

  • Para todos los proyectos, Visual Studio agrega un método global denominado GetManagedClass.

  • Para los proyectos de Visual Basic en los que se exponen miembros de una clase de elemento host mediante la propiedad EnableVbaCallers , Visual Studio también agrega una propiedad denominada CallVSTOAssembly al ThisDocumentmódulo , ThisWorkbook, Sheet1, Sheet2o Sheet3 en el proyecto de VBA.

    Puede utilizar la propiedad CallVSTOAssembly o el método GetManagedClass para tener acceso a los miembros públicos de la clase que expuso a código VBA en el proyecto.

Nota:

Mientras desarrolla e implementa la solución, hay varias copias diferentes del documento donde puede agregar el código VBA. Para obtener más información, consulte Directrices para agregar código VBA al documento.

Usar la propiedad CallVSTOAssembly en un proyecto de Visual Basic

Utilice la propiedad CallVSTOAssembly para tener acceso a los miembros públicos que agregó a la clase de elemento host. Por ejemplo, la siguiente macro VBA llama a un método denominado MyVSTOMethod que se define en la clase Sheet1 de un proyecto de libro de Excel.

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

Esta propiedad es una manera más conveniente de llamar al ensamblado de personalización que el uso del método GetManagedClass directamente. CallVSTOAssembly devuelve un objeto que representa a la clase de elemento host que expuso a VBA. Los miembros y los parámetros de método del objeto devuelto aparecen en IntelliSense.

La propiedad CallVSTOAssembly tiene una declaración similar al código siguiente. Este código supone que ha expuesto la clase de elemento host Sheet1 de un proyecto de libro de Excel denominado ExcelWorkbook1 a VBA.

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

Uso del método GetManagedClass

Para usar el método global GetManagedClass , pase el objeto VBA que corresponde a la clase de elemento host que contiene el reemplazo del método GetAutomationObject . A continuación, utilice el objeto devuelto para obtener acceso a la clase que expuso a VBA.

Por ejemplo, la siguiente macro VBA llama a un método denominado MyVSTOMethod que se define en la clase de elemento host Sheet1 de un proyecto de libro de Excel llamado ExcelWorkbook1.

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

El método GetManagedClass tiene la siguiente declaración.

GetManagedClass(pdispInteropObject Object) As Object

Este método devuelve un objeto que representa a la clase que expuso a VBA. Los miembros y los parámetros de método del objeto devuelto aparecen en IntelliSense.

Directrices para agregar código VBA al documento

Hay varias copias diferentes del documento donde puede agregar código VBA que llama a la personalización de nivel de documento.

A medida que desarrolla y prueba la solución, puede escribir código VBA en el documento que se abre mientras depura o ejecuta el proyecto en Visual Studio (es decir, el documento de la carpeta de resultados de compilación). Sin embargo, cualquier código VBA que agregue a este documento se sobrescribirá la siguiente vez que compile el proyecto, ya que Visual Studio reemplaza el documento de la carpeta de resultados de compilación por una copia del documento de la carpeta de proyecto principal.

Si desea guardar el código VBA que agregue al documento mientras depura o ejecuta la solución, copie el código VBA en el documento de la carpeta de proyecto. Para obtener más información sobre el proceso de compilación, vea Compilar soluciones de Office.

Cuando esté listo para implementar la solución, hay tres ubicaciones principales del documento en las que puede agregar el código VBA.

En la carpeta del proyecto del equipo de desarrollo

Esta ubicación es conveniente si tiene un control completo sobre el código VBA del documento y el código de personalización. Dado que el documento se encuentra en el equipo de desarrollo, puede modificar fácilmente el código VBA si cambia el código de personalización. El código VBA que agregue a esta copia del documento permanece en el documento al compilar, depurar y publicar la solución.

No se puede agregar el código VBA al documento mientras está abierto en el diseñador. Primero debe cerrar el documento en el diseñador y, a continuación, abrirlo directamente en Word o Excel.

Precaución

Si agrega código VBA que se ejecuta al abrir el documento, en ciertas ocasiones este código podría dañar el documento o evitar que se abriera en el diseñador.

En la carpeta de publicación o instalación

En algunos casos, podría ser conveniente agregar el código VBA al documento en la carpeta de instalación o publicación. Por ejemplo, puede elegir esta opción si el código VBA ha sido escrito y probado por un otro desarrollador en un equipo que no tiene instalado Visual Studio.

Si los usuarios instalan la solución directamente desde la carpeta de publicación, debe agregar el código VBA al documento cada vez que publique la solución. Visual Studio sobrescribe el documento de la ubicación de publicación cuando se publica la solución.

Si los usuarios instalan la solución desde una carpeta de instalación distinta a la carpeta de publicación, puede evitar tener que agregar el código VBA en el documento cada vez que publique la solución. Cuando haya una actualización de publicación lista para moverse de la carpeta de publicación a la carpeta de instalación, copie todos los archivos en la carpeta de instalación, salvo el documento.

En el equipo del usuario final

Si los usuarios finales son desarrolladores de VBA que llaman a los servicios que proporciona en la personalización de nivel de documento, puede indicarles cómo llamar al código mediante la propiedad CallVSTOAssembly o el método GetManagedClass de sus copias del documento. Al publicar actualizaciones en la solución, no se sobrescribirá el código VBA del documento del equipo del usuario final, ya que las actualizaciones de publicación no modifican el documento.

Tareas realizadas por las propiedades del elemento host

Cuando se usan las propiedades EnableVbaCallers y ReferenceAssemblyFromVbaProject , Visual Studio realiza diferentes conjuntos de tareas.

EnableVbaCallers

Al establecer la propiedad EnableVbaCallers de un elemento host en True en un proyecto de Visual Basic, Visual Studio realiza las siguientes tareas:

  1. Agrega los atributos ComClassAttribute y ComVisibleAttribute a la clase de elemento host.

  2. Reemplaza el método GetAutomationObject de la clase de elemento host.

  3. Establece la propiedad ReferenceAssemblyFromVbaProject del elemento host en True.

    Al volver a establecer la propiedad EnableVbaCallers en False, Visual Studio realiza las siguientes tareas:

  4. Quita los atributos ComClassAttribute y ComVisibleAttribute de la clase ThisDocument .

  5. Quita el método GetAutomationObject de la clase de elemento host.

    Nota:

    Visual Studio no vuelve a establecer automáticamente la propiedad ReferenceAssemblyFromVbaProject en False. Puede establecer esta propiedad en False manualmente mediante la ventana Propiedades .

ReferenceAssemblyFromVbaProject

Al establecer la propiedad ReferenceAssemblyFromVbaProject de cualquier elemento host de un proyecto de Visual Basic o Visual C# en True, Visual Studio realiza las siguientes tareas:

  1. Genera una biblioteca de tipos para el ensamblado de personalización e incrusta la biblioteca de tipos en el ensamblado.

  2. Agrega una referencia a las siguientes bibliotecas de tipos en el proyecto de VBA del documento:

    • La biblioteca de tipos para el ensamblado de personalización.

    • La biblioteca de tipos de Microsoft Visual Studio Tools para Office Execution Engine 9.0. Esta biblioteca de tipos se incluye en el entorno de ejecución de Visual Studio Tools para Office .

    Cuando la propiedad ReferenceAssemblyFromVbaProject se vuelve a establecer en False, Visual Studio realiza las siguientes tareas:

  3. Quita las referencias de la biblioteca de tipos del proyecto de VBA del documento.

  4. Quita la biblioteca de tipos incrustada del ensamblado.

Solución de problemas

En la tabla siguiente se enumeran algunos errores comunes y sugerencias para corregir los errores.

Error Sugerencia
Después de establecer la propiedad EnableVbaCallers o ReferenceAssemblyFromVbaProject , un mensaje de error indica que el documento no contiene un proyecto de VBA o que no tiene permiso de acceso al proyecto de VBA en el documento. Asegúrese de que el documento del proyecto contenga al menos una macro VBA, de que el proyecto de VBA tenga la confianza suficiente para ejecutarse y de que el proyecto de VBA no esté protegido mediante contraseña.
Después de establecer la propiedad EnableVbaCallers o ReferenceAssemblyFromVbaProject , un mensaje de error indica que falta la declaración GuidAttribute o está dañada. Asegúrese de que la GuidAttribute declaración se encuentra en el archivo AssemblyInfo.cs o AssemblyInfo.vb del proyecto y que este atributo está establecido en un GUID válido.
Después de establecer la propiedad EnableVbaCallers o ReferenceAssemblyFromVbaProject , un mensaje de error indica que el número de versión especificado por el AssemblyVersionAttribute no es válido. Asegúrese de que la AssemblyVersionAttribute declaración en el archivo AssemblyInfo.cs o AssemblyInfo.vb del proyecto esté establecida en un número de versión de ensamblado válido. Para obtener información sobre los números de versión de ensamblado válidos, vea la clase AssemblyVersionAttribute .
Después de cambiar el nombre del ensamblado de personalización, el código VBA que llama al ensamblado de personalización deja de funcionar. Si cambia el nombre del ensamblado de personalización después exponerlo a código VBA, se rompe el vínculo entre el proyecto de VBA del documento y el ensamblado de personalización. Para corregir este problema, cambie la propiedad ReferenceFromVbaAssembly del proyecto a False y luego de nuevo a Truey, a continuación, reemplace cualquier referencia al antiguo nombre del ensamblado del código VBA por el nuevo nombre del ensamblado.