PLM之家精品课程培训

PLM之家精品课程培训

联系电话:18301858168   |   QQ咨询:939801026
NX二次开发培训

NX二次开发培训

UFUN/NXOpen C++和实战案例

适合初级入门或想深入了解二次开发的工程师,本培训结合ufun,NXOpen C++,大量的实例及官方内部的开发技术。
公众号二维码

关注公众号

点击扫描二维码免费在线高清教程

课程详情
Catia二次开发培训

Catia二次开发培训

市场需求大,掌握核心技术前景广阔

Catia二次开发的市场需求大,人才稀缺。掌握开发技能潜力巨大,随着经验积累将在汽车、航空等领域有所作为。
B站二维码

在线原创B站视频

点击关注工业软件传道士主页

课程详情
Teamcenter培训

Teamcenter培训

全方位培训,从基础应用到高级开发全覆盖

涵盖用户应用基础培训、管理员基础培训、管理员高级培训及二次开发培训等全方位内容,由多年经验讲师打造。
QQ群二维码

加入同行交流

点击扫描二维码加入QQ群

课程详情
×

PLM之家plmhome公众号

课程涵盖: PLM之家所有原创视频

×

关注B站视频

所有高清视频一览无余,全部在线播放学习

×

加入PLM之家QQ群

同行交流,疑问解答,更多互助

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

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

[复制链接]

2014-11-8 08:13:41 6531 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表格的操作。/ ]# @5 g6 E' P8 L( @; h
  9 E8 M& i; l5 g' X  z
本文源码的应用环境说明:
# Y7 h+ k) D: b7 X/ l, `Windows XP SP3/ x! t7 @+ W7 D, i# U/ t9 v& e. {
Microsoft Visual Studio 2010' {6 U& O" [# U
Microsoft Office Excel 2007
" c" i6 G- x" x  q  8 F9 B0 h  H) w
1、添加OLE/COM支持。
5 z0 N3 P- j8 ]首先,应用程序必须添加对OLE/COM的支持,才能导入OLE/COM组件。
' a  K1 [1 Y3 n2 X; l* t  q7 F本文使用的是MFC对话框程序,在创建工程的向导中选中Automation选项即可为程序自动添加相应的头文件和OLE库初始化代码。
- c; |4 J0 }8 Z  S0 J1 I3 y3 `通过查看源代码,可以知道在stdafx.h的头文件中,添加了OLE/COM很多类所需添加的头文件。' G- Q3 l' u0 G  j' O$ h/ @
#include <afxdisp.h>        // MFC 自动化类8 |) _; f! C' J( L
同时,在应用程序类的InitInstance函数中,添加了OLE/COM的初始化代码,如下所示:2 g8 ~! z& I. d" a" n3 W! k
// 初始化 OLE 库. d, ~$ X- f6 h: r5 b6 x8 P
if (!AfxOleInit())
* L4 s8 w* A! c& h& B3 h8 Y& L  u{' Z! ^, t1 B( f; v: v1 C
AfxMessageBox(IDP_OLE_INIT_FAILED);' h3 w7 `* x/ h, {
return FALSE;2 h" k& c7 X5 i$ G' M0 R
}6 f5 d6 f$ \- U* k
  
' z4 f; c/ K. {2 ~5 B% ^2、导入并封装Excel中的接口$ W+ c* G  J- Y
Excel作为OLE/COM库插件,定义好了各类交互的接口,这些接口是跨语言的接口。VC可以通过导入这些接口,并通过接口来对Excel的操作。
7 b9 |, U4 _' r1 C由于本文只关心对Excel表格中的数据的读取,主要关注几个_Application、Workbooks、_Workbook、Worksheets、_Worksheet、Range等几个接口。Excel的各类接口的属性、方法可以通过MSDN的Office Development进行查询。
( B- @3 z$ v+ i9 ^& gVS2010导入OLE/COM组件的接口的步骤为:Project->Class Wizard->Add Class->MFC Class From TypeLib,先选择要导入的组件所在的路径,即Excel.exe所在的路径,然后再选择
5 J# Z4 M# T) d/ L& Y2 Y要导入的Excel类型库中的接口。4 {0 Q, I6 \# R+ h  M! F
在完成接口导入后,VS2010将自动为导入的接口创建相应的实现类,用于对接口属性和方法的实现。由于标准的C++没有属性访问器,只能添加一个两个存取函数来实现对属性的访问,通过在属性名称前加上get_和put_前缀分别实现对属性的读写操作。即,由VC自动完成C++类对接口的封装。
' R$ `( ?; f" P' a& s# F  , n1 G; J! e, Y( ~7 c
本文所导入的接口对应的类和头文件的说明如下所示:* v8 ^) K# x" r4 X. P5 d
  
