啰嗦一下:本人所在公司从事碟式斯特林太阳能发电设备的研发与销售。单台设备图如下:

  工作原理如下:整个设备大致可分为五个部分,

    1、服务器,负责气象、发电等数据存取,电、网连接等处理;

    2、气象站,通过光感应器实时获取气象数据,传送至服务器

    3、碟型镜面,反射阳光热量,均匀聚焦到350mm直径的圆形范围内——发动机热头大小;

    4、斯特林发动机,吸收镜面反射热量,通过内部气体膨胀、收缩带动发动机发电;

    5、通信线,连接系统各个部分,使其运行正常。

  对于这样一台设备,要使其高效发电,出气象条件要好之外,对每块镜片的最终安装位置要求极高。因为所有的支撑架子、镜片的形状、曲率等参数不可能做到一模一样,所以每台设备在镜片初步安装之后都必须进行精细的调整。具体技术问题这里暂不讨论。

  而对于一个电站,由几十或成百上千台碟子组成,除了镜片调试以外,还有一个重要的问题需要解决:所有碟子的布局。因为,若碟子之间的距离过小,会有遮挡,造成部分镜面没有阳光照射,发动机吸收热量减少,影响发电效率,严重的话会使其停止工作;而若距离过大,解决遮挡的同时,会造成整个电站面积过大,意味着通信线与土地的代价增加。因此,在这之间寻求一种折中的解决方案至关重要,做到尽量高效,低成本。

  针对斯特林碟式太阳能发电站的碟子位置布局问题,公司要求做一个软件,主要功能是分析历史电站的发电、气象、电价、布线等数据,并结合拟定的碟子布局模型,比较实际与模拟结果,选择最佳方案。

  回归正题:文件存储在Excel文件中,因此第一步是能够在程序中方便地读取表格数据,这里用的是VC6.0 MFC。

  1、电脑上安装VC6.0,Excel2007,其他Office版本亦可(WPS尽量避免);

  2、建立一个MFC基于对话框的应用程序工程,名称自己定,这里取名为"Solar",添加一个按钮、一个列表控件,分别取名为"Model2","List1",并为后者添加成员变量"m_ExcelData"。

  3、在程序入口处CXXXApp:: InitInstance()函数AfxEnableControlContainer();语句之后加入下面几行:

 if (CoInitialize(NULL) != )
{
AfxMessageBox(“初始化COM支持库失败!”);
exit();
}

假如这个条件不通过就不能运行起程序。在程序的出口处CSolarApp:: ExitInstance()函数return语句之前加入下面这句话:

 CoUninitialize();

来释放COM支持库,这样对COM库的支持就已完成。

  4、下面要从Office的安装目录中找到对VC操作excel文件的动态库,在某些版本下这个文件是Excel8.olb或Excel9.olb,在我的版本中是excel.exe这个exe也是动态库的形式,是微软公司主要的文件结果之一。选择VC的View(查看)菜单里面的类向导ClassWizad命令,会弹出一个对话框;然后点击Add Class…按钮选择From a type library,会弹出一个打开对话框,从这里打开Office安装目录下D:\Program Files\Microsoft Office\Office12\EXCEL.EXE文件,从里面选择几个要用到的类:_Application, Workbooks, _Wrokbook, Worksheets, _WorkSheet, Range,点击OK按钮。会在程序中生成一个excel.h和excel.cpp文件,这些文件中包含了刚才我们选择的几个类的代码。下面介绍一下这几个类:

  在VC操纵excel的exe动态库里面有好多个对象模型,就是刚才在创建过程中看到的那个列表,但是经常用到的有这么几个:_Application, Workbooks, _Wrokbook, Worksheets, _WorkSheet, Range,Charts和_Chart,最后面的两个是用来操作图表的,这里没有用到所以这里也就不记录了。

  1>_Application:这里的Application就是Excel本身,众所周知,一个Excel可以包含多个工作簿,每个工作簿又可以包含多个工作表,而每个工作表又可以包含多个区域或者图表,所以这里他们是树型的结构关系,而application最基本的一个功能就是找到它的子项工作簿。果然,我们在引入我们程序的Application类中看到了这样的成员函数:GetWorkbooks()。

  2> Workbooks:这个对象是一个容器对象,它里面存放着所有打开的工作簿。因此,我们可以猜测它一定有添加,查找,打开/关闭工作簿的功能。(本程序中使用excel的一个xlt模板来生成一个xls文件就是使用了这个容器对象的添加功能。)

  3> _Workbook:这是一个工作簿,也就相当于一个xls文件。Excel可以同时打开多个工作簿,所以工作簿之间必定能够互相切换,每个工作簿可以关联工作表容器并获得工作表的索引。

  4> Worksheets:也是一个容器对象,和Workbooks类似。

  5> _Worksheet:这个就是我们看到的工作表,比如Sheet1,sheet2等等。

  6> Rang:就是我们看到的能选中的方框的大小。而我们所要作的操作基本上是以区域为单位进行的。

  5、准备工作做好之后,接下来开始实现按钮功能:按下之后读取Excel表格数据,并显示在列表控件中。这里只是进行简单地显示,没有给出具体的处理过程及结果图像。目标Excel文件数据如下,行、列分别为30、9(包括序号)。

  在头文件"afxstd.h"中添加以下几个头文件(有些电脑环境可能不必全部加),注意别重复添加某些头文件。

 #include <comdef.h>
