|
在实际的工作中,我们经常要对一些表格数据进行处理,如果先把这些表格数据通过Excel处理,再导入到AutoCAD,
) U5 d/ Z( E+ U. V( a2 { 那绝对会起到事半功倍的效果。随着Automation编程技术的出现,我们可以很方便地实现这一点了,下面是个9 w9 L* ?* u7 N+ D, C
ObjectARX的例子,其功能是动态关联Excel,然后读取其数据,并将这些数据打印在文本域中。
+ v- B2 X5 ]! _8 t6 g //动态从Excel读取数据$ G& z% U1 a4 S" S$ M$ B6 ~) H% X
int DynamicReadFromExcel()# y/ ?" m" r' ]7 H/ Q( n3 i. q) _- n
{* `8 C) q n, M% d" {6 e
//常用变量定义1 n. `9 p3 A7 t5 b& {
_Application app;* _ C* V0 {% q& ^' h
Workbooks books;. b) V% c3 u {/ R
_Workbook book;% ^: L2 J, K1 L+ E7 E. ~+ y
Worksheets sheets;& K* `! m4 n+ h6 w
_Worksheet sheet;
2 L2 E/ u" a/ Z# r: } Range range;
( m8 n* [4 K% _( ?' w! g; f& b Range iCell;
0 \2 A; |2 H' ?2 B1 Y3 R+ D LPDISPATCH lpDisp;. x8 Z; p( _& d: }! d! u0 J
COleVariant! I8 I$ o9 E8 d1 S8 p- Z" l
covTrue((short)TRUE),
- l0 o8 y- _8 i covFalse((short)FALSE),
: |9 Q5 @0 c+ c0 d% N0 d$ B covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
* T a+ ^# p) |$ U COleVariant vResult;
2 L8 O* w! Z1 i3 O2 w+ N+ Z //采用MFC方式初始化COM库,程序结束时COM库会自动释放/ y& E/ c: S5 ?# G# m
if(!AfxOleInit())& \ f0 L6 B; J8 Q" Y& a# v4 W/ c
{
! i$ M% H: {! p V) t* E, z, c MessageBox(NULL,"初始化COM支持库失败!\n无法控制Excel!", \
N2 l% P8 X" Z8 W2 Q "TrueTable",MB_IConERROR | MB_OK);% s% x+ g5 F. x8 ]! k
return RTERROR;
) r$ P {! \6 }. k" A9 t/ J4 r }
2 t/ B5 d0 |9 Z& q* { //关联已经运行的Excel实例
3 \% o; i2 i* O' S3 V CLSID clsid;% _0 Y) i7 J( [ j: M
CLSIDFromProgID(L"Excel.Application", &clsid);3 x, e" p, o3 {6 S+ X# v/ }
IUnknown *pUnk = NULL;
8 }& a+ |; {# \& l& l; J IDispatch *pRunDisp = NULL;
3 ?4 ?) `, A( i for(long i=1;i<=5;i++) //做5次尝试
2 ]2 ~# m* t, ^7 Q! r+ U( K {4 s" Y; g. y l
HRESULT hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);0 T6 J, y9 Z5 G/ E( s) Z
if(SUCCEEDED(hr))
( Z$ O& K8 n: W7 u/ t {
& t7 Z. `7 R1 r/ i hr = pUnk->QueryInterface(IID_IDispatch, (void **)&pRunDisp);
; [& |" e5 X1 n6 |( E# @ break;
+ ?2 H- [) {8 o9 P6 V: y1 _' n+ t }
" t2 i6 o4 {8 R) j9 S; | ::Sleep(10);
5 u) Z m! T* O8 _5 g( F }( ^( m9 s; t' c. h& Y+ F3 Z6 ?8 X
if (!pRunDisp)2 S7 w: Q' Y& F2 X' }6 s
{
' b, I# R, X# m) ]% d( q: q4 p6 L ::MessageBox(NULL, "没有发现Excel!", "TrueTable", MB_ICONHAND);) E9 X G* d4 G6 S
return RTERROR;
6 `4 A" }9 ?1 S% ?4 g& G' q }
. u- I, _! Y' Q8 h# U f if (pUnk) pUnk->Release();' S% L7 o0 }: Y9 X/ K) ^" }
//关联Excel! A) O6 ?: j. Z! S. U6 O
app.AttachDispatch (pRunDisp);4 K% a9 k) v0 ]& ]% W
//得到当前活跃sheet v) Y% z+ q1 C
//如果有单元格正处于编辑状态中,此操作不能返回,会一直等待
# D ~8 Z! w$ W |0 e lpDisp=app.GetActiveSheet();
" h" @; A. b1 s$ H& C if(lpDisp==NULL), ~+ R/ y& p* s5 p ^
{' L* Z0 R* [+ b% Q% T$ b0 R
MessageBox(NULL, "没有发现有效的表格!", \ ]: m6 }7 o" @7 b2 V$ s1 y
"TrueTable",MB_IConERROR | MB_OK);
/ A1 Q2 _8 W; r* J' Z! X app.ReleaseDispatch ();
$ B' z1 t7 O, F! ] return RTERROR;
& {( z. Z1 ?0 a/ O5 B M; h }1 G% ~: R) d9 f- u5 K; X
sheet.AttachDispatch(lpDisp);
4 K" x2 x) v8 t2 ?+ R //已经使用的行数:
; S/ |; M( ~4 c' L long row_num;6 T8 d3 n$ o( D& R3 K
range.AttachDispatch(sheet.GetUsedRange());) [" y* r* v% g7 `
range.AttachDispatch(range.GetRows());
# @$ ^0 Y4 p3 i* q2 h row_num=range.GetCount();# A& m9 ^, u3 h/ Q
//已经使用的列数:7 o6 R" M0 ^& Y' p
long col_num;9 Q. p& t4 \4 H( R$ i+ R/ f% t
range.AttachDispatch(sheet.GetUsedRange());9 m- o3 y& S$ R
range.AttachDispatch(range.GetColumns());3 o3 ^' B# Q- u( n& P& ~/ a
col_num=range.GetCount();
( G# L. u9 a( b //已经使用区域的起始行、列:' d- _/ ~5 X9 L' V0 I
range.AttachDispatch(sheet.GetUsedRange());
9 `: U' K3 R# Q2 ?: d long StartRow=range.GetRow(); //起始行
3 F) S6 k# J9 V* d long StartCol=range.GetColumn(); //起始列" Q; k, N0 P$ G; S9 _
//读取sheet名
/ A& B" \: G1 Y) c9 k" A7 I/ t CString SheetName=sheet.GetName();
1 s$ Z. ?+ G. p- y' i3 F I //ads_printf("\n%s",SheetName);
/ g1 x" D1 q- h" ]" {8 Q if(col_num<2 && row_num<2) //此sheet为空$ L+ Z7 @" @1 m" S P- i
{
# n# ?! H7 J+ Y/ o) n MessageBox(NULL,"\n当前表格没有数据!", \
/ {) U3 e$ U5 a( ~" ] [ E3 d+ ]+ e "TrueTable",MB_IConERROR | MB_OK);
* P& ~) h+ _) r. `& h q% n) j6 k2 Y app.ReleaseDispatch ();9 u, ]: W' V8 X R- U6 U
return RTERROR;
5 T# U$ [: o- U4 F+ W* p: f }
- E* ?; W2 G7 r$ Y! V+ c+ q else) x8 W* y j& g/ v% n
{
8 F; v" H% ^% A# ^: E" H/ ^% ~ ads_printf("\n表格%s共%d行,%d列",SheetName,row_num,col_num);
9 i5 o, N! [& ^! z8 o }/ ?* n O6 J; z
//得到全部Cells,此时,range是cells的集合' U: d, u7 w" p- G
range.AttachDispatch(sheet.GetCells());
& K) v5 v b0 d }" _ } //读写数据了
6 J# |: I- v" u* Q- Y p% b CString cstr;# d& X) f0 g6 k Z$ R+ s# K
ads_printf("\n");: b' h3 Y! v$ O8 V* I* j& i; k
for(long i=StartRow;i<STARTROW+ROW_NUM;I++) {: \# e% g0 X. ~+ z
for(long j=StartCol;j<STARTCOL+COL_NUM;J++) {/ L" q4 M D( k) e/ v) |5 n
//读取单元格文本" o& r8 `2 k0 \! @* B
iCell.AttachDispatch(range.GetItem (COleVariant(i),COleVariant(j)).pdispVal );4 h! Q8 S0 w! M x6 Q" L: |* A
vResult =iCell.GetText();* g8 S. u( ]" Q) |+ R9 W9 }
cstr=vResult.bstrVal;# G5 l, X' f( \
//写单元格文本# S+ u6 H7 u6 t' j- q
ads_printf("%s ",(LPTSTR)cstr);0 ^ q9 k, d% T. `4 M7 o# E% F
}
( h2 K' L' R* D' u- C* l ads_printf("\n");
, ]3 x1 G7 v( @. `2 L H# h }
6 C5 N* }8 B0 Q( z; F; K9 G //释放Dispatch
) L2 u) T* k' N/ a iCell.ReleaseDispatch ();! U& i! Q: [: f) `. c
range.ReleaseDispatch ();
& k" k2 i( v% L5 K. }0 x sheet.ReleaseDispatch ();6 w/ a, @+ ^ j* Y1 ^
sheets.ReleaseDispatch ();
/ c( S5 G- |9 K% g* H/ p book.ReleaseDispatch ();
$ r$ f# q) l5 p/ b5 s1 ? books.ReleaseDispatch ();: c7 |3 l* d3 G: p C
app.ReleaseDispatch ();% c& T8 b6 T% k$ m* ~# H
return RTNORM;
% B4 a, G& c! |" ?- h. Z. H* h! C! v }
. F& h& T5 Y0 A2 r! C- M3 w 如果要输出到Excel的话,关键函数就是:
. f2 c1 n2 b8 W1 @, o iCell.SetItem(COleVariant(i),COleVariant(j),COleVariant(cstr)); |
|