7 ~3 \% e+ k! C! b  S2 P4 U  lExcel接口! T, w8 X' X7 i0 l5 {
导入类
( V+ I4 z$ U, Z; s头文件2 e' |+ N: _8 y+ P8 [/ e  ^5 k. q
说明
, S& [) }* a: h3 F6 @_Application$ {6 J+ F- h" ~
CApplicaton& [# Z3 R* Z. |, n6 i
Application.h, Q' N8 P1 C; N3 Y  v% k) x9 u
Excel应用程序。. y  ]3 o$ X/ I2 [" a& b' T
Workbooks
) n2 ^: Z( {1 NCWorkbooks
/ |  a/ E+ ?. r  p5 HWorkbooks.h* @, T  e% r; E1 P4 X
工作簿的容器,里面包括了Excel应用程序打开的所有工作簿。
: T7 ^  ?& a3 Z8 V6 O% y_Workbook& R3 W: a! Y7 l: S+ G( j4 \7 N7 I
CWorkbook
  P8 |" c$ d8 g2 |; BWorkbook.h
0 D5 C% m9 m) g1 o6 X8 V6 U单个工作簿。
# h: Y5 u+ w+ ~5 OWorksheets
' [2 ~; \9 M3 w7 F& A0 w3 WCWorksheets
0 c' _, K) s8 X9 nWorksheets.h$ \0 [' Z3 A4 ~1 L. H7 }& {
单个工作簿中的Sheet表格的容器,包括该工作簿中的所有Sheet。
. \4 e/ x* T, \# m1 t' Q_Worksheet+ c; U, C, l2 ]6 O6 H
CWorksheet
0 R7 @0 `  _9 Y! d1 `7 o6 Y# @+ qWorksheet.h
) W* K. q6 B7 ^, C* ?单个Sheet表格。
8 j" D( M  A& P; J+ CRange! |! Y0 B/ @) \( m$ ?& ~
CRange9 `+ |1 Y, u- U/ K" L  V2 |
Range.h
  ^% `2 `) c4 M9 X& B4 {一定数量的单元格,可对单元格进行单个或多个单元格进行操作。
% S7 t1 `- w- g1 o  - @" J# S& {7 N' v0 O
3、导入Excel的整个类型库5 B! ], t. W+ A3 Z
接口对应类只是对接口的属性和方法进行了封装,而Excel中的数据类型,如枚举类型却并为并不能使用,因此,为了更方便的操作Excel,还需要导入Excel的数据类型。
1 \0 J* }1 q4 z1 Q0 J. `. W通过查看导入接口对应的头文件可以发现,在所有导入接口的头文件中,都会有这么行:
! {% v7 z/ {, k. `( ]#import "D:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE" no_namespace# e" b0 ^, x- b' |" X
这行代码的作用是导入Excel整个类型库到工程中。
/ a9 i6 p9 w, @1 L由VS2010自动产生的导入代码存在以下几个问题:
+ h) u1 f7 P2 d(1)如果导入了多个接口,每个头文件都会把类型库导入一次,如果引用多个头文件,会导致类型库重复导入。) W% N) `4 Z2 O6 t! s( j4 w: ]
(2)Excel类型库中有些类型会跟MFC类库的某些类型冲突。& S/ z- ^1 X$ i. c' w
(3)Excel类型库的某些类型跟其他Office和VB的某些库相关,如果不导入相关库,将导致这些类型无法使用。。1 H) I* I; w4 W! x: O# g
以上三点问题的解决方法如下:' f3 r8 |* A3 y- [, W
(1)仅在_Application接口对应头文件中导入Excel类型库。7 J( N; z/ R) C+ _& |5 b3 q7 V1 f
(2)对冲突的类型进行重命名。
! }) Z( @  g: `- ]! u8 A; M0 u4 @3 t(3)在导入Excel类型库之前,先导入Office和VB的相关库。
" d3 Z$ U4 {) C' t5 ]7 u0 {5 o更改后的导入类型库的代码如下:
5 {0 \) g; ?* m8 c  2 _# s, `5 e" t  g
/*导入Office的类型库*/  t6 b0 [7 k7 g' R, I
#import "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE12\\MSO.DLL" \0 R8 C6 U- ?6 O# r# ?
rename("RGB", "MSORGB") \. D/ n7 Z2 V( {) M, l# l3 I2 r
rename("DocumentProperties", "MSODocumentProperties")- N& [' r( g3 g2 I/ q" B& j- h
using namespace Office;  r+ B9 }' d- c1 |8 S# M' U1 Z
  ' ?' T( ~+ k( ]* K. R' }
/*导入VB的类型库*/
3 |* n" ?+ F* {1 u5 H* o- a: _#import "C:\\Program Files\\Common Files\\Microsoft Shared\\VBA\\VBA6\\VBE6EXT.OLB"
" M9 L& s3 d( I) M  ^6 ~% e$ tusing namespace VBIDE;
& o9 ?, s8 Q1 R" [; ~% H; l- A  + v; L' }5 }% ?# T9 t# ], G
/*导入Excel的类型库*/( O8 V& e8 `2 r& l( P6 P7 z
#import "D:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE" \) j1 [4 A+ V8 u' B: P! W
rename("DialogBox", "ExcelDialogBox") \, S2 ~+ t# f) a% j
rename("RGB", "ExcelRGB") \: |# C# [& x7 Y1 l. S
rename("CopyFile", "ExcelCopyFile") \* ?" N2 K) n( U: Z8 l* @
rename("ReplaceText", "ExcelReplaceText") \
/ @6 I% h( S  K, nno_auto_exclude: {- E' P- ^3 D. m6 _
Using namespace Excel;
5 c, `! j) \. @+ o  ~8 O  ! U9 P. B+ j$ h6 y7 L4 @
编译程序后,会在DebUG或Release目录下生成三个文件mso.tlh、vbe6ext.tlh和excel.tlh。通过打开文件可知,该三个文件的命名空间分别是Office、VBIDE和Excel。导入了Excel的整个类型库后,就可以使用Excel中的所有类型了。0 q  A2 |9 O- o' l+ z
  
- E# v2 T% v7 K6 e- x' ~, q# Z9 V4、操作Excel步骤* P0 F3 q# ^0 d) b* L
操作Excel的主要步骤如下:
8 b- d4 Q# Q7 K(1)创建一个Excel应用程序。0 w: B5 w0 b3 t7 B8 P% m
(2)得到Workbook的容器。
+ O* I& I" x! J, F3 b(3)打开一个Workbook或者创建一个Workbook。
# N$ s: \/ R9 H3 }" m4 y$ A/ R(4)得到Workbook中的Worksheet的容器。  D# B5 y: u. g+ H# n: @
(5)打开一个Worksheet或者创建一个WorkSheet。
; ]% I- a5 u) S- E* C4 n! a# U% Y; i(6)通过Range对WorkSheet中的单元格进行读写操作。
0 P1 z& G) d. w- t(7)保存Excel。
% X: Q1 Z; u$ o& z! G(8)释放资源。
! ^$ o; k; r3 k  ( Q  J8 X) ], J6 D) R2 y, S
5、批量处理Excel表格
$ m4 @1 L  Z2 y0 N7 X0 ~, GVC通过OLE/COM操作Excel,是通过进程间的组件技术。因此,每次读写Excel中的单元格时,都要进行进程间的切换。当数据量大,如果一个单元格一个单元格的读取,主要的时间都花费在进程切换中。因此读取多个单元格,将可有效的提高程序的运行效率。+ H2 B5 R3 Y, g2 {% Q
对多个单元格的读写操作可以通过CRange中以下两个成员函数来完成。3 E# u8 k  U" q4 x+ Q5 D6 T0 Q
VARIANT get_Value2();
, `: q( K7 R1 e+ o9 m% qvoid put_Value2(VARIANT& newValue);
0 [, f' F( O: v0 W. ~0 C1 E! H其中,输入参数newValue只要输入一个二维数组,即可实现向Excel中一次写入多个单元格的值。+ x1 O* n( ?# |% O1 ]
其中,VARIANT中实现二维数据的方法可参考
7 Y3 \& [% s) t1 W' u( r, Q+ Yhttp://www.cnblogs.com/xianyunhe/archive/2011/09/13/2174703.html# Z% ~) N' L2 S+ Y4 O: }$ k7 j
当然,在对CRange类进行操作之前,要设置CRange类对应的单元格。+ l1 U; j! A7 x
  # @/ }7 M6 h' w$ r+ J: V8 u) l5 s, C- N
6、Excel表格的保存
- f6 r: `4 h5 L+ l# H; i8 F(1)如果要保存打开的工作簿,使用CWorkbook类的Save函数就可以保存工作簿,原文件将被覆盖。! g" d+ M8 t5 y. G( A
(2)如果是新创建的工作簿,或者是要另存为,可使用CWorkbook类的SaveAs函数。7 c9 Q4 n, ?3 N8 a8 o8 o
SaveAs的参数比较多。其中,第1个参数是设置要保存文件的路径;第2个参数是设置文件的格式,可在MSDN中查看枚举类型XlFileFormat来了解Excel的文件格式。经过测试,在本文所用的测试环境中,Excel2003的文件格式是xlExcel8,Excel2007的文件格式是xlExcel4。( N; q: x# c# p, U  `
  
9 _' f# t3 P8 R* [; N7、获取当前Excel的版本: @6 w: H/ e9 v# B
可以通过CApplication的get_Version函数来获得Excel的版本,其中,Excel2007的主版本号是12,Excel2003的主版本号是11。
+ M; ^9 _: u! p: U  
# [7 s) U; x0 E; `1 L! {; \- R8、示例源代码) h1 z) p8 w7 U/ V2 E. R; G
主要代码如下:3 j$ V6 _4 t, t( c+ }
  * g5 J. ~8 y3 ?

% o, v; f6 V$ Q  T. R! a- \
2 a' ]( e( r- x1 [    m_LisTCtrl.SetExtendedStyle(LVS_REPORT | LVS_EX_FULLROWSELECT);
$ d3 s: Z+ h2 ~* X  @2 B( p5 A. }2 p$ Y, m0 |
    CApplication ExcelApp;
, g& t/ N/ r. g, [4 I    CWorkbooks books;
! I% E# _6 L7 \$ o4 X2 b    CWorkbook book;# s3 `/ t8 ?, Z# Q2 ^3 `
    CWorksheets sheets;
  N5 e( z* Y1 d    CWorksheet sheet;
6 e/ _6 M3 Z8 U+ |; }1 H& h* m    CRange range;
- V9 }1 m% _% ^6 X# f    LPDISPATCH lpDisp = NULL;
7 j" D" w" S+ e; T1 A$ S" q" @7 U7 @8 L& T5 F  w8 e
    //创建Excel 服务器(启动Excel)
  D. V9 ]# z# Y- E+ s" r* ~    if(!ExcelApp.CreateDispatch(_T("Excel.Application"),NULL)): p0 I: `/ p: X2 W
    {: F+ \6 U/ o5 l! D2 b5 i
        AfxMessageBox(_T("启动Excel服务器失败!"));1 L; S3 `: G% ]  R9 x* L
        return -1;
' W# _0 B: E! z4 ?    }
1 h4 V7 }& l( R* @6 R7 X  N
0 E) l" c1 m3 T5 {$ T+ i  k    /*判断当前Excel的版本*/; F* \( i& |& `' ^* s# S( r6 P
    CString strExcelVersion = ExcelApp.get_Version();, q) w) a* q0 p" S# y; [
    int iStart = 0;
