|
在实际的工作中,我们经常要对一些表格数据进行处理,如果先把这些表格数据通过Excel处理,再导入到AutoCAD,, [# j( d1 M" i3 J
那绝对会起到事半功倍的效果。随着Automation编程技术的出现,我们可以很方便地实现这一点了,下面是个
- }5 m M+ S" m' K) {4 t0 s ObjectARX的例子,其功能是动态关联Excel,然后读取其数据,并将这些数据打印在文本域中。
) V& k2 j; }) \* U4 n- I" C //动态从Excel读取数据% ]/ U% h& L* E; E! n
int DynamicReadFromExcel()
; ]' y2 B& N1 }; I {, a7 z4 @( I3 @3 C6 C. Q
//常用变量定义$ z+ Z8 M- m5 `; k; b9 v8 O
_Application app;4 K! Q- e# O9 t6 F
Workbooks books;
; u# f+ l$ u% w$ j. F, | _Workbook book;
) N x/ @9 A `2 m* j4 C Worksheets sheets;7 n t1 R' Q6 ]% V% S" Y* m% _2 ~
_Worksheet sheet;
& p" \# v6 x2 s+ ?/ {( M, s9 V Range range;
" h8 D8 `$ [( `6 O Range iCell;
E0 s9 n+ Z( ] LPDISPATCH lpDisp;3 t" r, b x" D: t0 c4 e5 T
COleVariant
2 |5 O9 X7 _6 j$ f D; |7 F ?1 \ covTrue((short)TRUE),$ o2 H) D1 O) G8 K' N, B! Y( N
covFalse((short)FALSE),
$ f' p* |$ _; l* v covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);' Q- }% I4 G6 ^+ I# ]6 l
COleVariant vResult;' x8 Z* z% w; }2 p) `6 P
//采用MFC方式初始化COM库,程序结束时COM库会自动释放
" ^$ l, J( x) {# U! s7 J% M& \ if(!AfxOleInit())4 W8 O: i% n% o2 N) t
{
# c, C& h5 z5 J/ L MessageBox(NULL,"初始化COM支持库失败!\n无法控制Excel!", \
3 p2 f0 q7 J( v5 Q/ T, U "TrueTable",MB_IConERROR | MB_OK);
+ K u7 ^# f3 s+ f return RTERROR;
) x+ |$ {4 l8 Z/ W }, E3 J) [; H* d& u# @
//关联已经运行的Excel实例
. s! o, {. C" ~ CLSID clsid;& y7 o1 p, o/ v' G J# t4 b, M& [
CLSIDFromProgID(L"Excel.Application", &clsid);& F: Q* c/ c5 P* ?
IUnknown *pUnk = NULL;
G: h( Y8 w6 _5 d: L IDispatch *pRunDisp = NULL;9 |' A V2 n% N; J' E& [; L
for(long i=1;i<=5;i++) //做5次尝试
2 K8 ~& E& }9 g. Y2 V3 a {0 p$ u) n4 t# a5 ^
HRESULT hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);
6 z4 H! W. W! ?0 c9 `" @& x+ s' K if(SUCCEEDED(hr))" H7 x3 d2 _$ V- o8 B# L
{# C! Q" k3 W! G/ k7 l2 f
hr = pUnk->QueryInterface(IID_IDispatch, (void **)&pRunDisp);9 d: h) S$ Y+ U& _7 @
break;
5 s: S( j/ _& a8 u }
. Y; o T' L, L ::Sleep(10);( Y2 M2 v8 _- F" h0 ?: l
}! e$ C, X- r7 t' b/ H' b3 o
if (!pRunDisp). S Y1 Z' V* v7 o* i) o
{
# j6 P+ q# F$ B! l8 a9 h ::MessageBox(NULL, "没有发现Excel!", "TrueTable", MB_ICONHAND);
`5 @. ` r) k! T& q return RTERROR;
7 Q" i. q9 e+ T5 L }& D$ t) n! W3 @' }% Y
if (pUnk) pUnk->Release();# M/ L5 z m. I/ B' G5 u6 \# ^* }
//关联Excel
" x% M) ?! {% F! V app.AttachDispatch (pRunDisp);
0 J* u5 |* ?6 o! P //得到当前活跃sheet- \/ X" q% x* U
//如果有单元格正处于编辑状态中,此操作不能返回,会一直等待
1 v2 u1 P, g' K$ w. W lpDisp=app.GetActiveSheet();- C% u! W0 S" j5 |
if(lpDisp==NULL)
- N8 S4 V" O5 c+ ?8 p( ?5 L6 P {
! w( l" f6 D) \# }1 @ MessageBox(NULL, "没有发现有效的表格!", \
+ ^, @( y% g5 G+ s2 U2 [% d% }, j "TrueTable",MB_IConERROR | MB_OK);
" f9 o) k! @( t; t app.ReleaseDispatch ();
7 K$ _* W1 P% R0 X) |) X8 m1 r- [ return RTERROR;" v( @4 ~6 d, O w' s& s
}* D! X: m. X; s+ a0 @# t7 ~8 F
sheet.AttachDispatch(lpDisp);5 w/ A1 ^3 h+ _0 j: h
//已经使用的行数:
1 |* a$ X$ a a3 h0 n) h) p long row_num;
, J5 ?9 N- q- `: k6 M& q; F; q range.AttachDispatch(sheet.GetUsedRange());$ W/ b) |6 m0 j% l K3 `
range.AttachDispatch(range.GetRows());
( @) P9 E9 e, U: K0 P row_num=range.GetCount();( t0 ~% c* V3 P! v% I9 Y0 e
//已经使用的列数:
/ G5 d: U. @ V$ `7 Q: {+ L long col_num;8 g" {, e) [8 i, U* i; U( u' p4 {; x
range.AttachDispatch(sheet.GetUsedRange());. w7 c; R8 s/ W$ X
range.AttachDispatch(range.GetColumns());0 s9 X' {: t) H! w2 S
col_num=range.GetCount();! Z6 k+ n3 I7 b" N2 U( r# s
//已经使用区域的起始行、列:
* H& p# i; {# s0 d6 f- j( P4 o5 E4 b range.AttachDispatch(sheet.GetUsedRange());6 X$ X3 p) N1 \3 h7 _3 v3 Q
long StartRow=range.GetRow(); //起始行
4 m: j7 w3 }: } long StartCol=range.GetColumn(); //起始列
# Z! t, @7 u. a! Z! F; }0 I& Z //读取sheet名
1 o. D0 }0 ?; e/ L" \; o CString SheetName=sheet.GetName(); e& W& X+ H1 Y% N) i3 s
//ads_printf("\n%s",SheetName);' A2 }6 F& b$ \$ G. k; B/ o- ~- `
if(col_num<2 && row_num<2) //此sheet为空
! | q4 H# a, f+ O0 Z {
, }. S' W( E* w; B) ` MessageBox(NULL,"\n当前表格没有数据!", \
& Z9 j4 _5 c( n; w& d "TrueTable",MB_IConERROR | MB_OK);( o9 q( ?3 ~1 a) F5 c; U
app.ReleaseDispatch ();7 r9 J1 R" [: z6 \1 g
return RTERROR;# y) |+ u7 F0 ~- t% ?0 L
}
* P; k- ^: |; @/ S7 e else
# E( @) ]* d$ t# h) U/ B1 p {
* D* z8 y! d4 V& ] ads_printf("\n表格%s共%d行,%d列",SheetName,row_num,col_num);
- C" k# ~9 V3 w5 m }8 @) I( X& \$ G. a8 ~( B
//得到全部Cells,此时,range是cells的集合8 D% o' h J5 d) ]3 X- c
range.AttachDispatch(sheet.GetCells());: O+ P B3 a, \
//读写数据了$ Q1 q5 c9 ]2 ~6 C
CString cstr;" B7 o, z. I' m n: V1 C
ads_printf("\n");4 \" j" P4 z$ g# W
for(long i=StartRow;i<STARTROW+ROW_NUM;I++) {
2 ~) c* p9 a: _+ x# D! W for(long j=StartCol;j<STARTCOL+COL_NUM;J++) {
7 y3 C# m6 z5 |' M9 E! k+ t //读取单元格文本; J) X4 u$ E9 ?3 p/ L3 z$ |
iCell.AttachDispatch(range.GetItem (COleVariant(i),COleVariant(j)).pdispVal );, x7 ^& h% W, v( f$ E
vResult =iCell.GetText();, v2 F. @" s3 H# ]
cstr=vResult.bstrVal;6 d, y& w9 W4 [, ]
//写单元格文本/ F# R0 ` Q! Y8 b6 P
ads_printf("%s ",(LPTSTR)cstr);9 x/ s: s. N$ D. Z g
}
" h4 { l8 M1 t; a2 T ads_printf("\n");+ U) F3 b b6 b) r# B9 k- Y
}
/ n: {+ e& ^( i //释放Dispatch
" F+ E5 A0 r6 s; x5 b; p% U& J iCell.ReleaseDispatch ();
9 L% B- q$ A: |% C9 O/ g range.ReleaseDispatch ();
* A v3 z9 s; }9 D) ]% P1 a; ?- S& Q. ] sheet.ReleaseDispatch ();
, z# G' |' R ]/ F3 c1 n9 p sheets.ReleaseDispatch ();' `3 N3 k# U9 z' `
book.ReleaseDispatch ();2 }! F! ^5 ^, e
books.ReleaseDispatch ();
5 o* M! g5 R: G) G app.ReleaseDispatch ();$ ]/ D, t- N' b5 J) y6 M
return RTNORM;
! {0 `) h8 i0 _- @3 N( A }% ]% U s5 |0 k2 P: k
如果要输出到Excel的话,关键函数就是:& }1 H* \) \8 t* x
iCell.SetItem(COleVariant(i),COleVariant(j),COleVariant(cstr)); |
|