HOW TO: 从 C++ .NET 和 MFC 实现 Excel 的自动化操作以便使用数组填充或获取某个范围的数据

本文的发布号曾为 CHS308407
有关本文的 Microsoft C# .NET 版本,请参见 302096
有关本文的 Microsoft Visual Basic .NET 版本,请参见 302094

本任务的内容

概要
本分步指南演示如何从 Visual C++ .NET 实现 Excel 的自动化操作以便使用数组填充和检索多单元格范围内的值。

返回页首

为 Excel 创建自动化客户端

若要填充一个多单元格范围而无需一次填充一个单元格,请将 Range 对象的 Value 属性设置为一个二维数组。 同样,可通过使用 Value 属性同时检索多个单元格的值的二维数组。下面的步骤演示如何使用二维数组设置并检索数据。
  1. 按照下列 Microsoft 知识库文章中“Create an Automation Client”(创建自动化客户端)一节中的步骤创建基本的自动化客户端:
    307473 HOWTO: Use a Type Library for Office Automation from Visual C++ .NET(从 Visual C++ .NET 使用 Office 自动化的类型库)
    在第 3 步中,在窗体中添加第二个按钮和一个复选框。 将该按钮的 ID 更改为 IDC_GETVALUES,将标题更改为 Get Values。 将该复选框的 ID 更改为 IDC_CHECK,将标题更改为 Fill with Strings

    在本文的第 4 步中,选择 Excel 类型库。 Excel 2000 的默认位置是 C:\Program Files\Microsoft Office\Office\excel9.olb,Excel 2002 的默认位置是 C:\Program Files\Microsoft Office\Office10\excel.exe。选择以下 Microsoft Excel 接口:

    • _Application
    • _Workbook
    • _Worksheet
    • Range
    • Workbooks
    • Worksheets
    在第 6 步中,将下列 #include 语句直接放在 Autoprojectdlg.h 中的 #pragma once 指令后面:
    #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));}
  5. 替换为:返回到对话框并双击 Get Values。 将以下代码
    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. 单击 Get Values。该程序将检索单元格 A1:E5 中的数据并填充到一个新的数组中,然后将结果显示在一个消息框中。
  4. 选择 Fill With Strings 并单击运行以便用字符串型数据填充 A1:E5 单元格。
  5. 单击 Get Values 以便将字符串值显示在消息框中。
返回页首

疑难解答

如果在“从类型库添加类向导”中通过使用 File(文件)选项为 Excel 对象库添加类包装,则在浏览到该对象库时可能收到错误信息。 若要避免此问题,请键入该对象库的完整路径和文件名,而非浏览该文件。有关其他信息,请单击下列文章编号,查看相应的 Microsoft 知识库文章:
311408 BUG: &apos;Read-Only&apos; Warning When Adding MFC Class From Library(在从库添加 MFC 类时出现“只读”警告)
如果在生成示例应用程序时收到以下错误信息,请将 CRange.h 中的“Variant DialogBox”更改为“Variant _DialogBox”:
警告 C4003: “DialogBoxA”宏的实参不足
有关此错误的原因的更多信息,请参见下列知识库文章:
311407 BUG: MFC Wizard Doesn&apos;t Resolve Naming Conflicts with API Macros(MFC 向导不解决与 API 宏的命名冲突)
返回页首
参考
有关更多信息,请访问下面的 Microsoft Developer Network (MSDN) Web 站点:
使用 Visual Studio 进行 Microsoft Office 开发
http://msdn2.microsoft.com/en-us/library/aa188489(office.10).aspx
有关在低版本的 Visual Studio 中使用数组设置和检索 Excel 数据的更多信息,请参见下列知识库文章:
186120 HOWTO:Use MFC to Automate Excel and Fill a Range with an Array(使用 MFC 实现 Excel 的自动化操作并使用数组填充一个范围)
186122 HOWTO:Use MFC to Automate Excel and Obtain an Array from a Range(使用 MFC 实现 Excel 的自动化操作并从一个范围获得一个数组)
247412 INFO: Methods for Transferring Data to Excel from Visual Basic(用于将数据从 Visual Basic 传送到 Excel 的方法)


返回页首
xl range mfc
属性

文章 ID:308407 - 上次审阅时间:01/17/2007 08:50:00 - 修订版本: 3.1

Microsoft Visual C++ .NET 2002 标准版, Microsoft Excel 2000 标准版, Microsoft Excel 2002 标准版

  • kbhowtomaster kbautomation kbgrpdso KB308407
反馈