使用ADO写Excel,Excel默认长度修改【版主去哪里了?大牛去哪里了?】

零度的折翅 2014-09-23 02:32:43
下面是使用ado方式写的excel。如果我输入的字符长度大于255时,就会报错,说 “字段太小而不能接受所要添加的数据的数量。试着插入或粘贴较少的数据, IDispatch error #3105”。
请问各位大侠,如何可以将写入的数据长度修改了,可以录入大于255长度的数据。谢谢。

#include <iostream>
#include <sstream>
#include <fstream>
#include <time.h>
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" no_namespace rename("EOF", "adoEOF") rename("BOF", "adoBOF")

const int writeRows = 50;

inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};

std::string makeConnStr(std::string filename, bool header = true)
{
std::stringstream stream;

std::string hdr = header ? "YES" : "NO";

if(!filename.empty())
if(*--filename.end() == 'x')
stream << "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" << filename << ";Extended Properties=\"Excel 12.0 Xml;HDR=" << hdr << "\"";
else
stream << "Provider='Microsoft.JET.OLEDB.4.0';Data Source=" << filename << ";Extended Properties=\"Excel 8.0;HDR=" << hdr << "\"";

return stream.str();
}

void write(std::string filename)
{
if(FAILED(::CoInitialize(NULL))) return;

_ConnectionPtr pCon = NULL;
_CommandPtr pCmd = NULL;
_RecordsetPtr pRec = NULL;

try
{
_bstr_t connStr(makeConnStr(filename).c_str());

TESTHR(pCon.CreateInstance(__uuidof(Connection)));
TESTHR(pCon->Open(connStr, "", "", NULL));

TESTHR(pCmd.CreateInstance(__uuidof(Command)));
pCmd->ActiveConnection = pCon;
pCmd->CommandText = "CREATE TABLE MySheet(A int, B varchar, C int, D int, E int, F int, G int, H int, I int, J varchar)";
pCmd->Execute(NULL, NULL, adCmdText);

TESTHR(pRec.CreateInstance(__uuidof(Recordset)));
pRec->Open("SELECT * FROM MySheet", _variant_t((IDispatch*)pCon), adOpenKeyset, adLockOptimistic, adCmdText);

for(int i = 0; i < writeRows; ++i)
{
TESTHR(pRec->AddNew());

char str[11] = {0}; for(int j = 0; j < 10; ++j) str[j] = 'a' + (rand() % 26);
char mytest[] = "abcdefghigklmnopqrstuvwxyz1abcdefghigklmnopqrstuvwxyz2abcdefghigklmnopqrstuvwxyz3abcdefghigklmnopqrstuvwxyz4abcdefghigklmnopqrstuvwxyz5abcdefghigklmnopqrstuvwxyz6abcdefghigklmnopqrstuvwxyz7abcdefghigklmnopqrstuvwxyz8abcdefghigklmnopqrstuvwxyz9abcdefghigklmnopqrstuvwxyz10abcdefghigklmnopqrstuvwxyz11abcdefghigklmnopqrstuvwxyz12";

pRec->Fields->GetItem("A")->Value = _variant_t(i);
pRec->Fields->GetItem("B")->Value = _variant_t(str);
pRec->Fields->GetItem("C")->Value = _variant_t(i);
pRec->Fields->GetItem("D")->Value = _variant_t(i);
pRec->Fields->GetItem("E")->Value = _variant_t(i);
pRec->Fields->GetItem("F")->Value = _variant_t(i);
pRec->Fields->GetItem("G")->Value = _variant_t(i);
pRec->Fields->GetItem("H")->Value = _variant_t(i);
pRec->Fields->GetItem("I")->Value = _variant_t(i);
pRec->Fields->GetItem("J")->Value = _variant_t(str);
//pRec->Fields->GetItem("J")->Value = _variant_t(mytest);
}
TESTHR(pRec->Update());
TESTHR(pRec->Close());
}
catch(_com_error &e)
{
_bstr_t bstrDescription(e.Description());
CharToOem(bstrDescription, bstrDescription);
std::cout << bstrDescription << std::endl;
}

if(pCon != 0 && pCon->State == adStateOpen) pCon->Close();
::CoUninitialize();

}

int main()
{
write("data.xls"); // writing data.xls
system("pause");
}

...全文
651 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
零度的折翅 2014-09-30
  • 打赏
  • 举报
