Excel自动化在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 

但最后一行导致exception与消息:

Project2.exe引发exception类EOleException,并显示消息'ссталению,намнеудалосьнастифайлИСТИНА.xlsx。 Возможно,онбылперемещен,переименованилиудален?'

俄语翻译:

Project2.exe引发exception类EOleException消息'不幸的是,我们无法find文件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; 

有谁知道解决scheme?

更新1:在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:发送原始string文字会导致相同的exception 。

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

这似乎也不是一个环境问题。 我在几台电脑上testing了这个例子,没有任何效果。

在C ++中,反斜杠字符是string文字中的转义字符,因此需要将其转义。 代替

 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,并认为我会分享我发现的。 任何尝试设置或发送任何types的string文字导致不良variablestypes错误,在Excel中设置为TRUE像Dmitrii或导致内存错误。

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

我第一次尝试更改所有我的Variantvariables到OLEVariant没有成功,但后来能够使用任何string,我发送它使工作,即使是旧的string。 所以你可以试试

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

即使没有WideString格式它为我所做的工作,所以这也可以工作

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

至于转义,我不知道你是否需要用简单的string来避免在第二种情况下的反斜杠。

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

你可以使用各种策略来消除在这种情况下处理string的可能性。 但是,因为这确实涉及到一个string,并且由于您使用的是XE7,所以我相信您应该能够通过将字面值表示为原始string来避开这个问题(按照C ++ 11,C ++ Builder应该支持这个stringXE7):

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

请注意,使用原始string文字,您特别不会转义\ chars。

Interesting Posts