Как автоматизировать 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. Следующие шаги демонстрируют этот процесс как для настройки, так и для извлечения данных с помощью двумерных массивов.
Выполните действия, описанные в разделе "Создание клиента автоматизации" следующей статьи базы знаний Майкрософт, чтобы создать базовый клиент службы автоматизации:
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"
Добавьте следующие две открытые переменные-члены в класс CAutoProjectDlg:
CApplication oExcel; CWorkbook oBook;
В диалоговом окне щелкните правой кнопкой мыши IDC_CHECK и выберите "Добавить переменную". Приведите имя переменной m_bFillWithStrings и нажмите кнопку "Готово".
В диалоговом окне дважды щелкните "Выполнить" и замените приведенный ниже код.
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, выполните следующие действия.
Щелкните "Проект" и выберите пункт "Свойства имени проекта".
Примечание. Имя проекта — это заполнитель для имени проекта.
Разверните свойства конфигурации и нажмите кнопку "Общие".
В правой области щелкните, чтобы выбрать поддержку среды CLR, старый синтаксис (/clr:oldSyntax) в параметрах проекта поддержки среды CLR.
Чтобы выполнить поиск абонентской группы для пользователя в поле Абонентская группа (телефонный контекст), нажмите кнопку Обзор.
Дополнительные сведения о параметрах компилятора поддержки среды 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); }
Тестирование клиента службы автоматизации
- Нажмите клавишу F5, чтобы выполнить сборку и запуск примера программы.
- Щелкните "Выполнить". Программа запускает Excel с новой книгой и заполняет ячейки A1:E5 первого листа числовыми данными из массива.
- Нажмите кнопку "Получить значения". Программа извлекает данные из ячеек A1:E5 в новый массив и отображает результаты в окне сообщения.
- Выберите "Заполнить строками" и нажмите кнопку "Выполнить", чтобы заполнить ячейки A1:E5 строками.
- Нажмите кнопку "Получить значения", чтобы отобразить строковые значения в окне сообщения.
Устранение неполадок
Если добавить программы-оболочки классов для библиотеки объектов 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