回复
引用 9 楼 cjzzmdn 的回复:
我觉得这样可以。建表时字段类型为memo msdn应该有这些
_RecordsetPtr  m_pRecordset;
	char mytest[] = "abcdefghigklmnopqrstuvwxyz1abcdefghigklmnopqrstuvwxyz2abcdefghigklmnopqrstuvwxyz3abcdefghigklmnopqrstuvwxyz4abcdefghigklmnopqrstuvwxyz5abcdefghigklmnopqrstuvwxyz6abcdefghigklmnopqrstuvwxyz7abcdefghigklmnopqrstuvwxyz8abcdefghigklmnopqrstuvwxyz9abcdefghigklmnopqrstuvwxyz10abcdefghigklmnopqrstuvwxyz11abcdefghigklmnopqrstuvwxyz12";
	try {
		m_pConnection->Execute("CREATE TABLE test1111 ([0] MEMO,[1] MEMO,[2] CURRENCY,[3] MEMO,[4] MEMO,[5] MEMO,[6] CURRENCY)",NULL,adCmdText);
		ConnectDB();
		m_pRecordset.CreateInstance(__uuidof(Recordset));
		m_pRecordset->Open("[test1111$]",m_pConnection.GetInterfacePtr(), // 获取库接库的IDispatch指针
			adOpenStatic,//adOpenDynamic,adOpenKeyset
			adLockPessimistic,
			adCmdTable);
		for (int i=0;i<10;i++)
		{
			m_pRecordset->AddNew();
			m_pRecordset->Fields->GetItem("0")->Value = mytest;
		}
谢谢。 非常感谢。
零度的折翅 2014-09-30
  • 打赏
  • 举报
回复
引用 8 楼 zhaowech 的回复:
[quote=引用 6 楼 huoqingna2332 的回复:] [quote=引用 3 楼 zhao4zhong1 的回复:] 可能是Excel的限制。
Excel可以直接输入大于255的字符,而且使用外部导入数据,数据源也可以大于255的限制。所以我怀疑,就是Ado连接的时候有一个默认的最大长度255,但是我就是没有找到。[/quote] 调试了,仔细想了想,我也帮你调试了下,任何一方都没有问题,总结如下: 1.发生这个错误是因为字段默认的大小为255,因此写入大于255引起异常是合理的 2.要想写入更多的数据,需要修改字段的定义大小,具体为 FieldPtr pFd=pRec->Fields->GetItem("J"); pFd->DefinedSize=512; 上面得到了你所想写入的J位置的指针,然后查看DefinedSize,刚好是255,修改为512(只要比要写入大就oK),这样写入就不会就问题了。但是,直接修改会提示,对象打开时无法修改,这里怎么改,我就不多说了。总之,问题到这儿都好解决了。 3.至于为什么Excel不会报错,很明显了,Excel对会事先判断输入数据是否大于当前字段可填充数据上限,如果会,那么它会提升上限,这个过程用户是察觉不到的,而个人程序,就不一样了。 [/quote] 感谢,非常感谢。
cjzzmdn 2014-09-29
  • 打赏
  • 举报
回复
我觉得这样可以。建表时字段类型为memo msdn应该有这些
_RecordsetPtr  m_pRecordset;
	char mytest[] = "abcdefghigklmnopqrstuvwxyz1abcdefghigklmnopqrstuvwxyz2abcdefghigklmnopqrstuvwxyz3abcdefghigklmnopqrstuvwxyz4abcdefghigklmnopqrstuvwxyz5abcdefghigklmnopqrstuvwxyz6abcdefghigklmnopqrstuvwxyz7abcdefghigklmnopqrstuvwxyz8abcdefghigklmnopqrstuvwxyz9abcdefghigklmnopqrstuvwxyz10abcdefghigklmnopqrstuvwxyz11abcdefghigklmnopqrstuvwxyz12";
	try {
		m_pConnection->Execute("CREATE TABLE test1111 ([0] MEMO,[1] MEMO,[2] CURRENCY,[3] MEMO,[4] MEMO,[5] MEMO,[6] CURRENCY)",NULL,adCmdText);
		ConnectDB();
		m_pRecordset.CreateInstance(__uuidof(Recordset));
		m_pRecordset->Open("[test1111$]",m_pConnection.GetInterfacePtr(), // 获取库接库的IDispatch指针
			adOpenStatic,//adOpenDynamic,adOpenKeyset
			adLockPessimistic,
			adCmdTable);
		for (int i=0;i<10;i++)
		{
			m_pRecordset->AddNew();
			m_pRecordset->Fields->GetItem("0")->Value = mytest;
		}
孤影品茗 2014-09-28
  • 打赏
  • 举报
回复
引用 6 楼 huoqingna2332 的回复:
[quote=引用 3 楼 zhao4zhong1 的回复:] 可能是Excel的限制。
Excel可以直接输入大于255的字符,而且使用外部导入数据,数据源也可以大于255的限制。所以我怀疑,就是Ado连接的时候有一个默认的最大长度255,但是我就是没有找到。[/quote] 调试了,仔细想了想,我也帮你调试了下,任何一方都没有问题,总结如下: 1.发生这个错误是因为字段默认的大小为255,因此写入大于255引起异常是合理的 2.要想写入更多的数据,需要修改字段的定义大小,具体为 FieldPtr pFd=pRec->Fields->GetItem("J"); pFd->DefinedSize=512; 上面得到了你所想写入的J位置的指针,然后查看DefinedSize,刚好是255,修改为512(只要比要写入大就oK),这样写入就不会就问题了。但是,直接修改会提示,对象打开时无法修改,这里怎么改,我就不多说了。总之,问题到这儿都好解决了。 3.至于为什么Excel不会报错,很明显了,Excel对会事先判断输入数据是否大于当前字段可填充数据上限,如果会,那么它会提升上限,这个过程用户是察觉不到的,而个人程序,就不一样了。
零度的折翅 2014-09-28
  • 打赏
  • 举报
回复
引用 2 楼 qq_20151837 的回复:
没做过,懂不起。 upup,增加人气!!!
哈哈。 谢谢。
零度的折翅 2014-09-28
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
可能是Excel的限制。
Excel可以直接输入大于255的字符,而且使用外部导入数据,数据源也可以大于255的限制。所以我怀疑,就是Ado连接的时候有一个默认的最大长度255,但是我就是没有找到。
零度的折翅 2014-09-28
  • 打赏
  • 举报
回复
引用 4 楼 zhaowech 的回复:
ADO用的COM,如果是COM组件内部的限制,要解除限制还是很麻烦的 我试了下,你这段代码,没有报错 如何复现错误???
这两天比较忙,不好意思,才看到。 把需要写入的字符串大于255,错误就会出现。 我尝试的修改create table语句,直接将最大长度突破255,结果直接create报错,郁闷。

for(int i = 0; i < writeRows; ++i)
        {
            TESTHR(pRec->AddNew());
 
            char str[11] = {0}; for(int j = 0; j < 10; ++j) str[j] = 'a' + (rand() % 26);
            char mytest[] = "abcdefghigklmnopqrstuvwxyz1abcdefghigklmnopqrstuvwxyz2abcdefghigklmnopqrstuvwxyz3abcdefghigklmnopqrstuvwxyz4abcdefghigklmnopqrstuvwxyz5abcdefghigklmnopqrstuvwxyz6abcdefghigklmnopqrstuvwxyz7abcdefghigklmnopqrstuvwxyz8abcdefghigklmnopqrstuvwxyz9abcdefghigklmnopqrstuvwxyz10abcdefghigklmnopqrstuvwxyz11abcdefghigklmnopqrstuvwxyz12";
 
            pRec->Fields->GetItem("A")->Value = _variant_t(i);   
            pRec->Fields->GetItem("B")->Value = _variant_t(str);  
            pRec->Fields->GetItem("C")->Value = _variant_t(i);
            pRec->Fields->GetItem("D")->Value = _variant_t(i);
            pRec->Fields->GetItem("E")->Value = _variant_t(i);
            pRec->Fields->GetItem("F")->Value = _variant_t(i);
            pRec->Fields->GetItem("G")->Value = _variant_t(i);
            pRec->Fields->GetItem("H")->Value = _variant_t(i);
            pRec->Fields->GetItem("I")->Value = _variant_t(i);
           // pRec->Fields->GetItem("J")->Value = _variant_t(str);     
            pRec->Fields->GetItem("J")->Value = _variant_t(mytest);        
        }
孤影品茗 2014-09-26
  • 打赏
  • 举报
回复
ADO用的COM,如果是COM组件内部的限制,要解除限制还是很麻烦的 我试了下,你这段代码,没有报错 如何复现错误???
赵4老师 2014-09-26
  • 打赏
  • 举报
回复
可能是Excel的限制。
qq_20151837 2014-09-26
  • 打赏
  • 举报
回复
没做过,懂不起。 upup,增加人气!!!
零度的折翅 2014-09-25
  • 打赏
  • 举报
回复
咋就没有人来呢!

3,882

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