|
在实际的工作中,我们经常要对一些表格数据进行处理,如果先把这些表格数据通过Excel处理,再导入到AutoCAD,. D. e) W3 \, _9 W
那绝对会起到事半功倍的效果。随着Automation编程技术的出现,我们可以很方便地实现这一点了,下面是个
7 b' H, @* \- T' M+ q ObjectARX的例子,其功能是动态关联Excel,然后读取其数据,并将这些数据打印在文本域中。; ~; E, S; S, h3 i* G8 V! i2 O
//动态从Excel读取数据
, ^7 V& U2 W/ K int DynamicReadFromExcel()
% M) U( c6 Z5 s1 X" ~ E) m0 X {" T' `6 X4 X: { t0 C- f4 z: d
//常用变量定义- U3 e* t+ y0 r/ u1 w! E5 e1 I
_Application app;9 t& J0 D. I0 ]6 `0 d' U7 d8 r: I
Workbooks books;
" M) d$ m* s# x. v _Workbook book;
; l$ g! p5 a4 R- T# L Worksheets sheets;
% y6 f0 q: C, K* |+ S9 j) @ _Worksheet sheet;
1 l- ?% |7 A8 |6 h9 t Range range;- A( b% H) ~' L- K; q b( M
Range iCell;4 e( S9 d1 j* L! d2 J! H
LPDISPATCH lpDisp;
/ K( n' r7 O- o6 T COleVariant# e/ a3 F9 p. e9 R' Z1 D
covTrue((short)TRUE),/ f( ~ u4 G7 p( h- F0 |
covFalse((short)FALSE),% A- j0 B. q5 Q* p" x
covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
) [7 v0 C: {6 A4 W+ B$ F) y COleVariant vResult;
3 w4 A B1 Q5 I7 Z8 K7 K //采用MFC方式初始化COM库,程序结束时COM库会自动释放: R2 ~5 h# L) f0 B
if(!AfxOleInit())
. M( }* j# X0 _! f6 v" m' U {1 Y, q! a4 h# X
MessageBox(NULL,"初始化COM支持库失败!\n无法控制Excel!", \$ W0 Y) m9 R+ {/ m: B$ P+ z
"TrueTable",MB_IConERROR | MB_OK);
; S9 X6 G$ }8 M( [' c% { return RTERROR;* k# P ^& ? r% X+ Y+ R
}
9 Y& {2 B; e2 s //关联已经运行的Excel实例% R1 k4 f8 k% E3 [/ B
CLSID clsid;- T. m& V" Y* ?% u" d8 J
CLSIDFromProgID(L"Excel.Application", &clsid);
! U& p4 t! m6 v- |) \: H( g3 f! L IUnknown *pUnk = NULL;
# Y$ Z/ z+ E: e9 O0 U2 F( v: s& \- n IDispatch *pRunDisp = NULL;' a& L, v% V+ M! Y8 ^" U* B
for(long i=1;i<=5;i++) //做5次尝试
, O% O& ~! m: T+ c& ~( ?- T {4 l* F t3 T* X8 n* _$ u" T
HRESULT hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);
/ r7 R/ x+ I N/ y2 G5 t c. T( N if(SUCCEEDED(hr))
3 r% t" H8 B* }) g3 Y+ D3 k {8 Q3 t$ q! F6 w' S8 p$ N) M
hr = pUnk->QueryInterface(IID_IDispatch, (void **)&pRunDisp);
8 m. p% v$ ?& j break;
2 Z: X9 `4 v3 r5 c4 s" K9 a }
2 o* O+ B( C5 t/ H! U) }( U ::Sleep(10);" e6 I. F, t( L K# C0 M
}
2 M2 a( D7 a; W6 g0 M$ l+ v! }8 F* } if (!pRunDisp)
$ o7 d5 }0 s- N9 S1 ?( Q1 M {* b$ U# G9 p0 t8 S- J9 ^/ G6 F
::MessageBox(NULL, "没有发现Excel!", "TrueTable", MB_ICONHAND);. _+ K! }1 g1 M/ P$ j" Y* U
return RTERROR;. p1 J" V4 Z# O8 t/ [. P8 ]0 ^
}! h6 W% U( l* C6 ^1 W" f% o- u8 u
if (pUnk) pUnk->Release();. d# b' U* K6 P+ ~
//关联Excel
! J% w! y. Q2 T3 n. N5 O( K5 `- B app.AttachDispatch (pRunDisp);
" Y( B1 t x. M& ~+ F //得到当前活跃sheet! W2 F! r' b# P5 [+ d7 t
//如果有单元格正处于编辑状态中,此操作不能返回,会一直等待( U( t' M9 ~3 l* j7 H! L
lpDisp=app.GetActiveSheet();
) ?7 L# n( W2 R& q- S if(lpDisp==NULL)2 v0 C+ m" T( o) B$ q2 U. D7 n
{
" a' m' ~- g p' a MessageBox(NULL, "没有发现有效的表格!", \
6 L1 C; r; z7 _8 O4 Y2 Y o0 `5 a: Z) D "TrueTable",MB_IConERROR | MB_OK);+ s8 z" f; A @- J* y# m9 @& ]
app.ReleaseDispatch ();
: b, N7 P4 \4 e return RTERROR;0 P# Z- ?$ B' c, m) ?' k. D
}
: @/ T( y- D3 q( _( Z5 Z, Q sheet.AttachDispatch(lpDisp); f. K* N* H }3 V" E. X
//已经使用的行数:
" d4 N7 p% a+ B long row_num;
; |5 U1 @" Z- h range.AttachDispatch(sheet.GetUsedRange());
: l! H9 M" W! _& l, I range.AttachDispatch(range.GetRows());3 X* m" l' O1 f7 u2 L: D7 A- i
row_num=range.GetCount();4 P- j: e- u' h$ [/ A: m; y/ ^( Z
//已经使用的列数:5 k2 ?) ?8 Q! ?% |
long col_num;# j: m+ X0 j( h) V# T
range.AttachDispatch(sheet.GetUsedRange());
% |# l4 n/ x0 ?( S" `$ ] range.AttachDispatch(range.GetColumns());) S' A0 I0 A4 R0 t( t
col_num=range.GetCount();
1 b5 u/ }9 o) J; C' `, R* \ //已经使用区域的起始行、列:6 G* ?# |9 q9 a/ O6 F
range.AttachDispatch(sheet.GetUsedRange());) |# p# ?0 O1 J# ~: I: k, @
long StartRow=range.GetRow(); //起始行
1 Y- Z j& t9 v& z3 F long StartCol=range.GetColumn(); //起始列
0 E1 D6 {" E* ^+ f0 F! o9 q //读取sheet名* a$ `. ~$ b6 ^1 ~
CString SheetName=sheet.GetName();
8 Q" n* e2 D M" {6 l6 p. H0 j //ads_printf("\n%s",SheetName);5 v4 s7 i% P. W5 z( g
if(col_num<2 && row_num<2) //此sheet为空4 _5 U! \/ V8 `2 U+ x2 N- m" ~
{
F4 L5 A8 @; g MessageBox(NULL,"\n当前表格没有数据!", \
2 F1 {- z; y: E) d$ B4 [ "TrueTable",MB_IConERROR | MB_OK);
, D+ i8 _. [' k% F6 _8 e app.ReleaseDispatch ();0 b/ v* L! m( [) \6 K4 h
return RTERROR;2 n$ O; h8 y3 I- D9 _$ |1 p
}
) I' e& q, [% h9 i+ U! _8 e else# ~* i6 }* J! B9 v
{0 a" ^( Q$ a: C' t6 r
ads_printf("\n表格%s共%d行,%d列",SheetName,row_num,col_num);/ F: H# Z0 ~ U: o' T
}$ E4 A* t* D: O
//得到全部Cells,此时,range是cells的集合
( B* \" l' X) I! a6 ~& S/ s' P range.AttachDispatch(sheet.GetCells());
% S& ^9 z& K- |" S: S //读写数据了
; d: Z, a' X1 Q# T& H1 w CString cstr;
/ _7 r0 H! w* j! W ads_printf("\n");
+ i( V& _& {+ O5 E* z, |$ W7 F for(long i=StartRow;i<STARTROW+ROW_NUM;I++) {
9 [7 l% L1 T7 W* [7 w; S for(long j=StartCol;j<STARTCOL+COL_NUM;J++) {
% b( u+ t5 e$ l$ t. x //读取单元格文本# o+ |$ ?& c; z. G% j2 ~
iCell.AttachDispatch(range.GetItem (COleVariant(i),COleVariant(j)).pdispVal );
' `4 }6 U: u% O5 R. |3 O8 ? vResult =iCell.GetText();) J- ` H, _0 Y/ I6 A
cstr=vResult.bstrVal;1 @* }$ S6 R' I% S
//写单元格文本% j I( g; J) P
ads_printf("%s ",(LPTSTR)cstr);0 X: T5 \8 A' t. ]# O/ B
}6 ~! k/ D" J0 e4 e
ads_printf("\n");- f: f$ ~+ b! h, C6 S
}
! L X n" b1 a: U" S9 ^ //释放Dispatch
1 Q' y3 ~$ _( @* t. J m5 F: U$ F iCell.ReleaseDispatch ();& Y P; t& {) w. D) w, [9 D
range.ReleaseDispatch ();
) l8 R9 x& [, u sheet.ReleaseDispatch ();
/ A4 \2 c+ z, [* k; T7 s8 m$ a# Z sheets.ReleaseDispatch ();' E0 C9 _7 n0 {: N; { u U( u4 O4 v
book.ReleaseDispatch ();
5 C5 y( R, e- j$ E books.ReleaseDispatch ();, U; D/ n7 J9 H3 v. T! E
app.ReleaseDispatch ();
; a+ L: s' Q3 u: }0 y4 ?7 y return RTNORM;
U- C! z# Q/ Z; ?6 R' E! | }6 z* p/ K+ e' ? F
如果要输出到Excel的话,关键函数就是:" ?/ w! P# c2 X0 ]; _
iCell.SetItem(COleVariant(i),COleVariant(j),COleVariant(cstr)); |
|