Compartir a través de


Inserción y automatización de documentos de Office con Visual Basic

Resumen

Al desarrollar una aplicación que usa datos en un documento de Office, puede ser beneficioso que esos datos se presenten directamente en la aplicación de Visual Basic para que el usuario pueda ver y editar los datos sin tener que cambiar a la aplicación de Office. Puede hacerlo en Visual Basic mediante el control contenedor OLE.

En este artículo se muestra cómo crear y automatizar dinámicamente un documento de Office mediante ole container control.

Más información

La capacidad de insertar un documento de Office en Visual Basic es posible gracias a la tecnología OLE (Object Linking and Embedding) de Microsoft. OLE está diseñado para permitir que una aplicación hospede un objeto que pertenece a otra aplicación de forma que sea conveniente para el usuario final, pero no requiere que las aplicaciones implicadas conozcan los detalles internos de la otra. Visual Basic proporciona el control contenedor OLE para permitir que los programadores de Visual Basic agreguen objetos OLE a un formulario.

Una vez incrustado el objeto, la mayoría de los servidores OLE admiten Automation para permitir que la aplicación host cambie o manipule mediante programación el objeto desde el código. Para obtener una referencia al objeto Automation, use la propiedad Object del contenedor OLE. Esta propiedad devuelve el objeto Automation que coincide estrechamente con el elemento determinado incrustado.

Creación de una aplicación de Visual Basic que hospede un libro de Excel

  1. Inicie Visual Basic y cree un nuevo proyecto estándar. Form1 se crea de forma predeterminada.

  2. En el cuadro de herramientas de controles, agregue tres botones de comando a Form1. A continuación, agregue una instancia del control Contenedor OLE. Cuando el control Contenedor OLE se coloca en el formulario, le pide el tipo de objeto que desea insertar. Para este ejemplo, debe agregar el objeto dinámicamente, por lo que haga clic en Cancelar para descartar el cuadro de diálogo sin agregar un objeto.

  3. En la ventana Código de Form1, agregue el código siguiente:

    Option Explicit
    
    Dim oBook As Object
    Dim oSheet As Object
    
    Private Sub Command1_Click()
       On Error GoTo Err_Handler
    
    ' Create a new Excel worksheet...
       OLE1.CreateEmbed vbNullString, "Excel.Sheet"
    
    ' Now, pre-fill it with some data you
     ' can use. The OLE.Object property returns a
     ' workbook object, and you can use Sheets(1)
     ' to get the first sheet.
       Dim arrData(1 To 5, 1 To 5) As Variant
       Dim i As Long, j As Long
    
    Set oBook = OLE1.object
       Set oSheet = oBook.Sheets(1)
    
    ' It is much more efficient to use an array to
     ' pass data to Excel than to push data over
     ' cell-by-cell, so you can use an array.
    
    ' Add some column headers to the array...
       arrData(1, 2) = "April"
       arrData(1, 3) = "May"
       arrData(1, 4) = "June"
       arrData(1, 5) = "July"
    
    ' Add some row headers...
       arrData(2, 1) = "John"
       arrData(3, 1) = "Sally"
       arrData(4, 1) = "Charles"
       arrData(5, 1) = "Toni"
    
    ' Now add some data...
       For i = 2 To 5
          For j = 2 To 5
             arrData(i, j) = 350 + ((i + j) Mod 3)
          Next j
       Next i
    
    ' Assign the data to Excel...
       oSheet.Range("A3:E7").Value = arrData
    
    oSheet.Cells(1, 1).Value = "Test Data"
       oSheet.Range("B9:E9").FormulaR1C1 = "=SUM(R[-5]C:R[-2]C)"
    
    ' Do some auto formatting...
       oSheet.Range("A1:E9").Select
       oBook.Application.Selection.AutoFormat
    
    Command1.Enabled = False
       Command2.Enabled = False
       Command3.Enabled = True
       Exit Sub
    
    Err_Handler:
       MsgBox "An error occurred: " & Err.Description, vbCritical
    End Sub
    
    Private Sub Command2_Click()
       On Error GoTo Err_Handler
    
    ' Create an embedded object using the data
     ' stored in Test.xls.<?xm-insertion_mark_start author="v-thomr" time="20070327T040420-0600"?> If this code is run in Microsoft Office
     ' Excel 2007, <?xm-insertion_mark_end?><?xm-deletion_mark author="v-thomr" time="20070327T040345-0600" data=".."?><?xm-insertion_mark_start author="v-thomr" time="20070327T040422-0600"?>change the file name to Test.xlsx.<?xm-insertion_mark_end?>
       OLE1.CreateEmbed "C:\Test.xls"
    
    Command1.Enabled = False
       Command2.Enabled = False
       Command3.Enabled = True
       Exit Sub
    
    Err_Handler:
       MsgBox "The file 'C:\Test.xls' does not exist" & _
              " or cannot be opened.", vbCritical
    End Sub
    
    Private Sub Command3_Click()
       On Error Resume Next
    
    ' Delete the existing test file (if any)...
       Kill "C:\Test.xls"
    
    ' Save the file as a native XLS file...
       oBook.SaveAs "C:\Test.xls"
       Set oBook = Nothing
       Set oSheet = Nothing
    
    ' Close the OLE object and remove it...
       OLE1.Close
       OLE1.Delete
    
    Command1.Enabled = True
       Command2.Enabled = True
       Command3.Enabled = False
    End Sub
    
    Private Sub Form_Load()
       Command1.Caption = "Create"
       Command2.Caption = "Open"
       Command3.Caption = "Save"
       Command3.Enabled = False
    End Sub
    
    
  4. Presione la tecla F5 para ejecutar el programa. Haga clic en el botón Crear. Esto inserta una nueva hoja de cálculo y automatiza Excel para agregar datos directamente a la hoja. Tenga en cuenta que si hace doble clic en el objeto, se activa localmente y el usuario puede editar los datos directamente. Ahora haga clic en Guardar para guardar los datos en un archivo y cerrar el objeto OLE. El botón Abrir le permite abrir una copia de un archivo guardado anteriormente.

