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

时间:2014-12-15 22:45:23

标签: excel delphi ole delphi-xe7 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文件。它可能已被移动,重命名或删除?'。

Screen with place where the source breaks

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)");

它似乎也不是一个环境问题。我在几台计算机上测试了这个例子并没有效果。

3 个答案:

答案 0 :(得分:2)

在C ++中,反斜杠字符是字符串文字中的转义字符,因此需要对其进行转义。而不是

L"D:\1.xlsx"

你需要写

L"D:\\1.xlsx"

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

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

你所报道的事情看起来似乎太奇怪了!我必须承认我在相信它时遇到了一些麻烦,因为它太古怪了。

答案 1 :(得分:1)

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

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

我首先尝试将所有Variant变量更改为OLEVariant但没有成功,但之后能够对我发送的任何字符串使用强制转换使其工作,甚至更旧的字符串。所以你可以试试

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

即使没有WideString格式,它也适用于我正在做的事情,所以这可能也可以正常工作

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

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

答案 2 :(得分:0)

问题似乎与C ++的使用非常具体相关,因此也就是C ++编译器处理文字字符串(或者至少是这个特定的C ++编译器)的方式。在这种情况下我不能说问题是什么 - 它甚至可能是编译器中的一个错误,因为(看似)正确的转义并不能解决问题。

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

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

请注意,对于原始字符串文字,您特别转义\字符。