Как автоматизировать Excel из MFC и Visual C++ 2005 или Visual C++ .NET для заполнения или получения данных в диапазоне с помощью массивов

Сведения о версии microsoft C# .NET в этой статье см. в 302096. Сведения о версии microsoft Visual Basic .NET в этой статье см. в 302094.

Примечание.

Microsoft Visual C++ 2005, Microsoft Visual C++ .NET 2003 и Microsoft Visual C++ .NET 2002 поддерживают как модель управляемого кода, предоставляемую Microsoft платформа .NET Framework, так и неуправляемую собственную модель кода Microsoft Windows. Сведения в этой статье относятся только к неуправляемому коду Visual C++.

Аннотация

В этой пошаговой статье показано, как автоматизировать Microsoft Excel из Visual C++ 2005 или Visual C++ .NET для заполнения и извлечения значений в диапазоне с несколькими ячейками с помощью массивов.

Создание клиента службы автоматизации для Excel

Чтобы заполнить диапазон с несколькими ячейками, не заполняя ячейки по одному, можно задать для свойства Value объекта Range двумерный массив. Аналогичным образом можно получить двумерный массив значений для нескольких ячеек одновременно с помощью свойства Value. Следующие шаги демонстрируют этот процесс как для настройки, так и для извлечения данных с помощью двумерных массивов.

  1. Выполните действия, описанные в разделе "Создание клиента автоматизации" следующей статьи базы знаний Майкрософт, чтобы создать базовый клиент службы автоматизации:

    307473 Как использовать библиотеку типов для службы автоматизации Office из Visual C++ .NET

    На шаге 3 добавьте в форму вторую кнопку и флажок. Измените идентификатор кнопки на IDC_GETVALUES и заголовок на "Получить значения". Измените идентификатор флажка на IDC_CHECK и заголовок на "Заполнить строками".

    На шаге 4 статьи выберите "Библиотека объектов Microsoft Excel 10.0", если вы автоматизируете Excel 2002 из Office XP. Расположение по умолчанию для Excel 2002 — C:\Program Files\Microsoft Office\Office10\Excel.exe. Или выберите "Библиотека объектов Microsoft Excel 11.0", если вы автоматизируете Microsoft Office Excel 2003. Расположение по умолчанию для Excel 2003 — C:\Program Files\Microsoft Office\Office11\Excel.exe. Выберите следующие интерфейсы Microsoft Excel:

    • _Приложения
    • _Книги
    • _Лист
    • Range
    • Книги
    • Листы

    На шаге 6 добавьте следующие #include сразу после директивы #pragma once в Autoprojectdlg.h:

    #include "CApplication.h"
    #include "CRange.h"
    #include "CWorkbook.h"
    #include "CWorkbooks.h"
    #include "CWorksheet.h"
    #include "CWorksheets.h"
    
    
  2. Добавьте следующие две открытые переменные-члены в класс CAutoProjectDlg:

    CApplication oExcel;
    CWorkbook oBook;
    
    
  3. В диалоговом окне щелкните правой кнопкой мыши IDC_CHECK и выберите "Добавить переменную". Приведите имя переменной m_bFillWithStrings и нажмите кнопку "Готово".

  4. В диалоговом окне дважды щелкните "Выполнить" и замените приведенный ниже код.

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

    на:

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

    Примечание В Visual C++ 2005 необходимо добавить параметр компилятора поддержки среды CLR (/clr:oldSyntax), чтобы успешно скомпилировать предыдущий пример кода. Чтобы добавить параметр компилятора поддержки среды CLR, выполните следующие действия.

    1. Щелкните "Проект" и выберите пункт "Свойства имени проекта".

      Примечание. Имя проекта — это заполнитель для имени проекта.

    2. Разверните свойства конфигурации и нажмите кнопку "Общие".

    3. В правой области щелкните, чтобы выбрать поддержку среды CLR, старый синтаксис (/clr:oldSyntax) в параметрах проекта поддержки среды CLR.

    4. Чтобы выполнить поиск абонентской группы для пользователя в поле Абонентская группа (телефонный контекст), нажмите кнопку Обзор.

    Дополнительные сведения о параметрах компилятора поддержки среды CLR см. на следующем веб-сайте Microsoft Developer Network (MSDN):

    https://msdn.microsoft.com/en-us/library/k8d11d4s.aspxЭти действия применимы ко всей статье.
    5. Вернитесь в диалоговое окно и дважды щелкните "Получить значения". Замените приведенный ниже код.

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

    на:

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

Тестирование клиента службы автоматизации

  1. Нажмите клавишу F5, чтобы выполнить сборку и запуск примера программы.
  2. Щелкните "Выполнить". Программа запускает Excel с новой книгой и заполняет ячейки A1:E5 первого листа числовыми данными из массива.
  3. Нажмите кнопку "Получить значения". Программа извлекает данные из ячеек A1:E5 в новый массив и отображает результаты в окне сообщения.
  4. Выберите "Заполнить строками" и нажмите кнопку "Выполнить", чтобы заполнить ячейки A1:E5 строками.
  5. Нажмите кнопку "Получить значения", чтобы отобразить строковые значения в окне сообщения.

Устранение неполадок

Если добавить программы-оболочки классов для библиотеки объектов Excel с помощью параметра "Файл" в мастере добавления класса из TypeLib, при переходе к библиотеке объектов может появиться сообщение об ошибке. Чтобы избежать этой проблемы, вместо просмотра файла введите полный путь и имя файла для библиотеки объектов.

Если при сборке примера приложения вы получаете следующее сообщение об ошибке, измените значение Variant DialogBox в CRange.h на Variant _DialogBox:

предупреждение C4003: недостаточно фактических параметров для макроса DialogBoxA

Ссылки

Дополнительные сведения см. на следующем веб-сайте Microsoft Developer Network (MSDN): разработка Microsoft Office с помощью Visual Studio https://msdn.microsoft.com/en-us/library/aa188489(office.10).aspx

Дополнительные сведения об использовании массивов для установки и извлечения данных Excel в более ранних версиях Visual Studio см. в следующей статье базы знаний:

247412 INFO: Методы передачи данных в Excel из Visual Basic