- K5 {: ?/ z' z- k    strExcelVersion = strExcelVersion.Tokenize(_T("."), iStart);
$ Z5 M5 `/ [" N/ ^$ E- Z- }& q    if (_T("11") == strExcelVersion)
7 \: Z$ {$ j6 u2 a# A1 y) z( |3 ]6 |, a    {
$ e; a2 }8 H- ]        AfxMessageBox(_T("当前Excel的版本是2003。"));
' X! D- y; }0 A; f% L  J" s    }$ C* A5 L0 n& d
    else if (_T("12") == strExcelVersion)) k4 g8 |7 r1 u; z0 @& [2 r6 `% y
    {
  B1 U  R, |- [+ \3 Q4 e3 ]! J0 S        AfxMessageBox(_T("当前Excel的版本是2007。"));
! J" z: Q+ x$ y    }4 t( u" }8 J% N2 K
    else
8 T! `; X1 }/ i1 l% @1 @. E    {
* D' D5 y8 N- I9 M: w/ r1 [        AfxMessageBox(_T("当前Excel的版本是其他版本。"));2 r; y9 N- c5 P
    }
5 B# y4 Z, V7 |
+ r) R3 h! s& g- {9 o  V! L! ?    ExcelApp.put_Visible(TRUE);& w6 l5 n$ L" G. U4 ?1 S
    ExcelApp.put_UserControl(FALSE);
4 O  F# S2 a1 @# A1 \! n
$ m% ]/ G/ V3 S' C- T- I4 _    /*得到工作簿容器*/4 z+ s& B& ?+ H; Q$ w
    books.AttachDispatch(ExcelApp.get_Workbooks());
2 t8 F1 _; q5 X" X2 l
! |7 n- o* C: z    /*打开一个工作簿,如不存在,则新增一个工作簿*/) }2 T+ E1 f. c. h; X
    CString strBookPath = _T("C:\\tmp.xls");' d) w3 a! R5 \3 ^5 n
    try- ~, _+ U2 T: l4 Z! I
    {
' K5 L' r; B. }' f9 N. M7 a& A        /*打开一个工作簿*/  A- j  S) P# x/ k$ y, P& N
        lpDisp = books.Open(strBookPath, % G+ z  ^1 w( m5 v
            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,* N' k" A- r8 _& ~
            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,
2 @# G, n' ~4 G            vtMissing, vtMissing, vtMissing, vtMissing);
3 @" B) H& G+ U/ S: A2 L2 r" \: h        book.AttachDispatch(lpDisp);
% S) g" o, B$ O$ L5 L7 b% g    }# y, J7 S, m5 N! j. C
    catch(...)
( O3 d$ [  L# P- u' ^    {
! ^# D0 I0 `7 P5 ?5 A7 M        /*增加一个新的工作簿*/
$ K/ A, I. `  K1 Y# {6 @        lpDisp = books.Add(vtMissing);
$ h* D1 m: t3 F, R) K        book.AttachDispatch(lpDisp);
6 M2 O# C' ~+ l+ |; T, `    }
; Y/ i. R# g7 p: _0 H     
" g/ m+ C% D( ?& w: {. E, c7 q# U* H+ s1 U6 u+ }" ]: t+ x
    /*得到工作簿中的Sheet的容器*/1 P5 |0 [" |  t4 v% t, g& \/ V) T  [
    sheets.AttachDispatch(book.get_Sheets());/ p# @  r! z0 a6 B

5 C/ [" N# D2 P/ ^* i. p    /*打开一个Sheet,如不存在,就新增一个Sheet*/9 r4 q& v% v8 M, ^; S2 g/ y* c
    CString strSheetName = _T("NewSheet");
" a4 l' ^  X7 I' j& Y    try5 X7 s( m2 c7 \0 b
    {
' W2 j! G' ], a( t3 ~- b9 o: B        /*打开一个已有的Sheet*// |# ^! B7 Q7 }- m" ^6 a9 F
        lpDisp = sheets.get_Item(_variant_t(strSheetName));
) ?: j  j1 {( f: O! x/ P        sheet.AttachDispatch(lpDisp);+ p6 V- p2 a% |6 C
    }
' R* b4 i7 G* `) S    catch(...)
; f; S4 C  {4 j6 S5 g4 g8 r/ T, f    {) t, A0 L: k. L2 |9 p% u' U
        /*创建一个新的Sheet*/* ?/ `" ]- W. p( o6 I; s8 B
        lpDisp = sheets.Add(vtMissing, vtMissing, _variant_t((long)1), vtMissing);
% H* w+ G+ g/ S" `$ V" O        sheet.AttachDispatch(lpDisp);
# X. H+ b" Y  e8 M        sheet.put_Name(strSheetName);
' m6 L7 V; g, o1 Y# w0 z/ B% G    }
& `5 n% J# ~) S6 [6 H' f/ B  S: a8 E# X, d: r1 D. t- U; C
    system("pause");
. W4 E. F  Q9 ]3 T$ Z6 u
6 x9 k/ P7 F7 o: h: {    /*向Sheet中写入多个单元格,规模为10*10 */3 \+ y6 Q/ m* @6 Q, @- x
    lpDisp = sheet.get_Range(_variant_t("A1"), _variant_t("J10"));9 L7 \: ~* [: Y8 _1 m* \
    range.AttachDispatch(lpDisp);
. w( k' Z- }1 ]; m4 u' Q0 g$ D' I) E$ O+ @9 X
    VARTYPE vt = VT_I4; /*数组元素的类型,long*/8 U  i/ m4 ?; Y( G* q$ w
    SAFEARRAYBOUND sabWrite[2]; /*用于定义数组的维数和下标的起始值*/# S% N3 Y5 r- `- e. ]" \8 e6 U
    sabWrite[0].cElements = 10;2 e+ V! ]( r8 V+ @! i, _
    sabWrite[0].lLbound = 0;
# @6 L5 l2 v: e    sabWrite[1].cElements = 10;
9 o7 v& l- ], U* B! B% \    sabWrite[1].lLbound = 0;
0 ~0 d) o, r" M3 A4 T9 D$ p9 t# G3 R$ g# n: n4 z8 t) V
    COleSafeArray olesaWrite;0 T; q0 ^) v3 D: E" Q4 X( U
    olesaWrite.Create(vt, sizeof(sabWrite)/sizeof(SAFEARRAYBOUND), sabWrite);3 g) b% p. _+ `1 A& b
3 O" C( C9 F/ L* g7 p
    /*通过指向数组的指针来对二维数组的元素进行间接赋值*/; x2 s' r* d0 \4 y
    long (*pArray)[2] = NULL;$ [9 @  g+ M$ b" J
    olesaWrite.AccessData((void **)&pArray);
/ h/ {$ V4 y0 W! P2 E+ G6 D* \    memset(pArray, 0, sabWrite[0].cElements * sabWrite[1].cElements * sizeof(long));
) [* j* Y+ |0 h2 P0 I! {
! i5 s% N3 L/ Y# N/ c, F    /*释放指向数组的指针*/: p4 d, J% H1 g
    olesaWrite.UnaccessData();- T" `/ v' m: M( F3 [1 e/ h
    pArray = NULL;
