|
在实际的工作中,我们经常要对一些表格数据进行处理,如果先把这些表格数据通过Excel处理,再导入到AutoCAD,3 U. F1 d( e# A B( s: z7 t8 U
那绝对会起到事半功倍的效果。随着Automation编程技术的出现,我们可以很方便地实现这一点了,下面是个! g" A1 T8 ]: l
ObjectARX的例子,其功能是动态关联Excel,然后读取其数据,并将这些数据打印在文本域中。
7 B1 w; x# x4 i" L0 Y //动态从Excel读取数据" b2 N$ ]0 ^% v8 c& F# s/ U
int DynamicReadFromExcel()
% G0 }3 }& @# i! N {
6 s$ P+ O( e$ J0 W/ p% c //常用变量定义
/ m3 w* i0 [/ e4 E _Application app;
! J8 E) B+ O( S Workbooks books;" X: z- K2 D2 P! {$ X) h- @
_Workbook book;
F$ ?7 o' A. P, Z Worksheets sheets;
! n, F8 p5 Y M# ^ _Worksheet sheet;
7 \: D; q) i* n) P, e5 a X, f! h Range range;
5 p( a& J9 f: U2 z$ V& e# F- X5 h1 C Range iCell;- C/ C; U. j2 A m* U- K$ w0 j1 \; y
LPDISPATCH lpDisp;
& j' p" I1 E' S+ s! s. c7 M COleVariant
1 d8 _3 h0 @, v# H$ Q. q1 `/ h covTrue((short)TRUE)," S7 ]$ c0 U* y9 p$ ? R
covFalse((short)FALSE),
7 q' Z* l6 z+ x! s. e7 d I$ k covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);& J( p( {4 A( h/ h
COleVariant vResult;3 z: C( @ l( B" D! Z( g. N
//采用MFC方式初始化COM库,程序结束时COM库会自动释放
' z9 `6 n. @ c A6 }2 k% |# d) J if(!AfxOleInit())
# z) ^( j$ Z' V# c {
* K' c8 _: R! ]% O MessageBox(NULL,"初始化COM支持库失败!\n无法控制Excel!", \
7 G# Q9 @2 r$ @8 o3 G" i* w' L1 W& H "TrueTable",MB_IConERROR | MB_OK);
, ^! J; O9 ~ ^6 S$ c1 J) R return RTERROR;- ~6 j6 }# B6 C/ X# h+ q1 b) p, g
}; X7 N3 T F, Y* b7 m4 \; J. A
//关联已经运行的Excel实例 _' e) M# S5 N! K" D
CLSID clsid;
1 |& J% _1 [# R( j CLSIDFromProgID(L"Excel.Application", &clsid);6 M; E* ?/ @7 M/ }, g
IUnknown *pUnk = NULL;( G& q( F& r# s
IDispatch *pRunDisp = NULL;
7 E0 T) \1 i" T7 |; W for(long i=1;i<=5;i++) //做5次尝试
& B j' s# h6 Y {/ K1 C- q; I5 K% m( L& O
HRESULT hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);6 T) H; ^3 ?! @7 |+ r
if(SUCCEEDED(hr)), ?7 W$ C0 h2 |6 v9 ]5 X3 }4 M6 F5 K
{# n7 l; e6 g2 s+ Y' E+ S8 `) f
hr = pUnk->QueryInterface(IID_IDispatch, (void **)&pRunDisp);
5 e; Z4 l! k7 k8 d5 k& A break;
; t9 D% f! R5 C0 y! n) }! y, H" ]( T }4 @0 i; L7 c" n2 b; N
::Sleep(10);
+ Z! O& z9 y/ B% F }
y: ~+ m4 f% O; p7 e; [* I) W6 n/ V if (!pRunDisp) |+ d' W4 N( r: U0 Y
{. {5 k) B, g: i. B/ b3 A. o" ~
::MessageBox(NULL, "没有发现Excel!", "TrueTable", MB_ICONHAND);3 \$ X" c' x5 p9 i
return RTERROR;
/ o, X/ c2 J6 V9 ` }
+ K5 `; a* I5 N9 C if (pUnk) pUnk->Release();
# L6 \# [1 g: S5 @% a7 {- Y8 V //关联Excel9 v2 ^3 W1 V& @1 @
app.AttachDispatch (pRunDisp);
3 N- [8 r2 ?- b7 v7 M6 a+ i //得到当前活跃sheet' k Q9 n; u. @# M
//如果有单元格正处于编辑状态中,此操作不能返回,会一直等待
2 k* [8 S. j( {1 C; l8 F/ x5 E lpDisp=app.GetActiveSheet();/ f' u; d2 X' j9 ~& A
if(lpDisp==NULL)
. ~% r& m5 u! A5 U {
: {) t# @! g. w* G MessageBox(NULL, "没有发现有效的表格!", \
, @8 Y- B$ E7 _1 V" W# Y6 l "TrueTable",MB_IConERROR | MB_OK);; E* i9 S0 Z0 ]2 k: Z0 g' {1 v' l
app.ReleaseDispatch ();$ E$ Z6 d$ _3 S5 |2 q1 Z
return RTERROR;0 X2 q( v; j+ `9 i2 Q3 H( N& E: U H
}
- S2 N) l/ |+ D7 O sheet.AttachDispatch(lpDisp);% v, n% J' F' |; j, P8 U5 q+ f
//已经使用的行数:
$ h( [1 E m2 S long row_num;
1 t+ s# k1 D! k$ e" r0 q range.AttachDispatch(sheet.GetUsedRange());# d- ~8 _, Y# B; n6 h
range.AttachDispatch(range.GetRows());
' t E7 G5 z7 B. u# e0 R row_num=range.GetCount();. _$ K9 J) |3 z
//已经使用的列数:
5 q; n' I# J% A+ h long col_num;+ a4 G9 K6 W- R1 x+ a8 x1 q# @
range.AttachDispatch(sheet.GetUsedRange());
$ V1 y! Q9 I! S0 ]( \ range.AttachDispatch(range.GetColumns());
4 e+ K; P5 e0 b/ J col_num=range.GetCount();; f! w6 v0 {% ?6 a; t: Q5 }
//已经使用区域的起始行、列:
/ I9 r- V' g; z- }1 _; n range.AttachDispatch(sheet.GetUsedRange());
: v9 \* ~9 }( ]2 }4 d long StartRow=range.GetRow(); //起始行2 B" x7 f% ~+ H* ]+ P5 q Z
long StartCol=range.GetColumn(); //起始列
" ^6 p; R2 |$ _5 _- C4 j* L/ E //读取sheet名
/ v; M9 q% C( F2 O CString SheetName=sheet.GetName(); I* O i5 o4 c0 p
//ads_printf("\n%s",SheetName);
0 v# p3 s$ n$ g, H if(col_num<2 && row_num<2) //此sheet为空
) W# m2 X5 j! Q {
' Q: K0 y8 r# h h6 }$ x% F& K MessageBox(NULL,"\n当前表格没有数据!", \1 M( a' O) z2 [2 `! s" }
"TrueTable",MB_IConERROR | MB_OK);
j8 C: x9 M3 J0 }& v app.ReleaseDispatch ();
# c6 t$ G' `" c- }1 F return RTERROR;
' d% G+ z' j/ I( _ }
' t' a0 P$ p* \8 H8 I else
. L, \' l( s7 {: o( l {. Y8 L( b# t. t2 l
ads_printf("\n表格%s共%d行,%d列",SheetName,row_num,col_num);9 F# o" I5 C) S5 ^% w
}
; C5 E8 q4 q' e$ Y( G- M5 @ //得到全部Cells,此时,range是cells的集合# B1 X7 h! r) y; F5 h( C) ?; C
range.AttachDispatch(sheet.GetCells());
9 D; y% C" p# @8 v+ T- ~ //读写数据了
8 z! X0 {) o) Y* K7 I. j* v) w CString cstr;+ T1 U* r/ o9 W4 r% u% T
ads_printf("\n");
! P7 E+ z# p7 S9 Q F& }" L for(long i=StartRow;i<STARTROW+ROW_NUM;I++) {
& }' k* @; e6 ?, q for(long j=StartCol;j<STARTCOL+COL_NUM;J++) {: g; @# q" T; n/ D8 F) g
//读取单元格文本
9 T4 ~# |8 O: W' P# S8 X iCell.AttachDispatch(range.GetItem (COleVariant(i),COleVariant(j)).pdispVal );+ r5 M7 O( W; c: ^) p7 l
vResult =iCell.GetText();
8 |5 \+ c# e6 \9 H cstr=vResult.bstrVal;9 D& R/ m9 Y# J' H6 J
//写单元格文本
6 Q' n, y ^0 v* z. g ads_printf("%s ",(LPTSTR)cstr);, f1 D0 I" C8 }+ S9 A$ _
} \0 Z, y5 k- s% y/ l
ads_printf("\n");
! O6 l0 n: d8 |- X4 C7 Q4 a4 \& I } A, E0 N# y) Y* g- Y
//释放Dispatch Z( k- P' b8 j7 o
iCell.ReleaseDispatch ();' G6 p7 |5 @: j9 d1 O
range.ReleaseDispatch ();) g4 J5 W- [' Z1 z
sheet.ReleaseDispatch ();; d+ N7 t: ?, B
sheets.ReleaseDispatch ();
8 H6 x, ?+ H! D# U/ s# T book.ReleaseDispatch ();
5 I+ x+ H% o' N) j+ o books.ReleaseDispatch ();
% X t4 g# j. l- c9 I* [ app.ReleaseDispatch ();+ A1 _* l& R, K: J5 y2 b5 E O
return RTNORM;8 k5 q. g8 c5 @, }. {7 d0 }
}/ \3 J' ?' f% w
如果要输出到Excel的话,关键函数就是:
6 D4 `' q. T t# n. \ iCell.SetItem(COleVariant(i),COleVariant(j),COleVariant(cstr)); |
|