繁体   English   中英

Excel自动化在C ++ Builder XE7中不起作用

[英]Excel automation isn't working in C++Builder XE7

我正在尝试使用下面的代码从RAD Studio XE7中的C ++ Builder打开.xlsx文件:

#include "ComObj.hpp"

Variant Excel = CreateOleObject("Excel.Application");
Variant Books = Excel.OlePropertyGet("Workbooks");
Excel.OlePropertySet("Visible", true);
// An escape character is missing but the problem remains
Books.OleProcedure("Open", L"D:\1.xlsx"); // exception here

但是最后一行导致消息异常:

Project2.exe引发异常类EOleException并显示消息“很遗憾,我们无法找到文件TRUE.xlsx。 它可能已被移动,重命名或删除了?”。

屏幕与来源中断的地方

Delphi中的代码似乎可以正常工作:

uses ComObj;

var
  Excel, Books: Variant;
begin
    Excel := CreateOleObject('Excel.Application');
    Books := Excel.Workbooks;
    Excel.Visible := True;
    Books.Open('D:\1.xlsx'); // code passes
end;

有人知道解决方案吗?

Update1: VB中的以下代码也可以正常工作:

Sub Button1_Click()
 Dim xlApp As Excel.Application
 Dim xlBooks As Excel.Workbooks

 Set xlApp = CreateObject("Excel.Application")
 Set xlBooks = xlApp.Workbooks

 xlApp.Visible = True
 xlBooks.Open ("D:\1.xlsx")
End Sub

Update2:发送原始字符串文字会导致相同的exception

Books.OleProcedure("Open", uR"(D:\\1.xlsx)");

这似乎也不是环境问题。 我在几台计算机上测试了该示例,但没有任何效果。

在C ++中,反斜杠字符是字符串文字中的转义字符,因此需要对自身进行转义。 代替

L"D:\1.xlsx"

你需要写

L"D:\\1.xlsx"

错误消息是奇怪的。 几乎就像COM调度代码中的某些转换将1解释为真值并将其转换为文本一样。 您可以尝试将文件名作为System::WideString传递,这可以System::WideString该问题。

System::WideString filename = L"D:\\1.xlsx";
Books.OleProcedure("Open", filename);

您所报告的内容似乎太不可思议了! 我不得不承认,由于它太古怪,我很难相信它。

刚刚遇到了C ++ Builder XE7的类似问题,并认为我会分享发现的内容。 任何试图设置或发送任何类型的字符串文字的尝试都会导致Bad Variable Type错误,在Excel中像Dmitrii一样被设置为TRUE或导致内存错误。

我最终发现,C ++ Builder中存在一个OLEVariant类型,其中包含与OLE自动化兼容的数据类型,并且在运行时可以根据需要进行转换。

我首先尝试将所有Variant变量都更改为OLEVariant,但没有成功,但随后我可以对我发送的任何字符串使用强制类型转换,以使其正常工作,甚至是较旧的char字符串。 所以你可以尝试

Books.OleProcedure("Open", (OleVariant)L"D:\1.xlsx");

即使没有WideString格式,它也可以正常工作,所以也可以

Books.OleProcedure("Open", (OleVariant)"D:\1.xlsx");

至于转义,我不确定在第二种情况下是否需要使用简单的字符串来转义反斜杠。

该问题似乎与C ++的使用特别相关,因此与C ++编译器处理文字字符串(或至少是此特定C ++编译器)的方式有关。 在这种情况下,我无法说出问题的确切原因-甚至可能是编译器中的错误,因为(貌似)正确的转义无法解决问题。

您可以采用各种策略来消除在这种情况下处理文字字符串的可能性。 但是由于这确实涉及文字字符串,并且由于您使用的是XE7,我相信您应该能够通过将文字表示为原始字符串来更明确地绕过此字符串(按照C ++ 11,C ++ Builder应该支持XE7):

Books.OleProcedure("Open", uR"(D:\1.xlsx)"); // uR indicates UTF-16 Raw string

请注意,使用原始字符串文字时,您不会转义\\ char。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM