簡體   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