|
在实际的工作中,我们经常要对一些表格数据进行处理,如果先把这些表格数据通过Excel处理,再导入到AutoCAD,, u. K/ M3 y! ?$ b b$ ^
那绝对会起到事半功倍的效果。随着Automation编程技术的出现,我们可以很方便地实现这一点了,下面是个
/ Y/ ~: l Y3 W3 X ObjectARX的例子,其功能是动态关联Excel,然后读取其数据,并将这些数据打印在文本域中。. x; s6 K* L" L/ r
//动态从Excel读取数据3 B# v' Z* X( ~8 G& }
int DynamicReadFromExcel()
( h; U0 D" ]6 d8 u9 T+ N {
( a1 ~5 y1 { W1 u$ f! g //常用变量定义
3 H2 `) I3 N9 \% Z: C1 f. [7 c$ v _Application app;9 S, k# y. v( b2 S0 i4 x4 n: e
Workbooks books;
! O% I6 ]+ u# P2 K1 ~/ w _Workbook book;
8 }( l: ~) L! K( J( \6 d9 M Worksheets sheets;
) p' H3 q2 d2 C$ E7 I1 x4 Y _Worksheet sheet;% p- |+ J/ K/ S. Y8 t
Range range;
5 e6 X2 i. k, h7 q S6 _% j; I Range iCell;5 Q' C# C8 k6 [8 Z( a" k
LPDISPATCH lpDisp;
& I0 O* a! E' t1 U; t7 c COleVariant
9 \3 e6 L4 d1 e1 a' G1 G covTrue((short)TRUE),$ ^5 i1 J. `- y+ U K
covFalse((short)FALSE),
) Z1 \8 l3 Y" ?. e4 B- B covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);1 v. K" x, ]4 X' I4 L& S
COleVariant vResult;
) D7 L# \# T9 K& W; `4 j+ @/ V //采用MFC方式初始化COM库,程序结束时COM库会自动释放
4 G7 ]- A' k! M if(!AfxOleInit())# e! y$ M; V: \; R: N
{7 Q( h+ r0 u- H
MessageBox(NULL,"初始化COM支持库失败!\n无法控制Excel!", \: V' a \2 R8 K- n; ]% o! |
"TrueTable",MB_IConERROR | MB_OK);
# v3 y+ U, R: k. w return RTERROR;
# W4 K2 j! ~" r5 ^ }5 q' t/ i( P" ?# u
//关联已经运行的Excel实例
) I( H4 A, B+ F1 m# T) d CLSID clsid;. y5 O6 j/ c( p1 H: Q0 ?% y5 b# w
CLSIDFromProgID(L"Excel.Application", &clsid);+ R( N4 b$ Z5 _# n
IUnknown *pUnk = NULL;9 P1 g7 [2 T4 @6 P- P' s
IDispatch *pRunDisp = NULL;
# M8 {7 w( F5 } for(long i=1;i<=5;i++) //做5次尝试
1 u* C; g/ ^4 P" h& f- F {* Q; C, a: Y: U9 {6 h
HRESULT hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);7 m. @3 H- A- f7 I
if(SUCCEEDED(hr))) I l4 R6 }* c0 i; f, K
{1 {/ ^! _$ @1 H3 W
hr = pUnk->QueryInterface(IID_IDispatch, (void **)&pRunDisp);# q2 }7 I; l, { ]/ Z
break;( m8 @: P P- Z& ]% J, k5 g
}
2 q* {1 q$ B# Z/ l ::Sleep(10);# n$ g- T! k) ?' G) `* y- i0 T
}
& q b3 ^0 u! }8 s9 S8 O if (!pRunDisp); Q. X8 @) i% N' I9 c2 R' f$ ~
{
' k. Q9 z$ f7 u" ^9 q( q3 Z3 i ::MessageBox(NULL, "没有发现Excel!", "TrueTable", MB_ICONHAND);
7 }2 k9 s7 }+ ] return RTERROR;
3 X4 _+ q5 l/ \2 K' j% [ }& x) r' @9 C! h$ ?
if (pUnk) pUnk->Release();
4 t6 f9 f% Q* F; S0 k //关联Excel
, m" \: o0 h! \. Q: \ app.AttachDispatch (pRunDisp);
2 W+ l1 ? D9 D: e9 C //得到当前活跃sheet+ a% J; a$ i( y. y* Z. t
//如果有单元格正处于编辑状态中,此操作不能返回,会一直等待
0 F8 m z: @' O; {0 [9 ` lpDisp=app.GetActiveSheet();
# ?4 @( R4 Z' m2 P- O3 m! b if(lpDisp==NULL)
$ S* \; N, E& i, _: a" n {
' y4 y. n* _ w5 K5 e ?7 W MessageBox(NULL, "没有发现有效的表格!", \
) P6 t0 v% v$ R F- b7 u1 S% C "TrueTable",MB_IConERROR | MB_OK);
' j* x) N- U3 y' K6 L' h app.ReleaseDispatch ();
" m& G7 L' b, f, U' @ return RTERROR;6 i* H8 R6 u" B3 q/ m$ G
}
3 k0 T2 H" F- v5 I sheet.AttachDispatch(lpDisp);: V H7 s7 Q6 T9 k8 j
//已经使用的行数:
* { _- V& g7 s long row_num;
' h6 Z1 [1 ]9 t% @1 L7 c) `8 u6 j range.AttachDispatch(sheet.GetUsedRange());6 k7 P. ~) @7 N; S- m1 v& z
range.AttachDispatch(range.GetRows());
( v& U/ Q: u3 o( R1 g row_num=range.GetCount();8 \& d; d2 h" p
//已经使用的列数:- k4 [. w9 H% i3 f0 N0 K
long col_num;, i6 x* X8 f6 O2 p1 y+ G
range.AttachDispatch(sheet.GetUsedRange());
5 z4 e4 a$ f' F( {1 S; t+ y range.AttachDispatch(range.GetColumns());
* Y1 V+ B3 |& x2 f% @6 Z, S col_num=range.GetCount();+ A( V; r) _) t4 v, Q
//已经使用区域的起始行、列:/ w8 k5 |4 c# G4 S6 u
range.AttachDispatch(sheet.GetUsedRange());' @* ^% o2 X( O# i( C" {
long StartRow=range.GetRow(); //起始行# Q ^. T" J0 C( o9 [* Y- I
long StartCol=range.GetColumn(); //起始列
; U4 T" F& ~7 K! R2 q //读取sheet名' g( o$ ~! u7 s' ~: i T" x! D
CString SheetName=sheet.GetName();
; c9 Q% v$ L& Y/ d/ [ //ads_printf("\n%s",SheetName);
4 f0 T9 ^2 Y/ n8 r) p, m2 W0 U if(col_num<2 && row_num<2) //此sheet为空
3 z0 c+ r% _! N) N {
; I& d1 D p. t4 k3 o) f MessageBox(NULL,"\n当前表格没有数据!", \
\( h# Q$ w+ _) `: ~$ D/ H# s8 S "TrueTable",MB_IConERROR | MB_OK);9 I' j0 w& ?2 h# ]
app.ReleaseDispatch ();) F& f1 c9 ~- q- H- w& ?
return RTERROR;) X; I9 u9 {( L$ Z# T
}1 B: ?$ D7 @1 Q3 x
else
5 c4 }- d3 s6 H6 c& } {. a' Q: W+ r. F; ^' }5 R( |
ads_printf("\n表格%s共%d行,%d列",SheetName,row_num,col_num);# F* q2 I& T* ^1 o; k, n5 y
}
8 d. |3 q4 N# e1 ~ //得到全部Cells,此时,range是cells的集合
0 _& c, {1 E7 t range.AttachDispatch(sheet.GetCells());
# W. C. G; Q# z9 x/ M //读写数据了
( a2 O9 {- ^' d9 S; t CString cstr;1 C" L- A9 B7 J- j5 {; [0 Y1 I
ads_printf("\n");
( P, t* p0 Y' }4 K for(long i=StartRow;i<STARTROW+ROW_NUM;I++) {
" V: p7 f* P! ~( \9 j for(long j=StartCol;j<STARTCOL+COL_NUM;J++) {
W0 c; N" a; C //读取单元格文本( I Z0 R. F2 l3 p- `2 S
iCell.AttachDispatch(range.GetItem (COleVariant(i),COleVariant(j)).pdispVal );% q8 N6 Z9 q/ q( c% i
vResult =iCell.GetText();
; z* F/ W$ ]; |: m) j9 z: I* r cstr=vResult.bstrVal;; K8 z) _2 E# R( P: F
//写单元格文本
$ b7 f7 Q3 c# K" w* ?0 z7 C$ q ads_printf("%s ",(LPTSTR)cstr);1 m6 v$ L; s! C- ]) b4 U
}3 C/ k- R; B; W8 J! N
ads_printf("\n");
& D1 u+ I' n' p% ~ }; {2 |8 e: G3 P; S
//释放Dispatch
: A- G: M6 M7 E8 C' ~% n2 w! q iCell.ReleaseDispatch ();
. E3 d6 E+ M0 ~4 c- Q/ S, p- T range.ReleaseDispatch ();9 \' Z7 p1 {, c: R, ^9 J: ]
sheet.ReleaseDispatch ();
9 k, L2 C8 G& I8 ~4 i1 B- o% u# x sheets.ReleaseDispatch ();
+ P* O9 P& X l! o book.ReleaseDispatch ();
+ u2 ^! n1 L) R5 _4 H. `9 r books.ReleaseDispatch ();
7 _5 F7 I4 _7 o app.ReleaseDispatch ();
8 Y1 W3 l! e! ]9 I return RTNORM;
/ l* N) p0 Y* m" P" P; g3 l, \ }: u! a9 h) r6 c# K( K) W/ X
如果要输出到Excel的话,关键函数就是:1 `' o& P( p0 i' M" c8 \+ Q9 E; `
iCell.SetItem(COleVariant(i),COleVariant(j),COleVariant(cstr)); |
|