|
在实际的工作中,我们经常要对一些表格数据进行处理,如果先把这些表格数据通过Excel处理,再导入到AutoCAD,, H' f# D/ k, s$ P: h, o( j
那绝对会起到事半功倍的效果。随着Automation编程技术的出现,我们可以很方便地实现这一点了,下面是个* S) [& b* c$ o9 Q" f' ^0 k; ^+ [
ObjectARX的例子,其功能是动态关联Excel,然后读取其数据,并将这些数据打印在文本域中。
) G& t E9 _1 _( e5 j7 s //动态从Excel读取数据
: ?) [" _) K/ }. b int DynamicReadFromExcel()* f% z1 ~! s) i7 c" B* B- a
{
% h# A' v; N7 u5 `6 g5 N //常用变量定义+ L# `5 _1 W! ~, E6 n7 }$ q: k' p
_Application app;5 G" i( X1 x8 _- q
Workbooks books;4 q9 y1 i D- \7 u! I$ c
_Workbook book;
0 S3 M9 N1 _/ [! O" ?7 Z% ? Worksheets sheets;; H2 M. P1 i3 I' X
_Worksheet sheet;
1 H" `+ S8 k% v; }8 o: D Range range;
& m( Q: I" e' g0 D' B* R Range iCell;, J+ t+ V$ {4 t! Z- _
LPDISPATCH lpDisp;, q, c* _8 Z0 t) c/ E8 {
COleVariant
$ O, X4 k3 v- n% \. j+ a covTrue((short)TRUE),) \' O4 i! l5 i( H O1 Q+ l
covFalse((short)FALSE),
5 v4 F6 o/ x5 ]5 h* B covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
# _, k1 _9 j4 p2 C2 K7 s, u# o COleVariant vResult;
. U$ {" E4 c% |9 X //采用MFC方式初始化COM库,程序结束时COM库会自动释放! \2 ^' v4 k" W2 _2 Z
if(!AfxOleInit())0 r4 ^1 q! Z; N! [
{7 h( X2 k2 @8 z& d% j3 F u
MessageBox(NULL,"初始化COM支持库失败!\n无法控制Excel!", \6 b7 E$ ?5 S4 S! }
"TrueTable",MB_IConERROR | MB_OK);
( X w, A3 y7 h( O return RTERROR;1 J0 i1 @* b K0 C4 K
}+ j: W l9 [7 x2 `2 O0 f
//关联已经运行的Excel实例
$ M0 K; b3 A2 v6 M. w CLSID clsid;
& C; V; @, O# t CLSIDFromProgID(L"Excel.Application", &clsid);
4 v% k- V. _% E( i2 u# o8 V) v IUnknown *pUnk = NULL;6 T# X @; F: U( P
IDispatch *pRunDisp = NULL;& ]* a' U$ D( n! @3 p- l
for(long i=1;i<=5;i++) //做5次尝试9 B2 a& _6 l: g& l2 ]
{
" d1 H1 X; Z1 Z2 _: Q) p HRESULT hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);' r/ z2 J3 v- @, L
if(SUCCEEDED(hr)): h; L0 y8 K( @' f- j
{
/ {9 f! E* i* ], s! E. d2 n4 Q2 ?0 `% d6 j hr = pUnk->QueryInterface(IID_IDispatch, (void **)&pRunDisp);
# g% [% N+ W$ `, H' X/ c break;5 [! x7 ^; Z4 ~$ U3 M* }' ]
}; U6 r" d( P* }* o7 J0 c7 Z/ V
::Sleep(10);
: e) ?& J# a- A% X7 ]. A }
1 o/ @! b5 i, b) K if (!pRunDisp)( s9 `& t O1 z6 `4 i
{3 @8 ?# [ ~" [
::MessageBox(NULL, "没有发现Excel!", "TrueTable", MB_ICONHAND);2 n% K8 e. n2 I2 U* U5 a5 g: `* }
return RTERROR;
+ ^$ ^, x) i/ e4 W }1 Y8 y8 P7 L# [% B2 ]
if (pUnk) pUnk->Release();( m& C1 c( y" J9 D
//关联Excel
6 e/ }& q( B& A9 v( i& \/ U app.AttachDispatch (pRunDisp);
) U! e) w8 ?. ]; v: L5 C //得到当前活跃sheet8 X0 o1 c) m3 y. S6 B8 ]# i8 g
//如果有单元格正处于编辑状态中,此操作不能返回,会一直等待
: G6 J# h6 Z! U+ ], K9 K* D) x- ? lpDisp=app.GetActiveSheet();% @! o- Z( M( T2 v; d$ d. o
if(lpDisp==NULL)
& u" {1 T) ] f* D& B" _% ` {
' j# ^/ s) f8 A; K MessageBox(NULL, "没有发现有效的表格!", \4 e& |8 j6 w4 f n( C' b
"TrueTable",MB_IConERROR | MB_OK);
( O2 \' {% r) T& t% r! M app.ReleaseDispatch ();
2 t- H# Y) |* O" |+ x x# n return RTERROR;8 O' R6 {) G y/ W! g
}
; M4 @2 c4 {2 ]1 f7 T sheet.AttachDispatch(lpDisp);1 M+ a# o5 r# y: J3 h: F) ]
//已经使用的行数:. |7 x* F1 d- N& i9 q3 u) F- U
long row_num;& S7 j+ `/ u2 q! J+ a1 h4 c
range.AttachDispatch(sheet.GetUsedRange()); W, U- n3 E" T( E( N4 P6 {
range.AttachDispatch(range.GetRows());
$ y' m; H) |& \ row_num=range.GetCount();
4 _6 i, k6 U% W5 T4 T4 N, p //已经使用的列数:
, t6 B6 O* A% G long col_num;
4 Z/ W& s9 T6 m+ V7 j) s, a range.AttachDispatch(sheet.GetUsedRange());
G) K/ _6 l6 ^ range.AttachDispatch(range.GetColumns());5 o% b2 l' O: \1 V" o% S* _
col_num=range.GetCount();, W7 t- z# K) O) @' C" c8 y
//已经使用区域的起始行、列:! L2 l' {) X4 y
range.AttachDispatch(sheet.GetUsedRange());
2 r5 Y3 |& d1 d$ P long StartRow=range.GetRow(); //起始行: c9 a4 T/ D. a
long StartCol=range.GetColumn(); //起始列
" K) i4 j( C9 z1 ]$ N; t //读取sheet名
3 V( i# E& e0 X1 _% P6 p CString SheetName=sheet.GetName();/ m9 S) m, L, U
//ads_printf("\n%s",SheetName);
! ^& S6 c4 ?* Y6 p if(col_num<2 && row_num<2) //此sheet为空0 d9 v7 |+ o1 N. |( q3 G; r) `
{' K: u: K% P& z: `, |$ _) W
MessageBox(NULL,"\n当前表格没有数据!", \
1 x9 z' J+ q2 o7 U+ W/ T "TrueTable",MB_IConERROR | MB_OK);. E6 \& g' m& ]% @/ Q* J q
app.ReleaseDispatch ();6 k: J, r% P# z4 E4 r
return RTERROR;
: C* `# |! q+ |7 V! t& R+ T0 r/ y2 e }
$ F, I, p; U' k, O4 m+ z' r else# M+ r* I2 p4 g( w$ S2 H
{
4 E H2 `7 r$ q+ ^5 _ ads_printf("\n表格%s共%d行,%d列",SheetName,row_num,col_num);
" K$ `0 x2 @* ` }
b# W+ G( [9 e2 V3 Z //得到全部Cells,此时,range是cells的集合, `) O7 l/ r, K8 m& y
range.AttachDispatch(sheet.GetCells());: N8 n9 }1 ~9 J: q' j5 c" |# j
//读写数据了# s/ k- \9 W, N3 K+ e
CString cstr;1 K1 |: i. M; t% d& [. g& Q0 J
ads_printf("\n");& b6 d ~% L* J8 N% C
for(long i=StartRow;i<STARTROW+ROW_NUM;I++) {7 ]1 A" O/ u5 i
for(long j=StartCol;j<STARTCOL+COL_NUM;J++) {. L3 |! z: X$ W3 U5 A2 h7 \
//读取单元格文本
$ D' C# o# O3 N% n; E9 y- u g iCell.AttachDispatch(range.GetItem (COleVariant(i),COleVariant(j)).pdispVal );
. v0 ]2 v& h) @ vResult =iCell.GetText();
. g* y2 O& `6 [8 b+ q cstr=vResult.bstrVal;
% I: }/ d1 L! z1 Q //写单元格文本
" q0 i7 ]! J% w9 G3 ~! h9 r* J ads_printf("%s ",(LPTSTR)cstr);
( T$ z2 t( S( o) o: y- z$ j' A }' f9 O8 F6 _) `8 g) c
ads_printf("\n");7 D) W( p9 w( E$ q0 @( g% |# l9 d
}
2 Z+ h% t, y! e. _: I //释放Dispatch
& q9 K- I% M; N9 }: a iCell.ReleaseDispatch ();1 k8 ?* Q5 A& E2 a9 t
range.ReleaseDispatch ();, y4 X% _1 l3 w' X
sheet.ReleaseDispatch ();
5 D2 o, S* Z; T/ i0 D0 H sheets.ReleaseDispatch ();
: o w' V8 L6 \5 `/ m; F/ R% d book.ReleaseDispatch ();
% x' e0 @: T2 R, |1 H4 | books.ReleaseDispatch ();
7 ], d0 E+ S; t9 E1 C6 _ app.ReleaseDispatch ();) P; T4 v1 h- ?! W( u
return RTNORM;
4 i% D+ B' g1 y$ }8 \" Z }* |. L, T/ h5 U v, P- R
如果要输出到Excel的话,关键函数就是:. {6 N1 K; `+ V8 K3 g# k
iCell.SetItem(COleVariant(i),COleVariant(j),COleVariant(cstr)); |
|