Cómo automatizar Excel desde MFC y Visual C++ 2005 o Visual C++ .NET para rellenar u obtener datos en un intervalo mediante matrices

Para obtener una versión de Microsoft C# .NET de este artículo, consulte 302096. Para obtener una versión de Microsoft Visual Basic .NET de este artículo, consulte 302094.

Nota:

Microsoft Visual C++ 2005, Microsoft Visual C++ .NET 2003 y Microsoft Visual C++ .NET 2002 admiten tanto el modelo de código administrado proporcionado por Microsoft .NET Framework como el modelo de código nativo de Microsoft Windows no administrado. La información de este artículo solo se aplica al código de Visual C++ no administrado.

Resumen

En este artículo paso a paso se muestra cómo automatizar Microsoft Excel desde Visual C++ 2005 o Visual C++ .NET para rellenar y recuperar valores en un intervalo de varias celdas mediante matrices.

Creación de un cliente de Automation para Excel

Para rellenar un rango de varias celdas sin rellenar celdas de una en una, puede establecer la propiedad Value de un objeto Range en una matriz bidimensional. Del mismo modo, puede recuperar una matriz bidimensional de valores para varias celdas a la vez mediante la propiedad Value. En los pasos siguientes se muestra este proceso para establecer y recuperar datos mediante matrices bidimensionales.

  1. Siga los pasos descritos en la sección "Crear un cliente de Automation" del siguiente artículo de Microsoft Knowledge Base para crear un cliente de Automation básico:

    307473 Cómo usar una biblioteca de tipos para Office Automation desde Visual C++ .NET

    En el paso 3, agregue un segundo botón y una casilla al formulario. Cambie el identificador del botón a IDC_GETVALUES y el título a Obtener valores. Cambie el identificador de la casilla a IDC_CHECK y el título a Rellenar con cadenas.

    En el paso 4 del artículo, seleccione "Biblioteca de objetos de Microsoft Excel 10.0" si va a automatizar Excel 2002 desde Office XP. La ubicación predeterminada para Excel 2002 es C:\Archivos de programa\Microsoft Office\Office10\Excel.exe. O bien, seleccione "Biblioteca de objetos de Microsoft Excel 11.0" si va a automatizar Microsoft Office Excel 2003. La ubicación predeterminada para Excel 2003 es C:\Archivos de programa\Microsoft Office\Office11\Excel.exe. Seleccione las siguientes interfaces de Microsoft Excel:

    • _Aplicación
    • _Libro
    • _Hoja de cálculo
    • Rango
    • Libros
    • Worksheets

    En el paso 6, agregue las siguientes instrucciones #include directamente después de la directiva #pragma once en Autoprojectdlg.h:

    #include "CApplication.h"
    #include "CRange.h"
    #include "CWorkbook.h"
    #include "CWorkbooks.h"
    #include "CWorksheet.h"
    #include "CWorksheets.h"
    
    
  2. Agregue las dos variables miembro públicas siguientes a la clase CAutoProjectDlg:

    CApplication oExcel;
    CWorkbook oBook;
    
    
  3. En el cuadro de diálogo, haga clic con el botón derecho en IDC_CHECK y seleccione Agregar variable. Asigne a la variable el nombre m_bFillWithStrings y haga clic en Finalizar.

  4. En el cuadro de diálogo, haga doble clic en Ejecutar y reemplace el código siguiente.

    void CAutoProjectDlg::OnBnClickedRun()
    {
    // TODO: Add your control notification handler code here
    }
    
    

    con:

    void CAutoProjectDlg::OnBnClickedRun()
    {
    CWorkbooks oBooks;
    CWorksheets oSheets;
    CWorksheet oSheet;
    CRange oRange;
    COleVariant covOptional(DISP_E_PARAMNOTFOUND,VT_ERROR);
    
    // If you have not created Excel, create a new instance.
    if (oExcel.m_lpDispatch == NULL) {
    oExcel.CreateDispatch("Excel.Application");
    }
    // Show Excel to the user.
    oExcel.put_Visible(TRUE);
    oExcel.put_UserControl(TRUE);
    
    // Add a new workbook and get the first worksheet in that book.
    oBooks = oExcel.get_Workbooks();
    oBook = oBooks.Add(covOptional);
    oSheets = oBook.get_Worksheets();
    oSheet = oSheets.get_Item(COleVariant((short)1));
    
    // Get a range of data.
    oRange = oSheet.get_Range(COleVariant("A1"),covOptional);
    oRange = oRange.get_Resize(COleVariant((short)5),COleVariant((short)5));
    
    COleSafeArray saRet;
    DWORD numElements[2];
    numElements[0] = 5;
    numElements[1] = 5;
    
    long index[2];
    // Create a BSTR or double safe array.
    if (m_bFillWithStrings.GetCheck())
    saRet.Create(VT_BSTR,2,numElements);
    else
    saRet.Create(VT_R8,2,numElements);
    
    // Fill the array with data.
    for (int iRow = 1; iRow <= 5; iRow++) {
    for (int iCol = 1; iCol <= 5; iCol++) {
    index[0]=iRow-1;
    index[1]=iCol-1;
    if (m_bFillWithStrings.GetCheck()) {
    CString szTemp;
    szTemp.Format("%d|%d",iRow,iCol);
    BSTR bstr = szTemp.AllocSysString();
    saRet.PutElement(index,bstr);
    SysFreeString(bstr);
    } else {
    double d = iRow * iCol;
    saRet.PutElement(index,&d);
    }
    }
    }
    // Send the array to Excel.
    oRange.put_Value(covOptional,COleVariant(saRet));
    }
    
    

    Nota En Visual C++ 2005, debe agregar la opción del compilador de compatibilidad con Common Language Runtime (/clr:oldSyntax) para compilar correctamente el ejemplo de código anterior. Para agregar la opción del compilador de compatibilidad con Common Language Runtime, siga estos pasos:

    1. Haga clic en Proyectoy, a continuación, haga clic en Propiedades de NombreDeProyecto.

      NotaProjectName es un marcador de posición para el nombre del proyecto.

    2. Expanda Propiedades de configuracióny, a continuación, haga clic en General.

    3. En el panel derecho, haga clic para seleccionar Compatibilidad con Common Language Runtime, Sintaxis antigua (/clr:oldSyntax) en la configuración del proyecto de soporte técnico de Common Language Runtime .

    4. En el cuadro Plan de marcado (contexto telefónico), haga clic en Examinar para buscar el plan de marcado del usuario.

    Para obtener más información sobre las opciones del compilador de compatibilidad con Common Language Runtime, visite el siguiente sitio web de Microsoft Developer Network (MSDN):

    https://msdn.microsoft.com/en-us/library/k8d11d4s.aspxEstos pasos se aplican a todo el artículo.
    5. Vuelva al cuadro de diálogo y haga doble clic en Obtener valores. Reemplace el código siguiente.

    void CAutoProjectDlg::OnBnClickedGetvalues()
    {
    // TODO: Add your control notification handler code here
    }
    
    

    con:

    void CAutoProjectDlg::OnBnClickedGetvalues()
    {
    CWorksheets oSheets;
    CWorksheet oSheet;
    CRange oRange;
    COleVariant covOptional(DISP_E_PARAMNOTFOUND,VT_ERROR);
    
    // Make sure that Excel has been started.
    if (oExcel.m_lpDispatch == NULL) {
    AfxMessageBox("Excel has not been started.  Press button1 to start Excel.");
    return;
    }
    // Get the first worksheet.
    oSheets = oBook.get_Worksheets();
    oSheet = oSheets.get_Item(COleVariant((short)1));
    // Set the range of data to retrieve
       oRange = oSheet.get_Range(COleVariant("A1"),COleVariant("E5"));
    
    // Get the data.
    COleSafeArray saRet(oRange.get_Value(covOptional));
    
    long iRows;
            long iCols;
            saRet.GetUBound(1, &iRows);
            saRet.GetUBound(2, &iCols);
    
    CString valueString = "Array Data:\r\n";
    long index[2];
    // Loop through the data and report the contents.
    for (int rowCounter = 1; rowCounter <= iRows; rowCounter++) {
    for (int colCounter = 1; colCounter <= iCols; colCounter++) {
    index[0]=rowCounter;
    index[1]=colCounter;   
    COleVariant vData;
    saRet.GetElement(index,vData);
    CString szdata(vData);
                valueString += szdata;
    valueString += "\t";
    }
    valueString += "\r\n";
    }
    AfxMessageBox(valueString,MB_SETFOREGROUND,NULL);
    }
    
    