1 ?1 \; k! G" f  j8 |, Y! v
# q8 n( _8 ^' V    /*对二维数组的元素进行逐个赋值*/
( i- A! Q5 [: E# n* r* t    long index[2] = {0, 0};/ N/ G* |3 y/ a
    long lFirstLBound = 0;) }4 h. v1 `) v9 Q$ w  Y
    long lFirstUBound = 0;
3 C( _8 M& y5 |  s) s2 P1 t    long lSecondLBound = 0;
- ]6 s# f% D, J) s) e9 f" Q+ s/ a9 o    long lSecondUBound = 0;
6 P. @/ `' D  K9 `5 ~9 ~    olesaWrite.GetLBound(1, &lFirstLBound);
2 ]  H* [9 ]4 l& m) g) q    olesaWrite.GetUBound(1, &lFirstUBound);2 J8 ?2 t! O4 t! `9 I  D
    olesaWrite.GetLBound(2, &lSecondLBound);
' P' n) U/ |: H6 p    olesaWrite.GetUBound(2, &lSecondUBound);! s# A! O5 m) H4 B
    for (long i = lFirstLBound; i <= lFirstUBound; i++)
' S8 `9 s9 x* ?    {
# u# ^* ~$ H( \6 D, I        index[0] = i;+ n4 C0 g8 E1 d/ k
        for (long j = lSecondLBound; j <= lSecondUBound; j++)/ T/ K; \& h1 w/ A2 m. a: U
        {) v) H* E: a' b0 D# W  W
            index[1] = j;
