L'automation Excel ne fonctionne pas dans C ++ Builder XE7

J'essaie d'utiliser le code ci-dessous pour ouvrir un file .xlsx à partir de C ++ Builder dans RAD Studio XE7:

#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 

Mais la dernière ligne provoque une exception avec le message:

Project2.exe a soulevé la class d'exception EOleException avec le message 'К сожалению, нам не удалось найти файл ИСТИНА.xlsx. Возможно, он был перемещен, переименован или удален? '

Traduction du russe:

Project2.exe a soulevé la class d'exception EOleException avec message 'Malheureusement, nous n'avons pas pu find le file TRUE.xlsx. Cela a-t-il été déplacé, renommé ou supprimé? '.

Écran avec lieu où la source se casse

Le code de Delphes semble fonctionner bien:

 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; var 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; 

Est-ce que quelqu'un connaît la solution?

Update1: Le code suivant dans VB fonctionne également bien:

 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: l' envoi d'un littéral de string brut provoque la même exception .

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

Cela ne semble pas non plus être un problème d'environnement. J'ai testé l'exemple sur plusieurs ordinateurs sans effet.

En C ++, le caractère de barre oblique inverse est le caractère d'échappement dans les littéralités de string et doit donc être échappé. Au lieu de

 L"D:\1.xlsx" 

vous devez écrire

 L"D:\\1.xlsx" 

Le message d'erreur est cependant étrange. C'est presque comme si une certaine conversion dans le code de répartition COM interprète le 1 comme valeur de vérité et le convertit en text. Vous pouvez essayer de passer le nom de file en tant que System::WideSsortingng qui pourrait System::WideSsortingng le problème.

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

Ce que vous rapportez semble presque trop bizarre pour être vrai cependant! Je dois avouer que j'ai du mal à le croire parce que c'est trop bizarre.

Le problème semble très spécifiquement lié à l'utilisation de C ++ et donc à la manière dont les compilateurs C ++ traitent de strings littérales (ou du less de ce compilateur C ++ particulier). Bien que ce soit le problème dans ce cas, je ne peux pas dire – il pourrait même s'agir d'un bug dans le compilateur car (apparemment) l'échappement correct ne résout pas le problème.

Vous pourriez utiliser diverses stratégies pour éliminer la possibilité qu'il traite de la string littérale dans ce cas. Mais puisque cela implique une string littérale et que vous utilisez XE7, je crois que vous devriez pouvoir contourner ceci plus explicitement en exprimant le littéral en tant que string brute (selon C ++ 11, qui est / devrait être pris en charge par C ++ Builder XE7):

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

Notez qu'avec des littératures de strings brutes, vous n'échappez pas spécifiquement \ chars.

Je viens de faire face à un problème similaire avec C ++ Builder XE7 et je pensais que je partagerais ce que j'ai trouvé. Toute tentative de définir ou d'envoyer un littéral de string de n'importe quel type provoqué soit une mauvaise erreur de type de variable, a été définie comme TRUE dans Excel comme Dmisortingi ou a provoqué une erreur de memory.

Ce que j'ai finalement trouvé, c'est qu'il existe un type OLEVariant dans C ++ Builder qui contient des types de données compatibles avec l'automation OLE et que l'exécution peut se convertir au besoin.

J'ai d'abord essayé de changer toutes mes variantes de variantes à OLEVariant sans succès, mais j'ai pu utiliser une dissortingbution sur n'importe quelle string que j'ai envoyée pour qu'elle fonctionne, même d'anciennes strings de caractères. Alors, vous pourriez essayer

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

même sans la mise en forme de WideSsortingng, cela a fonctionné pour ce que je faisais, cela pourrait aussi fonctionner

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

En ce qui concerne l'échappement, je ne suis pas sûr si vous devez échapper à la barre oblique inverse dans le second cas avec une simple string ou non.