在C++Builder中使用OLE出现“类worksheet的paste方法无效”错误的一种解决方法

博客介绍了如何在C++Builder中通过OLE接口将数据库表和TStringList内容保存到Excel,以及利用剪贴板提高效率。作者在实现过程中遇到'类worksheet的paste方法无效'的错误,通过添加短暂延迟解决了问题。另外提到了保存为CSV文件作为快速生成Excel的替代方案,但无法创建多工作表。
摘要由CSDN通过智能技术生成

    在C++Builder中使用OLE的方式把数据库表中(TDBGrid)的内容保存到Excel的学习过程中,跟“ccrun(老妖) info@ccrun.com”学习了很多(致敬ccrun(老妖))。

    后来增加了把TStringList中的内容保存到Excel,重复向每个cell填充,这个方法的缺点是太慢。也可以一次填充一行(未实现)。下面是示意代码:

System::Variant vExcelApp;

System::Variant vSheet;
String strXlsFile;

        try
        {
            vExcelApp = System::Variant::CreateObject("Excel.Application");
        }
        catch (...)
        {
            MessageBox(0, "启动 Excel 出错, 可能是没有安装Excel.", "DBGrid2Excel", MB_OK | MB_ICONERROR);
            return true;
        }
        // 隐藏Excel界面
        // vExcelApp.OlePropertySet("Visible", false);
        vExcelApp.OlePropertySet("Visible", true);


vSheet = vExcelApp.OlePropertyGet("ActiveSheet");

TStringList *strList;

strList=new TStringList;

strList->Add("123");
strList->Add("abc");
AnsiString str;

str=strList->Strings[0];
vSheet.OlePropertyGet("Cells", 1, 1).OlePropertySet("Value", WideString(str));

str=strList->Strings[1];
vSheet.OlePropertyGet("Cells", 1, 2).OlePropertySet("Value", WideString(str));
delete strList;

        // 保存Excel文档并退出
        try
        {
            if (FileExists(strXlsFile)) // 如果文件存在,就删除
            {
                DeleteFile(strXlsFile.c_str());
            }
            /*
		 vExcelApp.OlePropertyGet("ActiveWorkbook").OleFunction("SaveAs",
		 WideString(lpXlsFile),
		 -4143, // FileFormat:=xlExcel8,
		 WideString(""), // Password:="",
		 WideString(""), // WriteResPassword:="", _
		 false, // ReadOnlyRecommended:=False,
		 false // CreateBackup:=False
		 );
		 */
            // FileFormat:=xlExcel8  ,Excel 97-2003格式文件
            vExcelApp.OlePropertyGet("ActiveWorkbook").OleFunction("SaveAs", WideString(strXlsFile).c_bstr(), -4143);
            vExcelApp.OleFunction("Quit");
            vExcelApp = Unassigned;
        }
        catch (...)
        {
            vExcelApp = Unassigned;
            return;
        }

    最近看到sprbreezeDelhpi利用剪贴板快速导出(复制)数据到excel_sprbreeze的专栏-CSDN博客)等人的相关文章,可以把用tab键间隔的TStringList内容拷贝到剪贴板后,再复制到excel中,速度要快很多,因此参考该方式,增加直接拷贝的方式把数据存到excel中,测试过程中,不定时不定点(有时卡在这里,下一个就可能在另外一个地方)出现“类worksheet的paste方法无效”的错误。后来猜测是不是excel还没有反应过来,于是在语句中增加Sleep(1000),休眠1秒(或者300毫秒等其他间隔),就不再出现该错误。

System::Variant vExcelApp;

System::Variant vSheet;

String strXlsFile;

        try
        {
            vExcelApp = System::Variant::CreateObject("Excel.Application");
        }
        catch (...)
        {
            MessageBox(0, "启动 Excel 出错, 可能是没有安装Excel.", "DBGrid2Excel", MB_OK | MB_ICONERROR);
            return true;
        }
        // 隐藏Excel界面
        // vExcelApp.OlePropertySet("Visible", false);
        vExcelApp.OlePropertySet("Visible", true);

TStringList *strList;

strList=new TStringList;

strList->Add("123 \t 456 \t 789");// 空格可以没有,用\t表示从输出tab
strList->Add("abc \t rt \t hj \t klp"); // 空格可以没有,用\t表示从输出tab

Clipboard()->Clear();
Clipboard()->AsText = saveCSV->Text;

vSheet = vExcelApp.OlePropertyGet("ActiveSheet");
vSheet.OleProcedure("Activate");
vSheet.OlePropertyGet("Cells", 1, 1).OleProcedure("Select");

// 没有这句,经常出现“类worksheet的paste方法无效”的错误
Sleep(300);  // 休眠300毫秒,或者1000毫秒

vSheet.OleFunction("Paste");
// vSheet.OleProcedure("Paste"); // 用这个函数也行

delete strList;

        // 保存Excel文档并退出
        try
        {
            if (FileExists(strXlsFile)) // 如果文件存在,就删除
            {
                DeleteFile(strXlsFile.c_str());
            }

            /*
		 vExcelApp.OlePropertyGet("ActiveWorkbook").OleFunction("SaveAs",
		 WideString(lpXlsFile),
		 -4143, // FileFormat:=xlExcel8,
		 WideString(""), // Password:="",
		 WideString(""), // WriteResPassword:="", _
		 false, // ReadOnlyRecommended:=False,
		 false // CreateBackup:=False
		 );
		 */
            // FileFormat:=xlExcel8  ,Excel 97-2003格式文件

            vExcelApp.OlePropertyGet("ActiveWorkbook").OleFunction("SaveAs", WideString(strXlsFile).c_bstr(), -4143);
            vExcelApp.OleFunction("Quit");
            vExcelApp = Unassigned;
        }
        catch (...)
        {
            vExcelApp = Unassigned;
            return;
        }

    当然,还有一种不用OLE的快速保存为excel文件的方法,就是保存为csv格式的文本文件,数据之间用逗号(,)间隔,这样用excel打开即可,缺点是不能分sheet保存为excel文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值