|
在实际的工作中,我们经常要对一些表格数据进行处理,如果先把这些表格数据通过Excel处理,再导入到AutoCAD,/ `& k3 H, Z' u7 x6 e% O y
那绝对会起到事半功倍的效果。随着Automation编程技术的出现,我们可以很方便地实现这一点了,下面是个
3 I) t" S# m* ~2 ^ ObjectARX的例子,其功能是动态关联Excel,然后读取其数据,并将这些数据打印在文本域中。( O5 }' n0 | t! A) _+ P1 o" t# U
//动态从Excel读取数据. v) q2 A I2 j8 E8 U' ?6 v/ `
int DynamicReadFromExcel()
# Y2 a3 p2 D' M% X) Q {
1 I0 l2 o. J9 p$ f- I% q8 e1 p% t6 e //常用变量定义
( K1 i7 W' B; R, d0 F7 R) T1 v% A8 A _Application app;
0 d& w) p O$ ]* _ F* m2 Z0 q$ d Workbooks books;# A; B; y+ ^9 U0 g) b7 r
_Workbook book;1 ^. Y0 n8 s; C2 J0 F r
Worksheets sheets;0 u+ e+ [$ t8 j' y0 w7 g
_Worksheet sheet;
2 q' r: P' C. ?+ g0 Y& ~3 b1 D Range range;
5 f& {% F$ h1 M' m. u Range iCell;
: Y" r5 B% B- ~+ W. w! | LPDISPATCH lpDisp;
/ y1 d* U, p, F; D1 P( }/ d0 ]* K COleVariant
! Q" {: ^0 M1 m& j' r7 G: s& N( ~ covTrue((short)TRUE),! ^7 a. K/ [. d" D
covFalse((short)FALSE),
/ M3 \ a1 _& K* s! w covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);1 g$ {7 w* X& o( j7 R6 U# e; D
COleVariant vResult;8 O7 `8 N) l# t8 A6 S
//采用MFC方式初始化COM库,程序结束时COM库会自动释放2 n# q8 E% p% I/ I! H
if(!AfxOleInit())
, E4 p, s( U* S% }3 U' p {
# C: }6 b2 h6 U6 D& @ MessageBox(NULL,"初始化COM支持库失败!\n无法控制Excel!", \
6 B: @. A+ B4 T, O "TrueTable",MB_IConERROR | MB_OK);3 a" A& X2 n6 s3 o2 o. `# B
return RTERROR;. `6 O0 ?2 F/ a% q. E
}
, \ ^2 }" u7 \; }" r$ X //关联已经运行的Excel实例
- G0 J; S, h# }6 q, @2 T CLSID clsid;; k0 d1 {3 G: u1 k
CLSIDFromProgID(L"Excel.Application", &clsid);1 l6 G0 K# l9 s+ G5 c
IUnknown *pUnk = NULL;
/ t% g$ x( o4 R' t! `" Y- `1 D IDispatch *pRunDisp = NULL;
7 w& y9 k$ Q q* I! } for(long i=1;i<=5;i++) //做5次尝试
' Z9 K2 S% z$ r2 p: q% T. l( w2 T {( }' D+ K) I6 y, v2 a* ]
HRESULT hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);
. G. ]( k! \+ w if(SUCCEEDED(hr))& ^( l' H% l: t: Z5 U; m! E" j
{% T* l4 c3 J* f( X
hr = pUnk->QueryInterface(IID_IDispatch, (void **)&pRunDisp);
% |7 n# F) N: n' y& @! e% B break;/ z5 f, ]- I0 D' \: n
}) Q+ ]/ o0 b9 u
::Sleep(10); g1 n: h* ^0 W
}# m( o: F% Q3 S9 U. {
if (!pRunDisp)
+ |$ P" r5 g! e w {* H% ?" H5 `8 ]5 R7 J9 V
::MessageBox(NULL, "没有发现Excel!", "TrueTable", MB_ICONHAND);& b6 ]1 U: \1 H+ ~# b: j# u
return RTERROR;
3 k; t# F. c* @& ]: ?) d: E+ C }* e6 M) e( T" d3 \
if (pUnk) pUnk->Release();
3 Z" M, z y) Y/ y' B/ N5 j- l, { //关联Excel& t. b& R" T3 H' D
app.AttachDispatch (pRunDisp);
5 T" o3 p' A: ]9 K/ V/ |7 T0 p$ ~ //得到当前活跃sheet8 N8 L; z5 h' E! \0 X r9 [
//如果有单元格正处于编辑状态中,此操作不能返回,会一直等待2 M9 d& h* m# W6 g5 u) o; v
lpDisp=app.GetActiveSheet();% R9 }# o8 m7 j% u' m
if(lpDisp==NULL)
& |% S6 [( x4 `! i* A3 S {
2 l4 m, X4 b: P6 k* S% `' C) y; | MessageBox(NULL, "没有发现有效的表格!", \0 V6 w7 M* w7 H. ^# ~
"TrueTable",MB_IConERROR | MB_OK);4 ~: |: t2 p) v- V& C
app.ReleaseDispatch ();( G. e* t& m- S* ?2 o5 p3 O
return RTERROR;' t0 M% A% \! d4 @4 S5 Z
}8 ]5 r' m1 _1 d6 J
sheet.AttachDispatch(lpDisp);6 C. n6 f* t5 @: [0 D4 g7 t7 ^4 O
//已经使用的行数:
4 Y' R! Z* k! i9 y4 w9 b# ` long row_num;. ^5 ]- Q" V' g2 N" _6 }
range.AttachDispatch(sheet.GetUsedRange());
: P. ]9 f) X2 l z5 z% _ range.AttachDispatch(range.GetRows());
0 h2 {+ k+ R, V/ R row_num=range.GetCount();
3 E3 a; z6 S, {! \0 @" r5 L& d/ i //已经使用的列数:
" {8 U* t. h. A/ p% w long col_num;# h4 I& O) N3 [' i+ K" C
range.AttachDispatch(sheet.GetUsedRange());
' k; d: X0 [ x9 K range.AttachDispatch(range.GetColumns());+ F4 ^+ @) q4 z# P
col_num=range.GetCount();5 g3 V/ T/ q8 [5 a8 K3 w
//已经使用区域的起始行、列:
7 ~5 y, z/ U$ P range.AttachDispatch(sheet.GetUsedRange());
1 s; p' n/ ~; A) a$ W long StartRow=range.GetRow(); //起始行
8 [. y4 V+ h! D- g8 e3 J6 |- i long StartCol=range.GetColumn(); //起始列0 I7 Q1 b* R6 o V$ G/ q. b; _, V) M
//读取sheet名
2 \6 L( E/ n7 r4 b. U: `; d/ E7 Y1 h CString SheetName=sheet.GetName();
5 x- r6 L) g5 b, K* N$ c9 V //ads_printf("\n%s",SheetName);
8 }) l$ Q' ^% c0 D! N if(col_num<2 && row_num<2) //此sheet为空) r: Z6 R, y1 g; V8 v5 w! p5 s: y. W
{
9 Q# Z3 _2 M, W4 }3 ~5 N+ {* r MessageBox(NULL,"\n当前表格没有数据!", \
6 e" ^9 G! P* j2 [4 D% |9 D "TrueTable",MB_IConERROR | MB_OK);) @; _9 w2 E+ m( u+ W: N
app.ReleaseDispatch ();& V! Y% K3 ^$ ] v6 @# ~
return RTERROR;
- i; _. g3 z* T: W }
7 f, n% b# G3 R" d else4 F3 x$ G& o) x0 f
{
+ K& _% Z* O) s* x% [$ ]0 A' G ads_printf("\n表格%s共%d行,%d列",SheetName,row_num,col_num);
' ^4 C; C3 ? w2 Q; J }4 I3 Q$ c/ ~5 R2 k# m
//得到全部Cells,此时,range是cells的集合6 _9 n1 U* K4 ?) X% R* I$ h
range.AttachDispatch(sheet.GetCells());
6 v3 [7 y& D8 ]! Q* z //读写数据了
, g) s# @+ Y7 x0 a/ L) g CString cstr;, m' {; y0 C! H% h9 |% A r7 ^
ads_printf("\n");
8 n8 a4 \2 z+ { for(long i=StartRow;i<STARTROW+ROW_NUM;I++) {
3 G/ c: Z- W; O for(long j=StartCol;j<STARTCOL+COL_NUM;J++) {
3 ]+ F. T* n2 f, `4 u9 ~ //读取单元格文本
2 R) O2 z+ r* |; [* N; D( k8 t- s$ t1 @ iCell.AttachDispatch(range.GetItem (COleVariant(i),COleVariant(j)).pdispVal );" ?: T6 Z: H0 o: M2 H1 r
vResult =iCell.GetText();
c% }; c! C2 i7 ^/ e cstr=vResult.bstrVal;
2 e) \% M' u8 i3 X: ?9 h //写单元格文本: s7 t% X1 x' |5 u
ads_printf("%s ",(LPTSTR)cstr);2 h$ Y9 W8 V$ i1 b/ I! d* w
}3 _0 A6 ?) n# M0 Q
ads_printf("\n");/ b; _4 l) H3 m! B2 j) I3 d
}8 V/ x f2 ^. |0 A: H/ H/ i
//释放Dispatch5 l* p3 s V5 h/ B
iCell.ReleaseDispatch ();6 ?4 U! A9 ^3 |' c. ^, ]% o8 O1 W
range.ReleaseDispatch ();) K8 I3 C; T# y# q3 u% ~# v' s
sheet.ReleaseDispatch ();8 d% G2 Y* [% p3 n
sheets.ReleaseDispatch ();
! _1 W. i# F( u0 A: ] book.ReleaseDispatch ();
# v1 i( J. F' O books.ReleaseDispatch ();
% j8 i% z9 L2 M; B2 J app.ReleaseDispatch ();
! X- N4 z* ` L) m5 r return RTNORM;
: }( t, |3 F* _' `( L }
/ m) O/ y1 L J 如果要输出到Excel的话,关键函数就是:& q2 Z. ]6 Q' @: Z% Y t
iCell.SetItem(COleVariant(i),COleVariant(j),COleVariant(cstr)); |
|