Creación de una aplicación de Visual Basic que hospede un documento de Word

  1. Inicie Visual Basic y cree un nuevo proyecto estándar. Form1 se crea de forma predeterminada.

  2. En el cuadro de herramientas de controles, agregue tres botones de comando a Form1. A continuación, agregue una instancia del control Contenedor OLE. Cuando el control Contenedor OLE se coloca en el formulario, le pide el tipo de objeto que desea insertar. Para este ejemplo, es necesario agregar el objeto dinámicamente, por lo que haga clic en Cancelar para descartar el cuadro de diálogo sin agregar un objeto.

  3. En la ventana Código de Form1, agregue el código siguiente:

    Option Explicit
    
    Dim oDocument As Object
    
    Private Sub Command1_Click()
       On Error GoTo Err_Handler
    
    ' Create a new Word Document...
       OLE1.CreateEmbed vbNullString, "Word.Document"
    
    ' Add some text to the document. The OLE.Object
     ' property returns the document object...
       Set oDocument = OLE1.object
    
    oDocument.Content.Select
       With oDocument.Application.Selection
    
    ' Add a heading at the top of the document...
          .Style = oDocument.Styles("Heading 1")
          .Font.Color = &HFF0000
          .TypeText "Blue Sky Airlines"
          .ParagraphFormat.Alignment = 1 '[wdAlignParagraphCenter]
          .TypeParagraph
          .TypeParagraph
    
    ' Now add some text...
          .TypeText "Dear Mr. Smith,"
          .TypeParagraph
          .TypeParagraph
          .TypeText "Thank you for your interest in our current fares " & _
                    "from Oakland to Sacramento. We guarantee to be " & _
                    "the lowest price for local flights, or we'll " & _
                    "offer to make your next flight FREE!"
          .TypeParagraph
          .TypeParagraph
          .TypeText "The current fare for a flight leaving Oakland " & _
                    "on October 4, 1999 and arriving in Sacramento " & _
                    "the same day is $54.00."
          .TypeParagraph
          .TypeParagraph
          .TypeText "We hope you will choose to fly Blue Sky Airlines."
          .TypeParagraph
          .TypeParagraph
          .TypeText "Sincerely,"
          .TypeParagraph
          .TypeParagraph
          .TypeParagraph
          .TypeText "John Taylor"
          .TypeParagraph
          .Font.Italic = True
          .TypeText "Regional Sales Manager"
          .TypeParagraph
    
    End With
    
    ' Zoom to see entire document...
       OLE1.SizeMode = 3
       OLE1.DoVerb -1
    
    Command1.Enabled = False
       Command2.Enabled = False
       Command3.Enabled = True
       Exit Sub
    
    Err_Handler:
       MsgBox "An error occurred: " & Err.Description, vbCritical
    End Sub
    
    Private Sub Command2_Click()
       On Error GoTo Err_Handler
    
    ' Create an embedded object using the data
     ' stored in Test.doc.<?xm-insertion_mark_start author="v-thomr" time="20070327T040719-0600"?> If this code is run in Microsoft Office
     ' Word 2007, change the file name to Test.docx.<?xm-insertion_mark_end?><?xm-deletion_mark author="v-thomr" time="20070327T040717-0600" data=".."?>
       OLE1.CreateEmbed "C:\Test.doc"
    
    Command1.Enabled = False
       Command2.Enabled = False
       Command3.Enabled = True
       Exit Sub
    
    Err_Handler:
       MsgBox "The file 'C:\Test.doc' does not exist" & _
              " or cannot be opened.", vbCritical
    End Sub
    
    Private Sub Command3_Click()
       On Error Resume Next
    
    ' Delete the existinf test file (if any)...
       Kill "C:\Test.doc"
    
    ' Save the file as a native Word DOC file...
       oDocument.SaveAs "C:\Test.doc"
       Set oDocument = Nothing
    
    ' Close the OLE object and remove it...
       OLE1.Close
       OLE1.Delete
    
    Command1.Enabled = True
       Command2.Enabled = True
       Command3.Enabled = False
    End Sub
    
    Private Sub Form_Load()
       Command1.Caption = "Create"
       Command2.Caption = "Open"
       Command3.Caption = "Save"
       Command3.Enabled = False
    End Sub
    
    
  4. Presione la tecla F5 para ejecutar el programa. Haga clic en el botón Crear. Esto inserta un nuevo documento y automatiza Word para agregar datos directamente al documento. Tenga en cuenta que si hace doble clic en el objeto, se activa localmente y el usuario puede editar los datos directamente. Ahora haga clic en Guardar para guardar los datos en un archivo y cerrar el objeto OLE. El botón Abrir le permite abrir una copia de un archivo guardado anteriormente.

