- UID
- 76681
- 积分
- 432
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2003-9-3
- 最后登录
- 1970-1-1
|
发表于 2005-11-5 01:36:00
|
显示全部楼层
在实际的工作中,我们经常要对一些表格数据进行处理,如果先把这些表格数据通过Excel处理,再导入到AutoCAD,那绝对会起到事半功倍的效果。随着Automation编程技术的出现,我们可以很方便地实现这一点了,我编的TrueTable就是采用了这个技术,下面是其中动态读取Excel数据的模块,不过进行了些简化,功能是动态关联Excel,然后读取其数据,并将这些数据打印在文本域中。
??
??//动态从Excel读取数据
??int DynamicReadFromExcel()
??{
?? //常用变量定义
?? _Application app;
?? Workbooks books;
?? _Workbook book;
?? Worksheets sheets;
?? _Worksheet sheet;
?? Range range;
?? Range iCell;
??
?? LPDISPATCH lpDisp;
?? COleVariant
?? covTrue((short)TRUE),
?? covFalse((short)FALSE),
?? covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
?? COleVariant vResult;
??
?? //采用MFC方式初始化COM库,程序结束时COM库会自动释放
?? if(!AfxOleInit())
?? {
?? MessageBox(NULL,"初始化COM支持库失败!\n无法控制Excel!", \
?? "TrueTable",MB_ICONERROR | MB_OK);
?? return RTERROR;
?? }
??
?? //关联已经运行的Excel实例
?? CLSID clsid;
?? CLSIDFromProgID(L"Excel.Application", &clsid);
?? IUnknown *pUnk = NULL;
?? IDispatch *pRunDisp = NULL;
??
?? for(long i=1;i<=5;i++) //做5次尝试
?? {
?? HRESULT hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);
?? if(SUCCEEDED(hr))
?? {
?? hr = pUnk->QueryInterface(IID_IDispatch, (void **)&pRunDisp);
?? break;
?? }
?? ::Sleep(10);
?? }
??
?? if (!pRunDisp)
?? {
?? ::MessageBox(NULL, "没有发现Excel!", "TrueTable", MB_ICONHAND);
?? return RTERROR;
?? }
??
?? if (pUnk) pUnk->Release();
??
?? //关联Excel
?? app.AttachDispatch (pRunDisp);
??
?? //得到当前活跃sheet
?? //如果有单元格正处于编辑状态中,此操作不能返回,会一直等待
?? lpDisp=app.GetActiveSheet();
?? if(lpDisp==NULL)
?? {
?? MessageBox(NULL, "没有发现有效的表格!", \
?? "TrueTable",MB_ICONERROR | MB_OK);
?? app.ReleaseDispatch ();
??
?? return RTERROR;
?? }
?? sheet.AttachDispatch(lpDisp);
??
?? //已经使用的行数:
?? long row_num;
?? range.AttachDispatch(sheet.GetUsedRange());
?? range.AttachDispatch(range.GetRows());
?? row_num=range.GetCount();
??
??
?? //已经使用的列数:
?? long col_num;
?? range.AttachDispatch(sheet.GetUsedRange());
?? range.AttachDispatch(range.GetColumns());
?? col_num=range.GetCount();
??
?? //已经使用区域的起始行、列:
?? range.AttachDispatch(sheet.GetUsedRange());
?? long StartRow=range.GetRow(); //起始行
?? long StartCol=range.GetColumn(); //起始列
??
?? //读取sheet名
?? CString SheetName=sheet.GetName();
?? //ads_printf("\n%s",SheetName);
?? if(col_num<2 && row_num<2) //此sheet为空
?? {
?? MessageBox(NULL,"\n当前表格没有数据!", \
?? "TrueTable",MB_ICONERROR | MB_OK);
?? app.ReleaseDispatch ();
??
?? return RTERROR;
??
?? }
?? else
?? {
?? ads_printf("\n表格%s共%d行,%d列",SheetName,row_num,col_num);
?? }
??
??
??
?? //得到全部Cells,此时,range是cells的集合
?? range.AttachDispatch(sheet.GetCells());
??
??
?? //读写数据了
?? CString cstr;
?? ads_printf("\n");
?? for(long i=StartRow;i?? {
??
?? for(long j=StartCol;j?? {
??
?? //读取单元格文本
?? iCell.AttachDispatch(range.GetItem (COleVariant(i),COleVariant(j)).pdispVal );
?? vResult =iCell.GetText();
?? cstr=vResult.bstrVal;
??
?? //写单元格文本
?? ads_printf("%s ",(LPTSTR)cstr);
??
?? }
?? ads_printf("\n");
?? }
??
??
?? //释放Dispatch
?? iCell.ReleaseDispatch ();
?? range.ReleaseDispatch ();
?? sheet.ReleaseDispatch ();
?? sheets.ReleaseDispatch ();
?? book.ReleaseDispatch ();
?? books.ReleaseDispatch ();
?? app.ReleaseDispatch ();
??
?? return RTNORM;
??
??}
??
?? 是不是很简单,如果要输出到Excel的话,只要稍加修改就OK了,输出的关键函数就是:
?? iCell.SetItem(COleVariant(i),COleVariant(j),COleVariant(cstr)); |
|