PLM之家精品课程培训,联系电话:18301858168 QQ: 939801026

  • NX二次开培训

    NX二次开培训

    适合初级入门或想深入了解二次开发的工程师,本培训结合ufun,NXOpen C++,大量的实例及官方内部的开发技术对于老鸟也值得借鉴!.

    NX CAM二次开发培训报名 NX二次开发基础培训报名
  • PLM之家Catia CAA二次开发培训

    Catia二次开发培训

    Catia二次开发的市场大,这方面开发人才少,难度大。所以只要你掌握了开发,那么潜力巨大,随着时间的积累,你必将有所用武之地!

  • PLM之Teamcenter最佳学习方案

    Teamcenter培训

    用户应用基础培训,管理员基础培训,管理员高级培训,二次开发培训应有尽有,只要你感兴趣肯学习,专业多年经验大师级打造!

  • PLM之Tecnomatix制造领域培训

    Tecnomatix培训

    想了解制造领域数字化吗?想了解工厂,生产线设计吗?数字化双胞胎,工业4.0吗?我们的课程虚位以待!

PLM之家PLMHome-国产软件践行者

[转载电子书] VS C++操作Excel详细教程

[复制链接]

2014-11-8 08:13:41 6424 0

admin 发表于 2014-11-8 08:13:41 |阅读模式

admin 楼主

2014-11-8 08:13:41

请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!

您需要 登录 才可以下载或查看,没有账号?注册

