|
在实际的工作中,我们经常要对一些表格数据进行处理,如果先把这些表格数据通过Excel处理,再导入到AutoCAD,$ B. I* Y Q8 G# x7 K$ {
那绝对会起到事半功倍的效果。随着Automation编程技术的出现,我们可以很方便地实现这一点了,下面是个/ y5 t4 } l; C t& \# D: e
ObjectARX的例子,其功能是动态关联Excel,然后读取其数据,并将这些数据打印在文本域中。; m; t8 X2 Q4 x7 U4 W: z
//动态从Excel读取数据, i0 i; g/ a1 z' W
int DynamicReadFromExcel()
1 X% \. V. e( v" T" S {, k" B6 t1 O8 O
//常用变量定义
& ^" u" Q, m* r3 r& \ _Application app;
% Z6 i8 r4 R7 ]$ ~& T. T Workbooks books;. e! P- |1 j: V7 x: z% {
_Workbook book;
% L/ A5 n4 C4 J% D Worksheets sheets;
9 a7 Z6 ]" m# g2 R _Worksheet sheet;
# l' ?8 I. \$ C- O Range range;# ?' Q. O* o7 r P( o9 I. @* p
Range iCell;. A% v+ y- _4 E7 c, T) ^* t
LPDISPATCH lpDisp;1 s/ j8 X1 D6 ?8 S$ q3 R# I1 d8 R
COleVariant! X. f1 C4 _# ]6 A9 H
covTrue((short)TRUE),$ B& H: x. O; h6 G2 s
covFalse((short)FALSE),
. f( z( @; v3 P; w3 _2 ` covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);( y" t& @* @9 o$ w3 H
COleVariant vResult;* t P8 t, n/ j& J) o# }
//采用MFC方式初始化COM库,程序结束时COM库会自动释放/ w& R$ p) Y0 o, e& r! c
if(!AfxOleInit())
$ G$ i# z: g, Z, m {4 q, ?8 r( ]$ V7 @" e T! I* r
MessageBox(NULL,"初始化COM支持库失败!\n无法控制Excel!", \+ V. B7 _7 p! D% ^
"TrueTable",MB_IConERROR | MB_OK);1 L4 i8 h6 M) T3 q$ _
return RTERROR;: v$ t% v& j% ]& F$ J
}0 {' D; E4 `6 Q" p5 |
//关联已经运行的Excel实例
* u: |# c3 I4 m CLSID clsid;
. N; u+ ^) y" f* o$ h8 @ CLSIDFromProgID(L"Excel.Application", &clsid);) ~) A2 a3 V+ Y. g. x
IUnknown *pUnk = NULL;
8 D: H, |3 U% E) V5 r IDispatch *pRunDisp = NULL;% {7 Y i- _/ [. r, i
for(long i=1;i<=5;i++) //做5次尝试
) g$ d& E* ]% ~+ m3 o {
3 |, I) n$ g1 ]2 T8 _ HRESULT hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);
. I* b/ X* s; Z$ \2 d+ Z if(SUCCEEDED(hr))
: l* _4 d/ Y d' t- A {
" C d! {" ~1 W) w# C% I w hr = pUnk->QueryInterface(IID_IDispatch, (void **)&pRunDisp);6 B% N `; K) c; O, J
break;8 O; a8 K% d% v" [
}
6 c5 y% _( C1 K! l& ]$ p: W/ L3 s ::Sleep(10);
% _& p! J) d7 B" h" L( i, A" [% |! Z }. y: [1 X; [5 Y$ [
if (!pRunDisp)
$ R7 N: U% \: L5 h {
5 J, a3 L# V! y. b9 u0 v ::MessageBox(NULL, "没有发现Excel!", "TrueTable", MB_ICONHAND);# ~# V- U. b* r: D& z6 r7 J
return RTERROR;
# ?# S Z: V3 D/ l Z$ {& u }
+ m8 p$ @" |/ Q( J# t4 m- | if (pUnk) pUnk->Release();- D* e4 \8 k: a/ j- J8 j' w
//关联Excel( X; ]/ k* Z+ c, i$ U3 Q0 @
app.AttachDispatch (pRunDisp);' Q8 |/ v; ]; A! `" [ R
//得到当前活跃sheet
/ u) [5 \5 {* t, c# W9 e5 O. g- G //如果有单元格正处于编辑状态中,此操作不能返回,会一直等待
' V9 L6 u+ i3 W6 w: n% r& E lpDisp=app.GetActiveSheet();
9 z ], [/ f0 a% u0 O if(lpDisp==NULL)( [5 B+ G+ Y6 M5 p$ s
{
7 I2 n2 Y z6 e- W. a; I) X MessageBox(NULL, "没有发现有效的表格!", \
$ k) I) v) Z& k2 u0 V5 i: t) k "TrueTable",MB_IConERROR | MB_OK);
# g+ w/ d! S* x9 X* s' Q app.ReleaseDispatch ();
/ a$ l% e, D" \* d' } return RTERROR;
; c( M8 q! l5 r1 D+ k }
; T2 A) M9 M! x3 `. T2 U: F sheet.AttachDispatch(lpDisp);* n( [* C% B- B* h" y P6 Q
//已经使用的行数:$ q: c, d" b8 R4 J3 ^" Z
long row_num;
9 j* f) e# B k% Z range.AttachDispatch(sheet.GetUsedRange());
/ C% N! L" e0 V" _ range.AttachDispatch(range.GetRows());
. i& m, u5 T/ C% _: m row_num=range.GetCount();
. ~: M- R6 l2 `& [) k/ y //已经使用的列数:
0 y/ ~$ u* U/ a, x% q) S) o0 z long col_num;4 Q4 I+ v* d9 _. n7 I' j
range.AttachDispatch(sheet.GetUsedRange());( {- c. ]; V6 D4 K- y
range.AttachDispatch(range.GetColumns());
1 p% N) Y$ M8 f& `4 E9 }. h col_num=range.GetCount();
6 I% a3 l/ G! f; W, q% ~ //已经使用区域的起始行、列:
; E& d. y; u8 S1 x range.AttachDispatch(sheet.GetUsedRange());: M5 Q. y& l) Z: x
long StartRow=range.GetRow(); //起始行
. o% m& e G: q$ N8 M( Q4 v8 q long StartCol=range.GetColumn(); //起始列
7 ~) b8 i! S5 m+ e3 X* J/ l! L! g- d //读取sheet名
b7 E$ p* j( ^9 l$ \ CString SheetName=sheet.GetName();4 W& p3 g R5 Y' f/ p5 w+ _$ p6 z
//ads_printf("\n%s",SheetName);3 n d3 j' m9 `1 o
if(col_num<2 && row_num<2) //此sheet为空1 Z: V! |3 A( I: ~' A; ^- K
{8 j2 o; z. o F, Z1 l
MessageBox(NULL,"\n当前表格没有数据!", \
5 E: ~- i: I! C! g) R8 p+ l "TrueTable",MB_IConERROR | MB_OK);$ ]% G! |( e2 [3 ^) p
app.ReleaseDispatch ();
2 b& A# p( z% P$ S8 c/ W* U9 j return RTERROR;
, U/ |/ R: V8 O$ ]9 l6 U }
9 f% _8 h! L6 U; p1 Z0 X else, M E" v' H S x% B( c* ]* x* j* O
{7 V( `1 h F- n' Z7 D3 C
ads_printf("\n表格%s共%d行,%d列",SheetName,row_num,col_num);" s' I; M. `( c) i
}: \# `9 T' _$ o3 i: U& l* K& T' @
//得到全部Cells,此时,range是cells的集合0 a& n$ t$ E4 e/ z* j! E7 J
range.AttachDispatch(sheet.GetCells());. r. @0 P4 ?% S/ d' O" @! w
//读写数据了# y+ W) z' [, D, M7 z
CString cstr;. L+ t: ]# J, h# E. C
ads_printf("\n");, f# K) J% n5 v* f" _# n
for(long i=StartRow;i<STARTROW+ROW_NUM;I++) {
/ w8 f8 z. j2 b3 Q* ~ for(long j=StartCol;j<STARTCOL+COL_NUM;J++) {' A5 I; m1 R2 F& z$ y3 _* F
//读取单元格文本
) ?! L3 v, |5 f& C0 | iCell.AttachDispatch(range.GetItem (COleVariant(i),COleVariant(j)).pdispVal );
. b' k5 W K5 F0 J vResult =iCell.GetText();
+ l$ W0 n2 K4 ` cstr=vResult.bstrVal;$ y" b; m+ u7 h
//写单元格文本: A* D: P1 G' N4 G( L/ L) C& F
ads_printf("%s ",(LPTSTR)cstr);
O" i7 E0 E: V/ z- S& Z }
8 T4 ]/ M9 g2 g9 Y ads_printf("\n");2 k* W* V2 Q! E" a$ L6 U5 z4 l
}0 S6 o" J% m9 v; M( B
//释放Dispatch% {" N: L5 h" X3 @7 B
iCell.ReleaseDispatch ();# d4 Y) m. A3 _
range.ReleaseDispatch ();* H/ M( S) T: Z. R
sheet.ReleaseDispatch ();: i n$ d+ |! C; V8 n9 \ |
sheets.ReleaseDispatch (); h5 e9 b; V! G
book.ReleaseDispatch ();
" w" z/ P1 A, F- u/ q: h6 U books.ReleaseDispatch ();
2 B! X. _% j) A) }" G1 _' G& X. y app.ReleaseDispatch ();) w# X2 H( M$ J9 I9 d6 z
return RTNORM;
; x& q. {5 z% L7 [7 Y8 D, S }) z# h. x. [+ @
如果要输出到Excel的话,关键函数就是:
- H. O2 [4 z: O1 E% p9 y% [ iCell.SetItem(COleVariant(i),COleVariant(j),COleVariant(cstr)); |
|