|
在实际的工作中,我们经常要对一些表格数据进行处理,如果先把这些表格数据通过Excel处理,再导入到AutoCAD,% V3 t4 ~( j, U
那绝对会起到事半功倍的效果。随着Automation编程技术的出现,我们可以很方便地实现这一点了,下面是个5 N8 u# S4 k- y9 v w0 t9 J
ObjectARX的例子,其功能是动态关联Excel,然后读取其数据,并将这些数据打印在文本域中。, r# k. b A2 L: w* O9 Z: V& k6 n
//动态从Excel读取数据$ P- w9 l: ]3 k8 J$ t
int DynamicReadFromExcel()$ m, ]. Y5 Y9 p0 K4 Z/ C
{& ]* z+ F* L9 Q# R/ R, _ [ x3 k
//常用变量定义
) K4 O& C6 j- g; Y b _Application app;, U* r, ?* ^' Y
Workbooks books;1 O+ i' Q, n. r' d; k
_Workbook book;
, B$ ~% d; q* K. I: J+ Z9 | Worksheets sheets;6 E7 N8 r6 P8 [/ ]" c- a' r1 c
_Worksheet sheet;9 r' ^6 I# w2 s9 v: ?& f
Range range;
- ], r/ Q. T2 P$ k+ f Range iCell;
. \; D3 X; C; P' l* _ LPDISPATCH lpDisp;3 @) r$ L# H6 \8 o6 e
COleVariant: Y0 { w9 f/ `; [' {
covTrue((short)TRUE),9 V. a5 x, ^+ c. @0 `4 Q. q0 j
covFalse((short)FALSE),
( `0 h4 B3 H$ T2 [' j. ~7 M/ N covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
C/ K6 Q2 O: Z. y ? COleVariant vResult;+ @$ F$ `" r* U2 b
//采用MFC方式初始化COM库,程序结束时COM库会自动释放! c" Z& ~; q; T& g) G1 ?
if(!AfxOleInit()). w8 g8 t2 D8 o. o* e
{
. o- T! y' H' k MessageBox(NULL,"初始化COM支持库失败!\n无法控制Excel!", \
- s. q+ B5 ~- C* t( m" A0 ~& L "TrueTable",MB_IConERROR | MB_OK);. P' |& q5 r+ Y- M) |
return RTERROR;$ \0 v" A/ r! z5 n' p
}7 H4 `& R# y' v* U" n5 z
//关联已经运行的Excel实例 b' e( W" X% a" k, T. ~
CLSID clsid;
# X5 p, T* o1 w) V CLSIDFromProgID(L"Excel.Application", &clsid);& y7 M( f4 m1 G1 A( o
IUnknown *pUnk = NULL;% \; d7 A' J4 [7 g Y) v s
IDispatch *pRunDisp = NULL;
; \9 {3 A. T7 S4 s l" { for(long i=1;i<=5;i++) //做5次尝试/ R* n( J8 O/ x4 d5 Z
{
6 K R; W! a, A( o HRESULT hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);
7 O' a' Z: ?. K7 C if(SUCCEEDED(hr))' ?- |/ ]& U/ T+ |& N) Y
{9 t$ a; G* l) f. N
hr = pUnk->QueryInterface(IID_IDispatch, (void **)&pRunDisp);
! r3 |# C3 V6 s3 H break;
) t- Q1 t5 N/ U }7 n5 c4 b8 ^) v6 Z% I
::Sleep(10);
* g+ B- L; T8 B( q: Z }
0 R9 H0 u' ~, e7 D, y" b if (!pRunDisp)4 N+ S: [* l0 x. [; A( _4 }
{
$ y) N0 Y; _& d" A3 ~# p3 X ::MessageBox(NULL, "没有发现Excel!", "TrueTable", MB_ICONHAND);0 ~# C. ^0 x0 c9 Z1 m, L) z
return RTERROR;5 u0 ~$ v; h" x" |0 ^
}
: Z8 q& s1 \2 M6 u if (pUnk) pUnk->Release();% z! a U6 `% V8 A/ v# ^
//关联Excel3 [) l A; p. w2 C `$ T# k
app.AttachDispatch (pRunDisp);. @" c* [6 }& y
//得到当前活跃sheet
0 u$ [- C2 f1 ?2 i3 Z9 L //如果有单元格正处于编辑状态中,此操作不能返回,会一直等待& M) }2 x g8 K j$ V- }$ g8 H
lpDisp=app.GetActiveSheet();
3 W# k1 n# y3 x0 d2 ?9 U1 | if(lpDisp==NULL)
8 _% D* y$ r! Y+ O* l% U$ G {! n$ Y) q4 V7 w; t- o- g5 J
MessageBox(NULL, "没有发现有效的表格!", \
9 i" l: g- g' H5 n& y0 [ "TrueTable",MB_IConERROR | MB_OK);
& q- y* O, x" `) m/ w/ k app.ReleaseDispatch ();, P! `- s! a$ r3 T; j
return RTERROR;' Y* u/ W9 V: i/ X6 t
}/ c$ ?/ r" }2 G# x$ s* t1 _) N
sheet.AttachDispatch(lpDisp);& k. t) v k6 L8 F9 n
//已经使用的行数:9 _- s- C8 j- e" K$ h
long row_num;
' \/ R; U, h+ Z# ` range.AttachDispatch(sheet.GetUsedRange());
8 ~6 l3 k) A& ~3 m! _7 r3 W range.AttachDispatch(range.GetRows());( m3 o, j* _( _' o" n+ f& c+ o$ m/ P
row_num=range.GetCount();
; J* m1 \; v" @* S8 Y/ v //已经使用的列数:
& L/ V+ |% l/ o# g/ p long col_num;
. i; y! W1 d6 m9 b" X: P6 ? range.AttachDispatch(sheet.GetUsedRange());
+ I x. C' E- |& ^/ x0 S- F range.AttachDispatch(range.GetColumns());6 ^% b" H4 |/ E! n# }! E3 M
col_num=range.GetCount();
# h+ }+ J* e& V9 _- t //已经使用区域的起始行、列:
$ o* |: q0 n& x& [& O4 e range.AttachDispatch(sheet.GetUsedRange());
' N/ J! t& k* z5 ?9 O& [1 p long StartRow=range.GetRow(); //起始行
, [$ U' Y. P# _) M( S long StartCol=range.GetColumn(); //起始列9 O! @6 A- q$ p# g: C# U
//读取sheet名
5 u# T: T) s+ ] CString SheetName=sheet.GetName();3 n( M) q1 F" y7 K+ r
//ads_printf("\n%s",SheetName);
8 z* M$ F* x8 y: G. L) w$ x if(col_num<2 && row_num<2) //此sheet为空
% k; `- x, q! d" N/ x {( L; T# ^! B# Q1 X" ?8 t
MessageBox(NULL,"\n当前表格没有数据!", \" C0 V2 z U6 U" M# _( K
"TrueTable",MB_IConERROR | MB_OK);! `# V5 u6 M7 W8 [, V* Z' }
app.ReleaseDispatch ();
( v. C( u* O& z! }1 C+ l return RTERROR;; I& L9 g4 N/ O5 C
}) [. G% u( S& q# D, L& \" t. V/ X3 D
else, I! f2 ^# O5 a2 n+ Q
{2 y4 j. V1 K- L, s8 v! m
ads_printf("\n表格%s共%d行,%d列",SheetName,row_num,col_num);
: p ~/ K, x2 L- A5 m+ ~9 h, T }
* D% l' g7 u4 s2 q0 u //得到全部Cells,此时,range是cells的集合( X" @" K; z2 W! m
range.AttachDispatch(sheet.GetCells());9 [. Z# ]4 E5 s/ g
//读写数据了' f, q X: g2 A% D d) V9 @
CString cstr;
$ S4 u5 e* Y' y6 [" O ads_printf("\n");
+ Z& W/ W! x5 ^: A7 f for(long i=StartRow;i<STARTROW+ROW_NUM;I++) {! T* H9 C& o) l5 F( `/ w
for(long j=StartCol;j<STARTCOL+COL_NUM;J++) {( \7 F1 c* C2 Q* t. k) T
//读取单元格文本
4 P4 x S6 M7 O iCell.AttachDispatch(range.GetItem (COleVariant(i),COleVariant(j)).pdispVal );
! o, O J1 u/ N; X$ }' z+ A( ]8 R vResult =iCell.GetText();
- z4 |* H1 t8 Z# l7 R& A5 n cstr=vResult.bstrVal;( [$ F3 v6 S% Q7 l
//写单元格文本
" ]5 O9 |( h- h0 l$ ^# ^2 R( O' k3 K ads_printf("%s ",(LPTSTR)cstr);
5 a' j/ [9 J; d% ? f }
/ z2 i+ f2 H3 I8 v$ e. Q8 E2 Y ads_printf("\n");
1 X. t5 D% j/ r [! _' w }2 f) X: p/ j& x" r* G
//释放Dispatch
7 f3 R4 @% t8 E9 R! s$ p iCell.ReleaseDispatch ();& x9 C9 t. E j" ]" I! \
range.ReleaseDispatch ();
7 W* Q$ \3 O) {- n sheet.ReleaseDispatch ();
# e6 Y7 s+ q }, n sheets.ReleaseDispatch ();/ O6 r( y; M# a, g0 e
book.ReleaseDispatch ();% V7 G9 _+ L. G2 E$ K1 \( b
books.ReleaseDispatch ();) }/ ?8 Y# }! r5 i6 q+ u5 n# E$ L
app.ReleaseDispatch ();
: O# [. y9 Z# @ H9 a2 c return RTNORM;
6 } N; }2 W- d. E3 d4 H }! W9 l, J) Z2 M2 @2 H0 f
如果要输出到Excel的话,关键函数就是:
2 h, R: a$ j2 j0 }' g iCell.SetItem(COleVariant(i),COleVariant(j),COleVariant(cstr)); |
|