x
通过VC实现对Excel表格的操作的方法有多种,如:通过ODBC数据库实现,通过解析Excel表格文件,通过OLE/COM的实现。本文主要研究通过OLE/COM实现对Excel表格的操作。! \$ X" u$ q: v! k5 F
  
) N# e9 Y4 h- k8 R+ u6 u" o! |本文源码的应用环境说明:
" U# c0 b/ X/ y2 ?Windows XP SP37 a0 R4 j/ b8 N2 I9 P% ?/ U; ]
Microsoft Visual Studio 2010
9 L; m5 q# [: T4 I( ~) ?" nMicrosoft Office Excel 2007
3 @7 s6 a$ r4 Z, l; M$ G" e  2 [! x. y8 t& k8 x* g
1、添加OLE/COM支持。+ U7 B' i0 ^; o% G/ n
首先,应用程序必须添加对OLE/COM的支持,才能导入OLE/COM组件。6 y! M  q# D0 [3 Y) E  M; X2 k) X
本文使用的是MFC对话框程序,在创建工程的向导中选中Automation选项即可为程序自动添加相应的头文件和OLE库初始化代码。5 E5 i; ?6 l9 u
通过查看源代码,可以知道在stdafx.h的头文件中,添加了OLE/COM很多类所需添加的头文件。2 P% I7 J( V( M5 m
#include <afxdisp.h>        // MFC 自动化类! E1 v6 R2 `9 f2 \8 G! ?# R, l
同时,在应用程序类的InitInstance函数中,添加了OLE/COM的初始化代码,如下所示:
- V$ Y( [0 j" w5 |% q9 ?// 初始化 OLE 库% k5 l8 ~+ G( Q( o( [; _
if (!AfxOleInit())
# W6 j( H4 s6 t* A/ U( F{% s& j% R% z; `. u
AfxMessageBox(IDP_OLE_INIT_FAILED);3 ~$ f! h; v& y: u8 ?- Z& Y1 Y: c
return FALSE;
! Z5 l# b0 J" ^7 E2 q# q4 U+ d( Q}
5 L, i* I; Q5 }% `  8 Y2 e! i1 D* a: t+ ?
2、导入并封装Excel中的接口
( S) g3 K1 s5 s0 E. nExcel作为OLE/COM库插件,定义好了各类交互的接口,这些接口是跨语言的接口。VC可以通过导入这些接口,并通过接口来对Excel的操作。- ~: A1 G1 ?/ t5 ?
由于本文只关心对Excel表格中的数据的读取,主要关注几个_Application、Workbooks、_Workbook、Worksheets、_Worksheet、Range等几个接口。Excel的各类接口的属性、方法可以通过MSDN的Office Development进行查询。$ |8 {& u" f8 }  M. t
VS2010导入OLE/COM组件的接口的步骤为:Project->Class Wizard->Add Class->MFC Class From TypeLib,先选择要导入的组件所在的路径,即Excel.exe所在的路径,然后再选择
) `+ H( ~9 V, e8 M$ s要导入的Excel类型库中的接口。3 N6 b, C+ S0 ]5 T
在完成接口导入后,VS2010将自动为导入的接口创建相应的实现类,用于对接口属性和方法的实现。由于标准的C++没有属性访问器,只能添加一个两个存取函数来实现对属性的访问,通过在属性名称前加上get_和put_前缀分别实现对属性的读写操作。即,由VC自动完成C++类对接口的封装。
+ _6 l" A. K. k/ W4 Q0 j2 r9 O  
5 |, A7 s9 H6 c' C  L+ N  j9 s本文所导入的接口对应的类和头文件的说明如下所示:/ q- t. ?# j: }1 C9 m7 M# _1 W
  
$ I% ^' R/ X1 z9 l" fExcel接口' i: A7 h" M+ ~6 q" X  _5 W+ ^  k5 W
导入类8 ]9 E1 r" \6 |/ w* t! I
头文件- z" n+ U: ]  J) R
说明. J0 V# s, y, M: q; D; [
_Application
" D% H- ^) Z7 X  D2 M4 J1 @CApplicaton
4 e  |. y/ d8 X! K9 V! sApplication.h
) R+ x( ?* S: G1 VExcel应用程序。
0 [# S6 W4 z) F. pWorkbooks; Z! Q: u4 z4 d# d+ u
CWorkbooks
. g7 |1 Z0 l' \4 c$ q, ~' \' {$ KWorkbooks.h
5 G* c: a# I! F7 w, }7 p" W% T工作簿的容器,里面包括了Excel应用程序打开的所有工作簿。9 U: x( U# j& }* E0 H! d: O$ ?. w3 M
_Workbook4 c% j- G9 k7 p
CWorkbook
- E  e3 Z. P6 s$ C, ?& UWorkbook.h
* N1 |- s; s" |! E; I1 y, H2 v# z单个工作簿。
. }. a( j: S* A* v/ TWorksheets  k( O# E( d5 V# ?# ?2 _
CWorksheets
1 W7 j& O1 Y  P, L5 z5 LWorksheets.h# V2 {: N; N# |; I  |
单个工作簿中的Sheet表格的容器,包括该工作簿中的所有Sheet。( _$ D1 ?% s" H$ ~- f) q- q
_Worksheet' W+ I: ?* _4 x: ^; I& r
CWorksheet2 ~. I; R0 d5 u
Worksheet.h
+ D2 T4 e6 y" o4 @: R: g单个Sheet表格。
: L& ?# W9 f% K& ?Range" `/ f6 }7 m: v; {- K
CRange2 b1 z8 P, e4 t7 |
Range.h3 [3 v. a, u5 n$ c2 |) {( W0 [4 ~
一定数量的单元格,可对单元格进行单个或多个单元格进行操作。7 c6 [9 S& ]2 L) T* Y
  
7 q3 I1 N7 G1 a3、导入Excel的整个类型库
4 D  h4 _# ^* e) I% m7 o; z. J) A接口对应类只是对接口的属性和方法进行了封装,而Excel中的数据类型,如枚举类型却并为并不能使用,因此,为了更方便的操作Excel,还需要导入Excel的数据类型。% _0 P' q0 p$ A; y9 M5 `
通过查看导入接口对应的头文件可以发现,在所有导入接口的头文件中,都会有这么行:
5 }# ]0 P8 s2 o' c#import "D:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE" no_namespace
, S/ O. G3 P0 C& D这行代码的作用是导入Excel整个类型库到工程中。, Q' E6 o8 n+ h5 ]9 E
由VS2010自动产生的导入代码存在以下几个问题:
1 ?- h9 Z+ E" x. T1 j) |* w(1)如果导入了多个接口,每个头文件都会把类型库导入一次,如果引用多个头文件,会导致类型库重复导入。
* J, Y, y/ T4 }" y; I/ C(2)Excel类型库中有些类型会跟MFC类库的某些类型冲突。
1 G+ |9 h$ U) E' _# F) m, T0 l' J(3)Excel类型库的某些类型跟其他Office和VB的某些库相关,如果不导入相关库,将导致这些类型无法使用。。
7 B5 o4 m9 S6 E. a. |以上三点问题的解决方法如下:& ~5 c3 q" x9 j* v7 e
(1)仅在_Application接口对应头文件中导入Excel类型库。
9 N+ B- W" H( F8 V(2)对冲突的类型进行重命名。$ l8 E; h1 _; Y( T3 w% Z: n, V* |, Q
(3)在导入Excel类型库之前,先导入Office和VB的相关库。
) b6 g! l; p1 b, z& X5 S$ o更改后的导入类型库的代码如下:% z0 a, _4 e# e/ ]/ t  R4 R, v
  ( ]% b+ V1 Q5 P4 c9 p1 t
/*导入Office的类型库*/5 ^" ^2 L3 t9 P" M+ F1 h  N7 j
#import "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE12\\MSO.DLL" \
- A  f7 T/ y0 lrename("RGB", "MSORGB") \6 ]; b0 D; ?* X5 ~. m* |# V7 s
rename("DocumentProperties", "MSODocumentProperties")
& R  T8 g$ m+ w! B, s0 {using namespace Office;
# c! G, a+ Y9 t0 _4 O' G! J  6 z" W/ A# H* h; M4 |
/*导入VB的类型库*/
; }- r, l' e7 }5 Y2 q# K( u#import "C:\\Program Files\\Common Files\\Microsoft Shared\\VBA\\VBA6\\VBE6EXT.OLB"1 W( l% H) |9 H! |
using namespace VBIDE;$ r1 a$ U" E4 P% q' ?7 R+ e9 I
  
7 O6 H. A, ~3 [) r/*导入Excel的类型库*/: V- Y# V1 h' Q. p0 @1 I6 D
#import "D:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE" \, F2 w$ w# r# {, k- X$ f: Y0 t3 b
rename("DialogBox", "ExcelDialogBox") \
# c1 f1 K. Y- }rename("RGB", "ExcelRGB") \# |, h% C) T$ _. s  A! ]9 y
rename("CopyFile", "ExcelCopyFile") \
5 p. q4 R$ [- U4 R6 ?: W5 H  ?rename("ReplaceText", "ExcelReplaceText") \
. t& r% h) e( p+ N" p; v  J% k4 _no_auto_exclude6 a0 V# U8 ~2 p) Z+ \; c. z0 @
Using namespace Excel;
5 L- J! p$ b3 @9 o1 V8 A; s  6 v4 A. A2 ^( m, c# f
编译程序后,会在DebUG或Release目录下生成三个文件mso.tlh、vbe6ext.tlh和excel.tlh。通过打开文件可知,该三个文件的命名空间分别是Office、VBIDE和Excel。导入了Excel的整个类型库后,就可以使用Excel中的所有类型了。
7 l' \4 _% u3 P+ S% B3 L) M  . A& f3 B% \; R# r1 ~- [
4、操作Excel步骤
6 Y- G% M  Q6 f8 o" z' |# n' s& D操作Excel的主要步骤如下:2 s$ T. M9 l1 }) U9 p# C
(1)创建一个Excel应用程序。$ }( N" _; F# D6 a$ K, V
(2)得到Workbook的容器。
$ \; d0 l% [. q) z(3)打开一个Workbook或者创建一个Workbook。
4 O; M! ]6 D# }+ `(4)得到Workbook中的Worksheet的容器。# k9 P% j' D1 D5 i8 O" ^6 r
(5)打开一个Worksheet或者创建一个WorkSheet。( ~' o( P$ l+ q$ F# c7 o
(6)通过Range对WorkSheet中的单元格进行读写操作。5 s0 M# Z$ s1 Q6 O
(7)保存Excel。% ?  m5 R* ~0 v6 h; H
(8)释放资源。- y- J0 S* {6 e4 r
  . J. |. B0 J" S! W. a
5、批量处理Excel表格9 x: r1 n: Q7 Q* w" @6 G
VC通过OLE/COM操作Excel,是通过进程间的组件技术。因此,每次读写Excel中的单元格时,都要进行进程间的切换。当数据量大,如果一个单元格一个单元格的读取,主要的时间都花费在进程切换中。因此读取多个单元格,将可有效的提高程序的运行效率。
6 P8 f3 ?# G8 W' F: ?- \对多个单元格的读写操作可以通过CRange中以下两个成员函数来完成。
* h* K2 J' P4 J5 JVARIANT get_Value2();
4 U7 E6 t8 u7 f4 F" a# mvoid put_Value2(VARIANT& newValue);; t8 R: F, Y; J3 O4 c8 Y& Y4 `
其中,输入参数newValue只要输入一个二维数组,即可实现向Excel中一次写入多个单元格的值。/ m6 S8 q/ ?9 W# l' v* u+ d
其中,VARIANT中实现二维数据的方法可参考7 n$ ^8 t# W6 I! j# \# \( r2 p7 H
http://www.cnblogs.com/xianyunhe/archive/2011/09/13/2174703.html/ O, g) r: D$ {2 R2 b2 P4 [" C
当然,在对CRange类进行操作之前,要设置CRange类对应的单元格。1 S9 [# E, F( s+ H$ l4 f& ?" w! ]
  - u) m- H9 U: F+ E1 A
6、Excel表格的保存
! ]2 H; ~3 A9 l$ P0 S(1)如果要保存打开的工作簿,使用CWorkbook类的Save函数就可以保存工作簿,原文件将被覆盖。
- N: p" z9 y/ n- ?(2)如果是新创建的工作簿,或者是要另存为,可使用CWorkbook类的SaveAs函数。* j  f7 J1 w' o
SaveAs的参数比较多。其中,第1个参数是设置要保存文件的路径;第2个参数是设置文件的格式,可在MSDN中查看枚举类型XlFileFormat来了解Excel的文件格式。经过测试,在本文所用的测试环境中,Excel2003的文件格式是xlExcel8,Excel2007的文件格式是xlExcel4。4 K+ w$ [0 U9 k8 v3 E. C  n$ K6 T
  1 e( Y/ T, L: J+ ~7 d
7、获取当前Excel的版本6 o8 \% }( e* S4 r+ S7 J. |
可以通过CApplication的get_Version函数来获得Excel的版本,其中,Excel2007的主版本号是12,Excel2003的主版本号是11。# _! E8 `; a8 Q! g4 M
  
' p+ V( z" r2 {1 y8、示例源代码
4 U% U3 s& ]) {. a: a  N主要代码如下:
9 j: }$ v/ g) O9 K1 E6 ~" p, {4 A  4 H* {) \7 {/ q6 N! H2 F
7 r5 {- [: j8 H/ s

6 E: a6 ]" d0 f9 s# H  h    m_LisTCtrl.SetExtendedStyle(LVS_REPORT | LVS_EX_FULLROWSELECT);
7 i7 J; R* g$ ?. V- z) m* H  ^6 e- m8 L+ B, m
    CApplication ExcelApp;4 V# L$ o$ u# `& }' v& z
    CWorkbooks books;
* Z- w7 f, R- l) T- P- ?1 c2 i    CWorkbook book;
7 j/ L& s2 k7 n& S: v6 [$ U: Z) F    CWorksheets sheets;* F& L- [+ |) D+ i
    CWorksheet sheet;0 u+ M$ `1 J7 P1 u( B9 n! ?
    CRange range;
4 U; |, U! J) j: H  A0 I* {$ R    LPDISPATCH lpDisp = NULL;
# q1 s- T7 b. m& _5 ~
* k) p* Y; i* ~& _, `    //创建Excel 服务器(启动Excel)
0 h* m9 V  E5 g6 L) v    if(!ExcelApp.CreateDispatch(_T("Excel.Application"),NULL))
# I' F- s) ^& j0 j    {
+ j+ p' u, R) A        AfxMessageBox(_T("启动Excel服务器失败!"));/ ~7 ~0 P; U7 a, [
        return -1;
4 U, h" r8 b: i$ v, M" z& c    }
4 w5 O. |( v4 ~$ z3 I7 Q
, b. a- ?6 {8 g* ]* B9 @/ E- ^- t- b    /*判断当前Excel的版本*/' g+ i! C- H9 `3 j
    CString strExcelVersion = ExcelApp.get_Version();
# R7 m! }8 l( q3 a: I5 A. n    int iStart = 0;
: x  m* _  q& `, `' X9 O) Q    strExcelVersion = strExcelVersion.Tokenize(_T("."), iStart);
% l7 ?7 q+ f4 |2 [2 {    if (_T("11") == strExcelVersion)% G5 W1 b6 ~: L0 ]( Q0 V
    {0 x& W# m6 g4 s0 |6 l
        AfxMessageBox(_T("当前Excel的版本是2003。"));
: X6 T9 z$ b9 b0 b  [    }
# L# ^" [5 V0 [1 O! V8 S& e3 l    else if (_T("12") == strExcelVersion); z0 Y& a% t+ V
    {
+ x1 @) V, U- @        AfxMessageBox(_T("当前Excel的版本是2007。"));
$ b% |1 Z- s1 M4 U# J; n, N    }
$ ?. r$ T& W9 s+ w4 f    else
6 s9 p: X5 X  R& Y1 G    {
$ Z; t: Z$ H  R2 C- a* j        AfxMessageBox(_T("当前Excel的版本是其他版本。"));
! c4 H" y! w/ b! J7 I+ O1 o# p    }
8 ?* T, Y. v3 e: P2 B  Q+ p& B3 r$ C# Z* S; E# c
    ExcelApp.put_Visible(TRUE);
) Y4 O, f% M. g    ExcelApp.put_UserControl(FALSE);
+ r! F; ^; u  e3 v3 e( d
2 ?# f  Y* i2 e( G0 P+ \# p$ K    /*得到工作簿容器*/: j0 \$ @. A" s  q: p
    books.AttachDispatch(ExcelApp.get_Workbooks());: u3 R5 T8 V4 Z1 y* h3 Y
3 L* s5 Z" |, s! f( E9 E( D
    /*打开一个工作簿,如不存在,则新增一个工作簿*/
: ?! d3 n- `3 p    CString strBookPath = _T("C:\\tmp.xls");5 x7 ?+ B1 n3 Z) g% T  {
    try
( i; P( j4 F& C. N    {0 V1 e- v% }& Y  v" H
        /*打开一个工作簿*/
2 @2 }+ {4 V2 a1 P        lpDisp = books.Open(strBookPath, + O* ?/ Y& P6 x+ J
            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,, c: s/ U, }- R! a
            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,
+ v  E8 t/ j4 _% V; h" e            vtMissing, vtMissing, vtMissing, vtMissing);
) x( X" q5 ]; N7 F        book.AttachDispatch(lpDisp);
+ M# l2 I0 }: q' l# t) F    }% g) U4 X* y! v+ l' r
    catch(...)
$ {8 {7 E3 j% a* i- l, k' r    {
& b( a  v. i4 g3 ~3 }( B$ l1 m/ i        /*增加一个新的工作簿*/
5 _. |0 v; Q: {# N( M        lpDisp = books.Add(vtMissing);
1 y/ F- Q3 Z& T6 y        book.AttachDispatch(lpDisp);$ t/ q' I4 H( P# D
    }/ R" `2 [( Z* Q5 r
     / F/ E' L' V) y) _# \9 v1 ?
5 t) f! p8 `0 n& T$ c4 _
    /*得到工作簿中的Sheet的容器*/
& F4 J& y0 i- @# r    sheets.AttachDispatch(book.get_Sheets());
' s8 z5 E3 L  H  H& W* V
& [/ F) p; ?- l4 p6 P( ^' u    /*打开一个Sheet,如不存在,就新增一个Sheet*/
, T4 k( `9 V' N% a* e- y. d    CString strSheetName = _T("NewSheet");4 g  z: ]7 v# c5 ]& h# U
    try
0 |* _* o( G! B! G# a3 |    {! x* G. M+ Q( C  ]
        /*打开一个已有的Sheet*/& P  d1 b% H, A3 Q* x
        lpDisp = sheets.get_Item(_variant_t(strSheetName));
) i! _3 ]. c; B5 L( p        sheet.AttachDispatch(lpDisp);; U0 |) q# C: F4 \) `/ |) t3 a. |5 R& R
    }
6 J2 D$ M7 w4 ^* g0 H9 a, i    catch(...)
: _9 m: G9 }. F, P' v8 I4 N5 a    {9 h- x3 s; y9 W4 A8 r# u
        /*创建一个新的Sheet*/
  H! M. q" C) G  M: F        lpDisp = sheets.Add(vtMissing, vtMissing, _variant_t((long)1), vtMissing);
$ X. B& `) K7 ]4 j/ f0 j        sheet.AttachDispatch(lpDisp);: F0 F: h1 ^; }& ?4 _
        sheet.put_Name(strSheetName);
* D- Q" S) g+ {0 u; I, g7 B& i3 F3 @    }' |$ {" H( W+ F2 Z/ c- t& J2 H

4 k* ?8 L. Z4 F4 {6 k, J% L) Y    system("pause");
" L, A) J- A  b" y6 R$ d
1 L6 t3 M! {* D8 E& F9 ]1 \    /*向Sheet中写入多个单元格,规模为10*10 */
+ ?# t1 G" J4 u) m# S    lpDisp = sheet.get_Range(_variant_t("A1"), _variant_t("J10"));5 R* i* r' V) y% M2 p3 e
    range.AttachDispatch(lpDisp);
8 b( V9 H$ C8 B% \' ~4 I5 u5 d3 a0 v: U* c
    VARTYPE vt = VT_I4; /*数组元素的类型,long*/
9 y, m# ]4 n% h3 D$ ^    SAFEARRAYBOUND sabWrite[2]; /*用于定义数组的维数和下标的起始值*// d* L5 Q+ c/ c
    sabWrite[0].cElements = 10;
1 h# A1 U0 y' {/ u0 j3 q* W    sabWrite[0].lLbound = 0;
, z% ^, n: O9 m6 b$ F( j$ J. `7 @    sabWrite[1].cElements = 10;5 {" A9 c, s& ]. B, B6 T
    sabWrite[1].lLbound = 0;4 o3 k8 ^7 r, e1 F
0 E( D5 p( o' \' J) k" z
    COleSafeArray olesaWrite;7 K: [4 O% P7 Q: G
    olesaWrite.Create(vt, sizeof(sabWrite)/sizeof(SAFEARRAYBOUND), sabWrite);
7 D/ q/ C9 P  p+ J9 I' ~$ ~8 b4 c
5 t' S' [7 I0 G0 a& X5 L/ k1 A    /*通过指向数组的指针来对二维数组的元素进行间接赋值*/
4 F1 f7 Q. M+ @* o; R' E1 o1 U- d    long (*pArray)[2] = NULL;
+ e0 @1 f, d5 D1 ?! r    olesaWrite.AccessData((void **)&pArray);' F. n, m9 L3 r$ c
    memset(pArray, 0, sabWrite[0].cElements * sabWrite[1].cElements * sizeof(long));- g* r7 N; A0 S$ V

4 E5 Z" v' t5 J/ m) N8 o& ]    /*释放指向数组的指针*/
, C% J& p4 \- M3 o    olesaWrite.UnaccessData();% }; m* z; k" o6 l) H
    pArray = NULL;
/ v6 ~  @; m" d8 E/ p6 Z9 z2 H( }% W8 U' g7 b  r' N. S5 t
    /*对二维数组的元素进行逐个赋值*/
% C% m) Z+ f3 u5 |) V    long index[2] = {0, 0};
$ A% ]3 u4 W" C2 o' F    long lFirstLBound = 0;/ M" N  T& d, N/ I& M$ }
    long lFirstUBound = 0;
; t" X( c. F1 Y' a    long lSecondLBound = 0;- a# I  i, k! B- l4 {! }
    long lSecondUBound = 0;
. e  c/ U2 ^2 n: O    olesaWrite.GetLBound(1, &lFirstLBound);
4 o7 D! z2 w; e% x4 b7 h$ z" y* C! e5 s    olesaWrite.GetUBound(1, &lFirstUBound);
# I/ f( t. ~* r; Q1 C6 Q) u" q( T    olesaWrite.GetLBound(2, &lSecondLBound);* M* I& \6 F! |% ?6 O1 \; r  Y
    olesaWrite.GetUBound(2, &lSecondUBound);0 v* h8 `! r: i( ~- c7 |
    for (long i = lFirstLBound; i <= lFirstUBound; i++)
4 r$ {9 c% W/ t3 m5 N    {; W( h+ ~; {) x" g3 H
        index[0] = i;/ ~  c( j+ f" X) i4 Y0 h. B7 X) X5 j) y. `) \
        for (long j = lSecondLBound; j <= lSecondUBound; j++)$ A1 h( ?: V  c' t: a
        {
1 l, E/ k0 d4 L: m            index[1] = j;# L+ l3 x8 I5 P! `, p
            long lElement = i * sabWrite[1].cElements + j; 6 D/ i: u! w( F
            olesaWrite.PutElement(index, &lElement);
0 v. _7 L8 U! z! ^' j3 S, h' ?        }- y) {; p4 v0 s) ~# F
    }: d6 U" {" s0 Q6 J8 w; k- o