#include <comutil.h>
#include <OAIDL.H>
#include <afxdisp.h>
#include "excel.h"

  若编译报重定义错误,解决方法是在"excel.h"头文件中的头部添加:

 #if !defined _HEAD_FILE_EXCEL9_
#define _HEAD_FILE_EXCEL9_

  在其尾部添加:

#endif

  在对话框初始化函数BOOL CSolarDlg::OnInitDialog()中添加列表控件风格设置语句:

 m_Exceldata.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);

  OK,在函数BOOL CSolarDlg::OnModel2()中添加数据读取及显示代码:

   _Application m_oExcelApp;
Worksheets m_oWorkSheets;
_Worksheet m_oWorkSheet;
Workbooks m_oWorkBooks;
_Workbook m_oWorkBook;
Range m_oCurrRange;
if (!m_oExcelApp.CreateDispatch( _T( "Excel.Application" ), NULL ) )
{
::MessageBox( NULL, _T( "创建Excel服务失败!" ), _T( "错误提示!" ), MB_OK | MB_ICONERROR);
exit();
} //设置为显示
m_oExcelApp.SetVisible(FALSE);
m_oWorkBooks.AttachDispatch( m_oExcelApp.GetWorkbooks(), TRUE ); //没有这条语句,下面打开文件返回失败。 LPDISPATCH lpDisp = NULL;
COleVariant covTrue((short)TRUE);
COleVariant covFalse((short)FALSE);
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
Range oCurCell; CString FilePathName;
CFileDialog dlg(TRUE);///TRUE为OPEN对话框,FALSE为SAVE AS对话框
if(dlg.DoModal() == IDOK)
{
FilePathName = dlg.GetPathName();
/*
(1)GetPathName();取文件名全称,包括完整路径。取回C:\\WINDOWS\\TEST.EXE
(2)GetFileTitle();取回TEST
(3)GetFileName();取文件全名:TEST.EXE
(4)GetFileExt();取扩展名EXE
*/
}
else
{
AfxMessageBox("Open file opetation has been canceled.");
return;
} // 打开文件
lpDisp = m_oWorkBooks.Open( FilePathName,
_variant_t(vtMissing),
_variant_t(vtMissing),
_variant_t(vtMissing),
_variant_t(vtMissing),
_variant_t(vtMissing),
_variant_t(vtMissing),
_variant_t(vtMissing),
_variant_t(vtMissing),
_variant_t(vtMissing),
_variant_t(vtMissing),
_variant_t(vtMissing),
_variant_t(vtMissing),
_variant_t(vtMissing),
_variant_t(vtMissing) );
// 获得活动的WorkBook( 工作簿 )
m_oWorkBook.AttachDispatch( lpDisp, TRUE );
// 获得活动的WorkSheet( 工作表 )
m_oWorkSheet.AttachDispatch( m_oWorkBook.GetActiveSheet(), TRUE );
// 获得使用的区域Range( 区域 )
m_oCurrRange.AttachDispatch( m_oWorkSheet.GetUsedRange(), TRUE ); // 获得使用的行数
long lgUsedRowNum = ;
m_oCurrRange.AttachDispatch( m_oCurrRange.GetRows(), TRUE );
lgUsedRowNum = m_oCurrRange.GetCount();
// 获得使用的列数
long lgUsedColumnNum = ;
m_oCurrRange.AttachDispatch( m_oCurrRange.GetColumns(), TRUE );
lgUsedColumnNum = m_oCurrRange.GetCount();
// 读取Sheet的名称
CString strSheetName = m_oWorkSheet.GetName(); //得到全部Cells,此时,CurrRange是cells的集合
m_oCurrRange.AttachDispatch( m_oWorkSheet.GetCells(), TRUE ); // 更新列表控件数据
for ( int j = ; j < lgUsedColumnNum; ++j)
{
if(j == )
{
m_Exceldata.InsertColumn(j,"Index",LVCFMT_CENTER);
m_Exceldata.SetColumnWidth(j,);
continue;
}
oCurCell.AttachDispatch( m_oCurrRange.GetItem( COleVariant( (long)( + )), COleVariant( (long)j ) ).pdispVal, TRUE );
VARIANT varItemName = oCurCell.GetText();
strItemName = varItemName.bstrVal;
m_Exceldata.InsertColumn(j,strItemName,LVCFMT_CENTER);
m_Exceldata.SetColumnWidth(j,);
} for ( int i = ; i < lgUsedRowNum; ++i) //标题栏0+1行已经取出,从1+1开始获取数据到29+1
{
strItemName.Format("%d",i);
m_Exceldata.InsertItem(i-,strItemName);
m_Exceldata.SetItemText(i-,,strItemName);
for ( int j = ; j < lgUsedColumnNum; ++j) //1-8
{
oCurCell.AttachDispatch( m_oCurrRange.GetItem( COleVariant( (long)(i + )), COleVariant( (long)j ) ).pdispVal, TRUE );
VARIANT varItemName = oCurCell.GetText();
strItemName = varItemName.bstrVal; // 判断是否是合并的单元格
VARIANT varMerge = oCurCell.GetMergeCells();
if ( varMerge.boolVal == - )
{
AfxMessageBox( _T( "是合并的单元格!" ) );
}
else if ( varMerge.boolVal == )
{
AfxMessageBox( _T( "不是合并的单元格!" ) );
} m_Exceldata.SetItemText(i-,j,strItemName);
}
} // 关闭
m_oWorkBook.Close( covOptional, COleVariant( FilePathName ), covOptional );
m_oWorkBooks.Close();
// 释放
m_oCurrRange.ReleaseDispatch();
m_oWorkSheet.ReleaseDispatch();
m_oWorkSheets.ReleaseDispatch();
m_oWorkBook.ReleaseDispatch();
m_oWorkBooks.ReleaseDispatch();
m_oExcelApp.ReleaseDispatch();
m_oExcelApp.Quit(); // 这条语句是推出Excel程序,任务管理器中的EXCEL进程会自动结束

 

 代码中字符串变量strItemName是全局变量,在文件开头声明:

 CString strItemName = " ";

  须注意的是:

  1> 代码中79-92行是为列表添加属性列及名称,第一个属性序号("Index")是人为命名并添加,不是必须的;从第二个属性列开始为表格属性;

  2> 代码中23-39行是文件打开过程,选择Excel文件后,下面代码会根据完整文件名进行数据读取;

  3> 在VC数组及列表控件中,下标从0开始,而读取Excel表格数据时,索引从1开始。

 至此,简单的编程过程已完成,重新生成解决方案,编译、运行,结果如下:

VC6.0读取Excel文件数据的更多相关文章

  1. 上传读取Excel文件数据

    /// <summary> /// 上传读取Excel文件数据 /// 来自http://www.cnblogs.com/cielwater /// </summary> // ...

  2. 项目一:第四天 1、快递员的条件分页查询-noSession,条件查询 2、快递员删除(逻辑删除) 3、基于Apache POI实现批量导入区域数据 a)Jquery OCUpload上传文件插件使用 b)Apache POI读取excel文件数据

    1. 快递员的条件分页查询-noSession,条件查询 2. 快递员删除(逻辑删除) 3. 基于Apache POI实现批量导入区域数据 a) Jquery OCUpload上传文件插件使用 b) ...

  3. php phpexcel 读取excel文件数据

    public function readExcel(){ $allPath = '/home/examine\video/list.xls'; \think\Loader::import('exten ...

  4. VB6.0 读取Excel文件并返还数据集RecordSet

    读取Excel文件并返还数据集RecordSet 该方法适用于.xls,.xlsx类型的文件 读取Excel文件的Function: '取得数据集 Function getRecordSetForEx ...

  5. php读取Excel文件数据

    首先先下载 PHPExcel 脚本之家下载地址:https://www.jb51.net/codes/194070.html 然后把文件丢到php脚本同级目录里面 在php文件里面写下以下代码即可 & ...

  6. java读取excel文件数据导入mysql数据库

    这是我来公司的第二周的一个小学习任务,下面是实现过程: 1.建立maven工程(方便管理jar包) 在pom.xml导入 jxl,mysql-connector 依赖 可以在maven仓库搜索 2.建 ...

  7. ASP.NET中上传并读取Excel文件数据

    在CSDN中,经常有人问如何打开Excel数据库文件.本文通过一个简单的例子,实现读取Excel数据文件. 首先,创建一个Web应用程序项目,在Web页中添加一个DataGrid控件.一个文件控件和一 ...

  8. 使用poi读取Excel文件数据

    package com.haiyisoft.iecp.util; import java.io.File;import java.io.FileInputStream;import java.io.F ...

  9. 人生苦短_我用Python_openpyxl库读取Excel文件数据_008

    上图为读取的目标文件--------------------------------------------------------------------------------- # coding ...

随机推荐

  1. cocos2d-x之加法计算器

    bool HelloWorld::init() { if ( !Layer::init() ) { return false; } Size visibleSize = Director::getIn ...

  2. textarea文本简单样式编辑

    第一种方法采用替换:就是将文本域的换号符号\r\n,替换成其他符号,存入数据库,然后显示的时候再转换回来: //转换换行符$str=preg_replace("/\r\n|\r|\n/&qu ...

  3. Ubuntu14.04安装中文输入法以及解决Gedit中文乱码问题[转载]

    转载自:http://www.cnblogs.com/zhcncn/p/4032321.html 写在前面:解决gedit 在txt文件格式出现乱码的问题,在我自己的操作中是需要把系统设置成中文显示环 ...

  4. 非常全面的讲解Hosts文件

    很奇怪有很多人不知道Hosts是什么东西.在网络病毒日渐盛行的今天,认识Hosts其实是很有用的,因为有好多的网页木马都盯上了这个文件,而在很多时候,您只需打开这个文件做一个小小的修改,就完全可以解决 ...

  5. Linux上Eclipse项目右键菜单没有Maven

    在Centos 7上安装了eclipse以后,着实很兴奋.eclipse luna版本自带maven.但是用mvn eclipse:eclipse创建的java工程,在右键菜单居然没有Maven按钮, ...

  6. List与Set的使用

    接口Collection: Collection是Java的一个集合框架, 也是一个根接口.JDK中没有提供此接口的任何实现,但是提供了更具体的子接口Set和List接口的实现,所有的Collecti ...

  7. TestNG之参数化

    TestNG提供了两种参数化的方式,一种是通过XML,一种是通过代码实现,下面对这两种方式做介绍. 一.通过xml /** * <suite name="Suite" par ...

  8. 2014 Super Training #6 A Alice and Bob --SG函数

    原题: ZOJ 3666 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3666 博弈问题. 题意:给你1~N个位置,N是最 ...

  9. POJ 2449 Remmarguts' Date --K短路

    题意就是要求第K短的路的长度(S->T). 对于K短路,朴素想法是bfs,使用优先队列从源点s进行bfs,当第K次遍历到T的时候,就是K短路的长度. 但是这种方法效率太低,会扩展出很多状态,所以 ...

  10. iOS程序间调用

    1.在被调用应用内的info.plist里面设置如下: 鼠标右击information property list ,然后从列表中选择URL types 右击 add row 添加一个对象(item) ...