|
在实际的工作中,我们经常要对一些表格数据进行处理,如果先把这些表格数据通过Excel处理,再导入到AutoCAD,
( u6 N; c9 X6 L& W; @- a 那绝对会起到事半功倍的效果。随着Automation编程技术的出现,我们可以很方便地实现这一点了,下面是个* w+ o5 H5 P, r9 j$ e
ObjectARX的例子,其功能是动态关联Excel,然后读取其数据,并将这些数据打印在文本域中。
6 e( G# D, J6 b1 n' ~ //动态从Excel读取数据- A: I" s- p2 H- u: h2 S
int DynamicReadFromExcel()6 Q7 k) N8 b# O2 S1 N8 S" c ^
{- g8 l+ J2 E5 C q6 l q
//常用变量定义- E( A* o# j1 Q% f$ H; f
_Application app;$ f0 C+ r6 k/ q3 J: P1 z
Workbooks books;
' W: z, o0 ^( X0 g6 j+ T8 m _Workbook book;8 b- f3 ]" f- a/ D5 k
Worksheets sheets;5 G* x, u, S6 o. Q& ~" ~2 e
_Worksheet sheet;2 X- }2 }! a: x" L% ?. ?" }
Range range;5 p- N& `: W, V; M! P
Range iCell;6 t: M. h' C+ |& {5 A: a6 k
LPDISPATCH lpDisp;
( Y* c; v2 `; M6 ~: L7 v: I COleVariant
' e3 k3 x w6 J+ q+ P F covTrue((short)TRUE),0 I$ s3 G5 F7 Z2 _
covFalse((short)FALSE),5 j" e; B! M3 v' @
covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
( _ l5 V2 k: x! o/ L5 t0 A) i: u COleVariant vResult;- n' p, u# Z$ f3 O1 t1 L( S
//采用MFC方式初始化COM库,程序结束时COM库会自动释放8 z3 I" Y5 e3 T9 C6 v' J9 P3 _
if(!AfxOleInit())
; N5 k7 \/ j8 v {7 q' A3 R' \ ~( x0 ?
MessageBox(NULL,"初始化COM支持库失败!\n无法控制Excel!", \
4 _; @; [! i; G' T4 |- h "TrueTable",MB_IConERROR | MB_OK);
; U/ E7 ]% }5 H/ Y$ @ return RTERROR;
" o4 A- n5 ^2 g9 D7 L) O }3 N* L9 V l5 O
//关联已经运行的Excel实例$ e8 ]4 f$ ?- y1 X! D3 {5 v, @5 L
CLSID clsid;
4 c, b' e* H' F9 @7 q CLSIDFromProgID(L"Excel.Application", &clsid);
* l* B# G1 h2 B& Z5 j4 j4 D! D# i IUnknown *pUnk = NULL;/ F ]! y( L! Y. x
IDispatch *pRunDisp = NULL;
]3 Q0 d% Y, V/ V for(long i=1;i<=5;i++) //做5次尝试
$ u6 L% O+ {- u( V% A% k9 f {
6 q x4 A' A, X& Q/ d7 { HRESULT hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);3 x0 Z# J# I( g3 Z( j
if(SUCCEEDED(hr)), a/ F1 Q D; F: _/ {1 _8 K, w
{
+ p0 h3 G: d9 U# F hr = pUnk->QueryInterface(IID_IDispatch, (void **)&pRunDisp);
& a0 p# ?7 B& y* {' v break;
6 n- \' F0 R- N }
: r/ b3 V& W$ d9 c! }: A ::Sleep(10);
' N8 n4 x$ i9 ? }
; C7 s) n! G5 \1 A( C$ A& p if (!pRunDisp)
W* K7 r9 p# i8 Y* V8 _9 O {
* ]6 n/ f; ]8 z8 H* B# c2 ` ::MessageBox(NULL, "没有发现Excel!", "TrueTable", MB_ICONHAND);9 |+ f# f2 Y! C+ ?& v
return RTERROR;) ~# I, B5 W* W8 y0 s
}( j' |- z+ @' m0 c
if (pUnk) pUnk->Release();
2 ]6 f; d3 T/ @% L //关联Excel
! j9 q6 ?6 B4 I3 |- l. M! A* D app.AttachDispatch (pRunDisp);
: r6 I. ~8 i: {. O) O4 Q# `0 B5 ~ //得到当前活跃sheet
, p+ k' u' N' j, @+ @2 x ~" L //如果有单元格正处于编辑状态中,此操作不能返回,会一直等待' j: v* T: B. z n
lpDisp=app.GetActiveSheet();# w0 S$ G+ P4 f- b1 U4 @" Q
if(lpDisp==NULL)
b9 |* b( Z8 G `6 h1 S; z { Y m y2 y+ ^0 K! b+ Z
MessageBox(NULL, "没有发现有效的表格!", \
9 ^8 W. P% t1 U# @6 v "TrueTable",MB_IConERROR | MB_OK);
" o7 |% {) S$ {- P app.ReleaseDispatch ();
8 X1 h5 w, y; t0 c' z/ J return RTERROR;9 Q6 P( ^4 X$ g1 W4 [
}
k) [3 Z: R, ?8 A2 ?7 s; r/ S8 ^2 w sheet.AttachDispatch(lpDisp);4 X* j, j8 S/ b2 H& L
//已经使用的行数:
) j9 q, u6 t5 k1 s! Q$ K+ k6 b long row_num;
7 D5 L0 I; m& h4 N- M range.AttachDispatch(sheet.GetUsedRange());8 Q/ |$ g4 m7 R+ o& V3 \
range.AttachDispatch(range.GetRows());
3 q0 I6 t0 A. M- D7 {+ _; g row_num=range.GetCount();
3 _) u+ b, `! `" J @ //已经使用的列数:# x6 B! ~5 U1 G! H- @
long col_num;
. H9 j2 j5 X4 d% o, b4 F range.AttachDispatch(sheet.GetUsedRange());
' x+ g7 R% v) Q+ J: I z e range.AttachDispatch(range.GetColumns());
: }; l- ^9 F' g7 _8 N# u: v9 M col_num=range.GetCount();5 P+ O* d8 T0 e. Y
//已经使用区域的起始行、列:& w' @3 o: X) h
range.AttachDispatch(sheet.GetUsedRange());* e7 u( _1 s1 O. ~" t
long StartRow=range.GetRow(); //起始行
- A- d; ~" ^/ t" u1 ] long StartCol=range.GetColumn(); //起始列- J7 a2 z& x$ [- g6 k/ l) n/ |, T
//读取sheet名( n6 N8 ^5 G; h" V, \- l6 w
CString SheetName=sheet.GetName();
- {: f7 Q1 @# A& R5 i9 I" T //ads_printf("\n%s",SheetName);3 P p+ b; N" i& f; `3 P
if(col_num<2 && row_num<2) //此sheet为空
+ g, p2 b+ }3 R; s {4 I- g0 E* P) z" `; g; ?! }
MessageBox(NULL,"\n当前表格没有数据!", \6 ^- D+ v; z" }, k& ? z: X
"TrueTable",MB_IConERROR | MB_OK);; W0 Z( v4 |) M6 ]# g
app.ReleaseDispatch ();
l& R5 Z. H5 |9 L# J, L return RTERROR;
- ]* a1 W1 a9 Q; D }0 w# i1 d- l/ {7 c$ m q
else
0 Z% C" s! Q6 r: D" v0 C |/ M {. ~4 P7 s( e" A; N5 D: z# q! e& @* v
ads_printf("\n表格%s共%d行,%d列",SheetName,row_num,col_num); F( ]1 O9 m% a1 g; f7 M& n0 M; r
}/ \: |, w8 @0 C1 Y# {# R
//得到全部Cells,此时,range是cells的集合
7 y7 A1 {0 S" T7 s% E+ i7 C range.AttachDispatch(sheet.GetCells());
7 z3 ~0 x+ ~$ s1 n //读写数据了
' @, @ Y1 e, o9 u4 ] CString cstr;
5 j/ C" S6 _$ s' E ads_printf("\n");1 _/ V8 ~0 W' _# r
for(long i=StartRow;i<STARTROW+ROW_NUM;I++) {
+ |3 C# ?! K, e2 ^" R for(long j=StartCol;j<STARTCOL+COL_NUM;J++) {
8 [3 X; e* l) h //读取单元格文本
( b( F1 Z* C7 b6 ~- j iCell.AttachDispatch(range.GetItem (COleVariant(i),COleVariant(j)).pdispVal );1 |; M q# a8 k; n: E
vResult =iCell.GetText();
9 q+ b d: E5 \5 Z: Y* d cstr=vResult.bstrVal;
/ y& \3 _! c Z4 R5 V/ }* B! C/ ` //写单元格文本
. C- Y0 L& j$ S/ o& f( J! z* ^ ads_printf("%s ",(LPTSTR)cstr);
* b0 c$ ^# d, v& X) r, {! ? }4 F- x& r+ a' j5 G" t" \
ads_printf("\n");
; ]8 f7 k# P* e' L }% v4 Z m# f2 S6 ^9 s
//释放Dispatch$ M7 G( E+ L" |- ^' b- O1 h
iCell.ReleaseDispatch ();) _$ G: V% H; I
range.ReleaseDispatch ();
# y* O7 M' i M3 J sheet.ReleaseDispatch ();& _8 E1 m+ L! P0 o, b
sheets.ReleaseDispatch ();" X) H! |/ X1 W0 A; V, ^
book.ReleaseDispatch ();
% D6 I! `- v! L books.ReleaseDispatch ();
2 _) a- u( h6 Q app.ReleaseDispatch ();
9 A0 N+ a$ {$ R! B: V0 R/ M+ k return RTNORM;) ?0 I* O, x1 s* t% {6 u2 l7 |
}- D3 X: [; }( ?9 D
如果要输出到Excel的话,关键函数就是:
8 y3 @2 l* A& Z, P( y/ n iCell.SetItem(COleVariant(i),COleVariant(j),COleVariant(cstr)); |
|