4 y' U+ J5 G6 L7 f; `% B7 x    /*把ColesaWritefeArray变量转换为VARIANT,并写入到Excel表格中*/
; y2 M" U$ b& C* m    VARIANT varWrite = (VARIANT)olesaWrite;1 ~4 J* C: K: ^+ O
    range.put_Value2(varWrite);
/ D5 u! P5 i% X; d$ {) a  |+ U3 k# ]0 a  c; ~& B; ~
    system("pause");2 |6 ^. K: T% T: H6 k
* B0 H  N. k6 W+ J* R) |( N
    /*根据文件的后缀名选择保存文件的格式*/
2 a- f/ c5 [6 n  K( r9 J3 M2 |! i, V     CString strSaveAsName = _T("C:\\new.xlsx");
  P* ~5 ]$ Y) v9 }3 @! w$ `2 G+ [+ i    CString strSuffix = strSaveAsName.Mid(strSaveAsName.ReverseFind(_T('.')));$ Y& v& {' c" w+ ]! H% ]; z
    XlFileFormat NewFileFormat = xlOpeNXMLWorkbook;6 `$ ]! H/ z) y
    if (0 == strSuffix.CompareNoCase(_T(".xls")))
+ G  I7 X0 i# M. _; V6 H3 C    {
( U! V& ]; ?4 C/ n        NewFileFormat = xlExcel8;/ D7 d& `4 q! K. {
    }
* K% Z$ z7 J* `: w1 o    book.SaveAs(_variant_t(strSaveAsName), _variant_t((long)NewFileFormat), vtMissing, vtMissing, vtMissing,
5 x5 q2 Q/ u+ H        vtMissing, 0, vtMissing, vtMissing, vtMissing,
( @- i; A8 O( G' D% F; J/ o( `5 s        vtMissing, vtMissing);
/ e. o6 x! ~1 Z
7 Y5 O& D( }3 b    system("pause");. a* c" t+ I/ Y" y: e8 B
2 s3 W2 X+ b7 M* Q
    /*读取Excel表中的多个单元格的值,在listctrl中显示*/3 u0 A9 m: f" k8 Y0 K9 _) e
    VARIANT varRead = range.get_Value2();
! Y! ?5 d( I' t! G3 j    COleSafeArray olesaRead(varRead);" D% g7 |' [1 L* F/ h+ w

) |, B9 ?# H# R; A0 E0 I- V    VARIANT varItem;
, |8 `2 Y# J  h' r    CString strItem;" \7 r6 h* g6 L. g7 [0 ~
    lFirstLBound = 0;6 o0 ^  a) ~- k+ n9 P. D4 J8 ]
    lFirstUBound = 0;
: T3 u7 D8 w1 L2 b# i    lSecondLBound = 0;3 h- A( Z2 M- G% P( `' c
    lSecondUBound = 0;9 ^0 A3 |  A  Q
    olesaRead.GetLBound(1, &lFirstLBound);
3 Y3 {: m7 R/ S) g/ u    olesaRead.GetUBound(1, &lFirstUBound);) S4 e+ }" z! Y) v4 ?2 Z
    olesaRead.GetLBound(2, &lSecondLBound);
5 X( @% A) X* U! t; q% D  Z. g    olesaRead.GetUBound(2, &lSecondUBound);3 i8 I6 S9 ]" |: r
    memset(index, 0, 2 * sizeof(long));$ g4 S( D2 B# H' U8 [* D1 t
    m_ListCtrl.InsertColumn(0, _T(""), 0, 100);) B. T" I( k- `( D
    for (long j = lSecondLBound; j<= lSecondUBound; j++)
( u2 C: N0 k2 ?" y    {
5 R9 S9 C( Y# a7 p' w, [* m        CString strColName = _T("");6 h; C% b( O. z; |# ~2 L1 J* p* t
        strColName.Format(_T("%d"), j);6 z& e: I' b" J. M9 X. z1 Y( }3 y5 m
        m_ListCtrl.InsertColumn(j, strColName, 0, 100);
# }( f$ M  j4 p/ H, R% `' b$ L* ]. l: B    }$ f2 D  r  v. [0 n; K: T7 f3 q% G
    for (long i = lFirstLBound; i <= lFirstUBound; i++)
3 E0 D5 `/ }& \- V: Z    {
8 B: x. v, L! \0 W3 ~        CString strRowName = _T("");
5 o0 N; x  u# B( Z        strRowName.Format(_T("%d"), i);
) p* F) B0 \( N& c9 v        m_ListCtrl.InsertItem(i-1, strRowName);2 W" T- {$ J* o3 P0 q) R

) Q0 l1 _* ^, u) l& z* D. r        index[0] = i;
$ x7 P: W9 m9 g/ i6 K( B4 x        for (long j = lSecondLBound; j <= lSecondUBound; j++)
4 O% r* ?# k5 x        {# k) g; v2 l0 M# B$ [
            index[1] = j;5 h& }8 f( C0 H4 ~% C
            olesaRead.GetElement(index, &varItem);0 ^# c  m$ L/ {2 ~0 I' q

! \  }- O0 R  v9 N9 ?1 ?( t            switch (varItem.vt)
8 B7 ?* m- V4 f! P. j5 Y            {5 G7 e2 ]0 Q& a7 L$ u' w
            case VT_R8:( b' u8 V& @8 Y
                {
8 A5 p) f9 G  v8 j                    strItem.Format(_T("%d"), (int)varItem.dblVal);
1 {% T. y! E) a0 }                }
. \+ D2 v5 _8 W/ \
: z, j+ j* Y- w3 h5 a. q            case VT_BSTR:
; n) m0 }8 k& W, W: b. k6 j* T                {
4 C& a' b+ F+ H& Y& D4 f' n                    strItem = varItem.bstrVal;
1 J) e2 Z0 r( W  ?; Z, S: r# E8 K6 i                }; m! M; k! p. d, G/ q. U2 W! g

) H) t- a9 m" i* d            case VT_I4:
# }5 ^+ M5 f! L$ _5 q& W                {
3 B, j& Z8 |8 r2 f4 {( ~5 Z# |                    strItem.Format(_T("%ld"), (int)varItem.lVal);: ^* G# D) `' |3 R
                }
3 z% o- z4 n2 W3 T, f( b& y0 b5 i' ]0 ?; ]4 E( z, Z$ ~4 r* @& n
            default:( A6 z; Y, P: k6 n' j
                {
9 n" ^0 X. ^5 @  V" @, ]4 u, K4 L: R2 C. w8 K7 o/ o: `, r  T9 V  H8 E
                }1 [1 h& l6 b4 p' v7 @- b' i
            }$ K0 R* n7 {; R+ g8 L, u; L  t
2 y/ f3 Q( r$ S3 b' a
            m_ListCtrl.SetItemText(i-1, j, strItem);
" n8 R1 \/ g8 A+ U" A        }( U3 P" q7 G, F3 ^% Q; T' z
    }  D" D+ n! s" D; {' P
. k5 s' S: d: V4 o" P, o1 K; p; {
% x' L, l9 A5 }2 I8 N6 H2 r% a
! A4 ^: g, l+ v
    /*释放资源*/! R: e  x0 _, ]9 |  n% l$ y
    sheet.ReleaseDispatch();
1 I. n' v5 v. M& }4 c* \6 X) C8 w    sheets.ReleaseDispatch();
" [9 ~0 D  ^+ q1 a8 I( I    book.ReleaseDispatch();# w6 Y, H0 R; w
    books.ReleaseDispatch();
9 v; |% B, r- S  D, W8 L! e/ e2 _- m    ExcelApp.Quit();
8 t7 i& e- ?% W) P8 `# h1 l    ExcelApp.ReleaseDispatch();& ?* w( b/ |" N1 w

1 r( Z! E1 O/ T% l9 {/ I/ ]
上海点团信息科技有限公司,承接UG NX,CATIA,CREO,Solidworks 等CAx软件,Teamcenter,3D Experience等PLM软件,工业4.0数字化软件的实施\二次开发\培训相关业务,详情QQ 939801026 Tel 18301858168 网址 www.diantuankj.com/ doTeam.tech
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 注册

返回列表 本版积分规则

  • 发布新帖

  • 在线客服

  • 微信

  • 客户端

  • 返回顶部

  • x
    温馨提示

    本网站(plmhome.com)为PLM之家工业软件学习官网站

    展示的视频材料全部免费,需要高清和特殊技术支持请联系 QQ: 939801026

    PLM之家NX CAM二次开发专题模块培训报名开始啦

    我知道了