您好,欢迎访问三七文档
当前位置:首页 > IT计算机/网络 > 数据库 > odbc与excel
CDatabasedatabase;CStringsSql;CStringsItem1,sItem2,sItem3;CStringsDriver;CStringsDsn;CStringsFile,sPath;CDBVariantvarValue;//获取主程序所在路径,存在sPath中GetModuleFileName(NULL,sPath.GetBufferSetLength(MAX_PATH+1),MAX_PATH);sPath.ReleaseBuffer();intnPos;nPos=sPath.ReverseFind('\\');sPath=sPath.Left(nPos);sFile=sPath+file://Demo.xls/;//将被读取的Excel文件名//检索是否安装有Excel驱动MicrosoftExcelDriver(*.xls)sDriver=GetExcelDriver();if(sDriver.IsEmpty()){//没有发现Excel驱动AfxMessageBox(没有安装Excel驱动!);return;}//创建进行存取的字符串sDsn.Format(ODBC;DRIVER={%s};DSN='';DBQ=%s,sDriver,sFile);TRY{//打开数据库(既Excel文件)database.Open(NULL,false,false,sDsn);CRecordsetrecset(&database);//设置读取的查询语句.注意此处表名的写法,excel里的表默认为系统表所以访问表时表名应为[表名$]sSql=SELECT考生编号,考生姓名,来源FROM[student2$]ORDERBY考生编号;//执行查询语句recset.Open(CRecordset::forwardOnly,sSql,CRecordset::readOnly);//获取查询结果while(!recset.IsEOF()){//读取Excel内部数值recset.GetFieldValue(考生编号,sItem1);recset.GetFieldValue(考生姓名,sItem2);recset.GetFieldValue(来源,sItem3);//显示记取的内容m_ExcelList.AddString(sItem1+--+sItem2);//移到下一行recset.MoveNext();}//关闭数据库database.Close();}CATCH(CDBException,e){//数据库操作产生异常时...AfxMessageBox(数据库错误:+e-m_strError);}END_CATCH;}注意问题:1、如excel表中某列既有数字又有字母等数据类型不一致时,读入为某一类型(如CString类型)时,会出一些异常情况,要先判断读入是什么类型,再进行处理。如:CDBVariantvarValue;recset.GetFieldValue(天线方向,varValue);switch(varValue.m_dwType){caseDBVT_DOUBLE:direction.Format(%.5f,varValue.m_dblVal);break;caseDBVT_LONG:direction.Format(%ld,varValue.m_lVal);break;caseDBVT_STRING:direction=varValue.m_pstring-GetBuffer(6);break;}CDBVariant类成员数据成员m_dwType包含当前存储值的数据类型。DWORD型m_boolVal包含一个BOOL型值m_chVal包含一个unsignedchar型值m_iVal包含一个short型值m_lVal包含一个long型值m_fltVal包含一个float型值m_dblVal包含一个double型值m_pdate包含指向TIMESTAMP_STRUCT型对象的指针m_pstring包含一个CString型值m_pbinary包含一个CLongBinary型值CDBVariant::m_dwType说明:这个数据成员包含用于当前在CDBVariant对象的联合数据成员中存储的值的数据类型。访问这个联合之前必须检查m_dwType的值,以确定要访问哪个联合数据成员。下表列出m_dwType的可能值和相应的联合数据成员。m_dwType联合数据成员DBVT_NULL没有联合成员对访问有效DBVT_BOOLm_boolValDBVT_UCHARm_chValDBVT_SHORTm_iValDBVT_LONGm_lValDBVT_SINGLEm_fltValDBVT_DOUBLEm_dblValDBVT_DATEm_pdateDBVT_STRINGm_pstringDBVT_BINARYm_pbinary2、字段有空格时,用中括号括起来sSql=SELECTLAC,CI,[CELLID],基站名,MSC,BSC,LAC,CI,BSIC,BCCH,TCH信道数,天线方向,天线高度,天线下倾,longitude,latitude,基站地址,frequencyFROM[Exceldemo$];今天花时间研究了一下ADO操作Excel文件的问题,跟大家分享一下:首先利用Excel2003创建了一个名为Demo.xls的文件,内容如下:NameAgeTY12TZL15然后打开VC,创建一个命令行应用程序。然后如一般的ADO程序一样编写相应代码,只是注意打开数据库的代码如下写:m_pConnection-Open(Provider=Microsoft.Jet.OLEDB.4.0;DataSource=Demo.xls;ExtendedProperties=\Excel8.0;HDR=No;IMEX=1\,,,adModeUnknown);注意一下HDR,如果后面是No的话,表示ADO将不把你Excel文件的第一行作为字段名(此时使用默认字段名:F1,F2。。以此类推,当然也可以用(LPCTSTR)m_pRecordset-GetFields()-GetItem((_variant_t)zz)-Name之类的代码来获得相应的字段名)。否则如上Excel文件的字段名将是Name与Age。另外是IMEX,如果设置了IMEX=1;则通知驱动程序始终将“互混”(数字,日期,字符串等)数据列作为文本读取,同时这个选项有可能影响到excel表格拒绝写操作,也就是说,如果我们要求写入excel的话,这个选项不能被设置。接下来是打开记录集,代码如下(注意一下表名的写法):m_pRecordset-Open(select*from[Sheet1$],_variant_t((IDispatch*)m_pConnection,true),adOpenDynamic,adLockOptimistic,adCmdUnknown);知道了字段名,打开了数据库跟记录集,随后的操作就跟普通ADO的操作一样了:读取操作:while(!m_pRecordset-adoEOF){_variant_tvar=m_pRecordset-GetCollect(Name);if(var.vt!=VT_NULL)_bstr_tstrName=(LPCSTR)_bstr_t(var);var=m_pRecordset-GetCollect(Age);if(var.vt!=VT_NULL)_bstr_tstrAge=(LPCSTR)_bstr_t(var);stringstrMid=strName+--+strAge;coutstrMid.c_str()endl;m_pRecordset-MoveNext();}插入操作:m_pRecordset-AddNew();m_pRecordset-PutCollect(Name,_variant_t(zz));m_pRecordset-PutCollect(Age,_variant_t(23));m_pRecordset-Update();更新操作:m_pRecordset-MoveFirst();m_pRecordset-PutCollect(Name,_variant_t(zz));m_pRecordset-Update();删除操作:不支持!这也是感到很遗憾的地方。好在我们可以通过执行update[Sheet1$]setName=NULL,Age=NULLwhereName='zz'之类的SQL语句来实现类似功能。当然,你要知道的是,这一行并没有真正删除掉,所以通常在select的时候要进行一定的筛选,例如:select*from[Sheet1$]whereNameisnotNULL;其它注意事项:如果通过执行SQL语句的方法完成数据插入与更新操作,需要注意所有的字段,包括数字,都要按文本来处理,否则会报类型不正确的错误。问题内容:如何处理ODBC中EXCEL驱动读取EXCEL文件中字段长度大于255字符时出现的数据截断问题.原问题:CRecordset::GetFieldValue()如何完成获得大于255字符串的数据字段?原讨论链接:=5194713所属论坛:数据库审核组:VC/MFC提问者:chenhq解决者:handsomerun感谢:handsomerun关键字:VC/MFC数据库EXCEL,ODBC,数据截断答案:CRecordsetrs(&db);rs.Open(CRecordset::forwardOnly,_T(SELECT*FROMSomeTable));//CreateaCDBVariantobjectto//storefielddataCDBVariantvarValue;//Loopthroughtherecordset,//usingGetFieldValueand//GetODBCFieldCounttoretrieve//datainallcolumnsshortnFields=rs.GetODBCFieldCount();while(!rs.IsEOF()){for(shortindex=0;indexnFields;index++){rs.GetFieldValue(index,varValue);//在这里如果某个字符串字段的长度大于255,就只能获得前255个字符??//dosomethingwithvarValue}rs.MoveNext();}rs.Close();db.Close();如何解决问题?如果用DoFieldExchange()可以通过RFX_Text(pFX,_T([d7]),m_d7,1024);来获得大于255的字段数据!我现在的现象是:读取EXCEL文件时,如果字符串大于255的数据字段,如果数据记录号在25号以前,无论采用DoFieldExchange()方式读取还是GetFieldValue(column,m_stempSql)都是正确的,如果字段在25记录号以后,确都是错误的。现在只能怀疑ODBC的EXCEL驱动有问题了?大家同意吗?---------------------------------------------------------------这个看过吗,不知道对你有没有帮助谢谢handsomerun(毛毛)果然是EXCEL驱动问题,在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel中TypeGuessRows的数据是25,所以我的程序在读取前25行数据不存在数据截断的问题.如果将他设置为
本文标题:odbc与excel
链接地址:https://www.777doc.com/doc-2890060 .html