Prueba del cliente de Automation

  1. Presione F5 para compilar y ejecutar el programa de ejemplo.
  2. Haga clic en Ejecutar. El programa inicia Excel con un nuevo libro y rellena las celdas A1:E5 de la primera hoja de cálculo con datos numéricos de una matriz.
  3. Haga clic en Obtener valores. El programa recupera los datos de las celdas A1:E5 en una nueva matriz y muestra los resultados en un cuadro de mensaje.
  4. Seleccione Rellenar con cadenas y haga clic en Ejecutar para rellenar las celdas A1:E5 con datos de cadena.
  5. Haga clic en Obtener valores para mostrar los valores de cadena en un cuadro de mensaje.

Solución de problemas

Si agrega contenedores de clases para la biblioteca de objetos de Excel mediante la opción Archivo del Asistente para agregar clases desde typelib, puede recibir un mensaje de error al ir a la biblioteca de objetos. Para evitar este problema, escriba la ruta de acceso completa y el nombre de archivo de la biblioteca de objetos en lugar de examinar el archivo.

Si recibe el siguiente mensaje de error al compilar la aplicación de ejemplo, cambie "Variant DialogBox" en CRange.h a "Variant _DialogBox":

advertencia C4003: no hay suficientes parámetros reales para la macro 'DialogBoxA'

Referencias

Para obtener más información, consulte el siguiente sitio web de Microsoft Developer Network (MSDN): Desarrollo de Microsoft Office con Visual Studio https://msdn.microsoft.com/en-us/library/aa188489(office.10).aspx

Para obtener más información sobre el uso de matrices para establecer y recuperar datos de Excel con versiones anteriores de Visual Studio, consulte el siguiente artículo de Knowledge Base:

247412 INFO: métodos para transferir datos a Excel desde Visual Basic