Consideraciones al usar el contenedor OLE

  • Si va a insertar desde un archivo existente, los datos que se ven dentro del contenedor OLE son una copia de los datos del archivo. Los cambios que realice no se guardarán automáticamente en el mismo archivo. Aunque puede usar una técnica similar a la anterior para guardar los resultados en un archivo específico, no todos los servidores OLE admiten esta funcionalidad. No se considera un comportamiento normal del objeto OLE.

  • Si está "vinculando" a un archivo, el objeto no se puede activar localmente. En su lugar, cuando el usuario hace doble clic en el objeto, el objeto se abre en la ventana de la aplicación de servidor. Solo los objetos incrustados se pueden activar en contexto.

  • El control contenedor OLE es compatible con los datos. Si tiene una base de datos Access 97 o Access 2000, puede enlazar el control a un campo Objeto OLE de la base de datos. Cuando se muestra el formulario, los datos se extraen de la base de datos y se muestran para que el usuario lo edite. Los cambios de edición realizados por el usuario se guardan automáticamente en la base de datos cuando se cierra el objeto OLE.

    Para enlazar los datos del control contenedor OLE, agregue un control Datos de Visual Basic y establezca su propiedad DatabaseName en la ruta de acceso de la base de datos. A continuación, establezca RecordSource en una tabla existente en la base de datos. Use la propiedad DataSource del control OLE para enlazar el control al control Datos de Visual Basic y, a continuación, establezca la propiedad DataField para que apunte a un campo determinado en el conjunto de registros que contiene el objeto OLE. Visual Basic hace el resto.

  • El tamaño y la posición del borde sombreado que se muestra cuando el contenedor se activa localmente viene determinado por el tamaño del objeto y las opciones seleccionadas para el control OLE. Este borde se muestra para marcar los límites de la ventana de edición. Los límites de la ventana de edición a menudo no coinciden con los límites del propio contenedor OLE; este comportamiento es normal para un objeto OLE. La ventana de edición no se puede modificar mediante programación desde Visual Basic.

  • Es posible que algunos métodos de Automatización no funcionen correctamente a menos que el objeto se haya hecho activo localmente. Para activar mediante programación un objeto OLE, use el método DoVerb y especifique vbOLEShow (-1) como verbo.

  • Puede determinar si el menú de un objeto vinculado o incrustado aparece en el formulario de contenedor estableciendo la propiedad NegotiateMenus de un formulario. Si la propiedad NegotiateMenus del formulario secundario se establece en True y el contenedor tiene definida una barra de menús, los menús del objeto se colocan en la barra de menús del contenedor cuando se activa el objeto. Si el contenedor no tiene barra de menús o la propiedad NegotiateMenus se establece en False, los menús del objeto no aparecen cuando se activa. Tenga en cuenta que la propiedad NegotiateMenus no se aplica a los formularios MDI, por lo que el menú de un formulario MDI no se puede combinar con los del objeto activado. Para ilustrar la negociación de menús, pruebe lo siguiente con la aplicación de ejemplo que creó en la sección anterior:

    1. Ejecute la aplicación y haga clic en el botón Crear para insertar un nuevo documento en el contenedor OLE.
    2. Haga clic con el botón derecho en el contenedor OLE y seleccione Editar para activar el objeto en contexto. Tenga en cuenta que los menús de la aplicación del objeto aparecen porque la propiedad NegotiateMenus de Form1 está establecida en True de forma predeterminada.
    3. Cierre el formulario para finalizar la aplicación.
    4. Con Form1 seleccionado, haga clic en Editor de menús en el menú Herramientas.
    5. Cree un nuevo menú de nivel superior con el archivo de título y el nombre mnuFile. Establezca la propiedad NegotiatePosition de este menú en "1-Left". Cree un elemento de menú con el título Abrir y el nombre mnuOpen.
    6. Haga clic en Aceptar para cerrar el editor de menús.
    7. Una vez más, ejecute la aplicación y haga clic en el botón Crear para insertar un nuevo documento en el contenedor OLE.
    8. Haga clic con el botón derecho en el contenedor OLE y seleccione Editar para activar el objeto en contexto. Observe que el menú de Form1 se ha combinado con los menús de la aplicación del objeto.

    Visual Basic no permite controlar el proceso de combinación de menús ni realizar cambios en los elementos de menú del servidor cuando se agregan. Sin embargo, puede cambiar o modificar los menús de una aplicación de Office a través de Automation mediante código similar al siguiente:

     ' This code disables the Insert|Object item on the merged menu...
       Dim oMenuBar As Object
       Set oMenuBar = oBook.Application.CommandBars("Worksheet Menu Bar")
       oMenuBar.Controls("&Insert").Controls("&Object...").Enabled = False
    
    

    Tenga en cuenta que es posible que sea necesario realizar algunos cambios antes de que el objeto se active localmente; de lo contrario, los cambios podrían no aparecer en el menú combinado.

    Nota Este punto de viñeta NO se aplica a Microsoft Office Excel 2007 ni a Microsoft Office Word 2007.

  • Visual Basic no admite actualmente la asignación de espacio de barra de herramientas. Por lo tanto, las barras de herramientas acopladas no aparecen normalmente cuando se activa el objeto. Sin embargo, podría ser posible mostrar una ventana de herramientas flotante con automatización:

       OLE1.DoVerb -1 '[vbOLEShow]
       With oBook.Application.CommandBars("Standard")
          .Position = 4 '[msoBarFloating]
          .Visible = True
       End With
    
    

    Nota Este punto de viñeta NO se aplica a Microsoft Office Excel 2007 ni a Microsoft Office Word 2007.

  • Para los programas que requieren que un objeto permanezca activo en contexto en todo momento, Microsoft ha proporcionado la tecnología Documentos ActiveX. No todos los servidores OLE son servidores de documentos ActiveX; Microsoft Word, Microsoft Excel y Microsoft PowerPoint son servidores de documentos ActiveX.

    Visual Basic no admite un control nativo para hospedar documentos ActiveX. Sin embargo, el control WebBrowser que viene con Internet Explorer (versión 3.0 y posteriores) admite esta forma de contención local. Es posible usar este control para abrir un documento de Office como documento ActiveX. Para obtener más información sobre el uso del control WebBrowser, consulte el siguiente artículo:

    243058 cómo usar el control WebBrowser para abrir un documento de Office

  • El método SaveToFile del contenedor OLE crea un archivo que se puede abrir en el contenedor OLE. Sin embargo, los archivos que se guardan con el método SaveToFile del contenedor OLE no se pueden abrir directamente en la aplicación de Office correspondiente. Si desea guardar el documento incrustado en el disco para que el documento se pueda abrir en la aplicación de destino, use el método SaveAs del documento de la aplicación:

    OLE1.object.SaveAs ("C:\MyNewFile.doc")