+ a" u6 q1 h" D7 V- j$ B; E9 C7 r            long lElement = i * sabWrite[1].cElements + j;
  w2 y9 F7 L) w            olesaWrite.PutElement(index, &lElement);
7 y( }3 L6 ^' u, P$ Y$ x- F        }+ m5 f! n0 \% g* `4 U2 U6 L
    }' ]$ r0 {0 g. q! u( ^

5 x- t5 I0 z  S  l    /*把ColesaWritefeArray变量转换为VARIANT,并写入到Excel表格中*/- x1 }8 K; Y, k; J
    VARIANT varWrite = (VARIANT)olesaWrite;
" g' A+ I+ G$ S2 |, Q    range.put_Value2(varWrite);
$ z. s0 E2 |$ g. Z9 B+ d& w/ X( E  e: {9 b
    system("pause");3 _* h; ~( N' j! x+ d* b8 E: U  T

1 o# h5 C6 e3 Y- X7 J% m    /*根据文件的后缀名选择保存文件的格式*/
; o; w8 O2 b" m( C8 U: `: X     CString strSaveAsName = _T("C:\\new.xlsx");
6 [# A: c: V0 c  S' P9 Q2 C    CString strSuffix = strSaveAsName.Mid(strSaveAsName.ReverseFind(_T('.')));
, ?/ x; l$ e( ]# \( ?7 Y( u    XlFileFormat NewFileFormat = xlOpeNXMLWorkbook;
0 d+ c5 _% d  U: K; e- D7 M    if (0 == strSuffix.CompareNoCase(_T(".xls")))
1 g6 h; r7 W. E0 n    {
! i7 N# v1 j( x+ ~/ @        NewFileFormat = xlExcel8;/ V0 C6 V+ n& Q$ I, O) R" B
    }" v6 }+ E1 ]) B2 M; J6 {0 R
    book.SaveAs(_variant_t(strSaveAsName), _variant_t((long)NewFileFormat), vtMissing, vtMissing, vtMissing,
( v' M& T6 P- s% Q3 w' ~* ]; B        vtMissing, 0, vtMissing, vtMissing, vtMissing,
, ^* ]% m& J+ E. s+ w        vtMissing, vtMissing);
- }/ F9 q( n* }. b) P% h4 A7 Q, ^  O6 q4 M# k
    system("pause");
7 T* `8 d$ q; b6 J  i
- d* |! H9 ]$ j: z- @* I) {/ f    /*读取Excel表中的多个单元格的值,在listctrl中显示*/+ _  m7 L9 c* s1 l- j4 V3 o
    VARIANT varRead = range.get_Value2();
" z" c( I& ?2 Z# f+ ^; r: f    COleSafeArray olesaRead(varRead);
) j: D, \% e9 m' U7 X: b" ^* z" f4 K) C4 ^! D2 c$ z
    VARIANT varItem;, z* l8 `" C8 H+ q
    CString strItem;+ a/ l5 n/ G) d9 J) y& ]9 q: l: I
    lFirstLBound = 0;
' A/ I9 `6 X! d1 B! j5 S9 A    lFirstUBound = 0;
( k% b( c' @( y8 A    lSecondLBound = 0;; n- ^$ ^9 u9 k9 n, j
    lSecondUBound = 0;/ \. F% e& V% ]( ?  o
    olesaRead.GetLBound(1, &lFirstLBound);
& Z& P4 x- `  j* \. S    olesaRead.GetUBound(1, &lFirstUBound);2 ]; a, H& p" h# N( n# ]- o
    olesaRead.GetLBound(2, &lSecondLBound);+ Y8 u: m4 z, U% x& J  C) i& n
    olesaRead.GetUBound(2, &lSecondUBound);
6 W1 E- q" @/ n: E4 R5 X  W" ~    memset(index, 0, 2 * sizeof(long));
8 }. P" p. c6 z4 V    m_ListCtrl.InsertColumn(0, _T(""), 0, 100);
2 {# I5 X7 a# f3 R# |0 k    for (long j = lSecondLBound; j<= lSecondUBound; j++)
. A' D8 a: c+ K6 h    {, J% O0 I) E. p! v1 H, R, ^. z
        CString strColName = _T("");
0 P4 v' \+ [2 d8 Z1 a        strColName.Format(_T("%d"), j);! c, n. P7 z( j& I) `
        m_ListCtrl.InsertColumn(j, strColName, 0, 100);" b) P! G1 R  ~9 R6 l" e1 L
    }
! H: ]3 C" L$ G* X0 T( Q% ^$ N    for (long i = lFirstLBound; i <= lFirstUBound; i++)  x3 Z; V: i( i! C+ Q0 Q1 ]; h& V
    {
( J. k# N" w% M/ Z  C* o: {        CString strRowName = _T("");
8 i/ n( L8 @( Z. K0 N        strRowName.Format(_T("%d"), i);
' u8 W: D5 M0 g  e        m_ListCtrl.InsertItem(i-1, strRowName);- X! D' f2 P- M$ h5 L/ `5 U9 P3 S) I
. P' S* m2 _! {- {
        index[0] = i;
' n7 @; w: D* j0 F6 f! Y        for (long j = lSecondLBound; j <= lSecondUBound; j++)
9 u* J9 x$ O( F% t! x) n% n1 i        {1 L( b" u4 k6 }8 m
            index[1] = j;
" ~( y% f: ^0 U' u$ X$ O% [            olesaRead.GetElement(index, &varItem);) J. m; {9 ~) t3 q& S

; I" H4 L  H* h9 V            switch (varItem.vt): w5 @# E1 p6 O/ D) @# [' w
            {
1 S& b  m; H( }  _$ w3 `; \. q  L            case VT_R8:& r- A. E8 W& j3 g2 O: V+ H
                {; O9 l9 N: P. F9 ~. q7 P
                    strItem.Format(_T("%d"), (int)varItem.dblVal);  U; u$ ^2 n* {- d6 r2 `
                }2 X4 h+ z2 u% ?4 q
( Y' v1 e0 ]4 U; p* E5 [( j
            case VT_BSTR:. l. K3 R0 Z. R* @8 B; d. Y2 }( ~
                {6 K1 Z/ o6 A+ t0 p" y
                    strItem = varItem.bstrVal;" b/ R5 H  Y( K$ A8 V1 D  a
                }
3 z* r, t) {& ~; H$ f7 q, O0 y8 _/ J7 x% z
            case VT_I4:
" t; u! G) l$ T                {+ @" G' d. S( D2 \# B8 _% A8 T
                    strItem.Format(_T("%ld"), (int)varItem.lVal);3 M: K' q4 A. q2 b2 C. u; x0 C
                }
+ S# Q4 u& q, |% z/ \* M1 h( b
1 O9 g: w1 d$ Y8 W( M            default:+ _5 d" a0 W5 Q# k5 n9 Y
                {  G* i! H. g$ u/ r" @& ?
4 |/ L+ e& N* L* w) o
                }
9 |) h1 g( Z# W- p- u' C* R+ n4 U3 T            }
4 h; q( w! b+ c. J3 T% `/ e1 U  X  K* e, d" R
            m_ListCtrl.SetItemText(i-1, j, strItem);
4 K$ Q+ b+ v- ]* A4 R/ T        }
7 G$ D7 e$ l3 K6 K) U1 |1 Z0 m# z    }! U" y8 H+ P9 \8 I$ x
; U0 s( {! u. E. w- k

9 i: @+ P9 R! w2 m) D
( ~& K! f  |; N) S$ |: u    /*释放资源*/
; D( w# ^5 I. q& n4 A( y    sheet.ReleaseDispatch();5 E, L/ `2 W( H# B+ N+ z
    sheets.ReleaseDispatch();( y) E$ j& K0 X3 H3 d1 A7 |
    book.ReleaseDispatch();
, q6 h0 T% g1 `6 @    books.ReleaseDispatch();3 Y: Q7 m' y& m' |4 T  G% H; |
    ExcelApp.Quit();$ t% `& A- M$ z5 Z
    ExcelApp.ReleaseDispatch();
- \* X, t' S! C1 F2 R* y' V5 H9 B9 ]2 Z3 y$ G
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了