IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Visual C++ Discussion :

VS 2010 - Automation Office Excel - Smart pointer - Import Directive


Sujet :

Visual C++

  1. #1
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2012
    Messages : 21
    Points : 16
    Points
    16
    Par défaut VS 2010 - Automation Office Excel - Smart pointer - Import Directive
    Bonjour,

    Pour une appli C++ sous VS 2010, je cherche à créer des fichiers Excel (pas des CSV car besoin de formatage de cellule).
    Désolé par avance si je ne suis pas dans le bon forum.

    J'ai vu qu'on pouvait passer entre autre par Automation Office par des smart Pointer (Import Directive) ou par appels directs à des services COM.
    A priori la technique par Smart Pointer me semble plus simple que la technique par services COM (Pour ce dernier, à première vue le code pique les yeux...).

    En revanche, à moins que j'ai mal compris, avec les smart pointer, il faut explicitement déclarer une version d'Excel précise.
    par exemple #import "C:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE" \

    Ca me semble contraignant question pérennité, il suffit qu'une nouvelle version d'Excel soit installée pour que cela cesse de fonctionner.

    Il y a un moyen de contourner cette contrainte ? Des import conditionnés par version d'Excel ?

    Sinon, bah utiliser les services COM et serrer les dents

    Merci de votre réponse et bonne journée.

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 068
    Points : 12 111
    Points
    12 111
    Par défaut
    Pour moi, "smart Pointer", cela n'a rien à voir avec "Import Directive".
    Donc je remplace "smart Pointer" par "Import Directive". (dans ma tête, oui je sais, ça n'aidera pas ma schizophrénie latente)

    appels directs à des services COM
    Les Services COM, c'est vague, très vague, vous voulez vraisemblablement parler d'ATL ou de l'API COM (une API en C à la Win32), non ?

    "#import", c'est juste un truc pour nous faciliter la vie.
    Vous avez les mêmes limitations qu'avec ATL et COM(de base).

    Le seul truc, c'est qu'en ATL et en COM, vous en chiez tellement, que la gestion du versionning, c'est pas plus compliquer que le reste.

    Vous ne pourrez pas espérer avoir du code qui fonctionne avec les versions ultérieures de produit, si les concepteurs du dit produit n'ont pas assuré la compatibilité ascendante.

    Donc, si la nouvelle version d'Office assure la compatibilité avec la version "Office12", votre code fonctionnera sans accro.
    Il ne pourra pas utiliser les nouvelles fonctionnalités de la nouvelle version, mais c'est tout.

    Si la nouvelle version n'assure pas de compatibilité, là, ça coince, mais aussi bien avec #import qu'avec ATL/COM.
    Si vous disposez de la TLB de la nouvelle version, rien ne vous empêche de faire plusieurs #import, mais attention aux collisions de noms.
    Une petite tambouille pour que le #import soient dans un "namespace{...}" différents (ou l'utilisation judicieuse des options de #import) pour éviter ces collisions et le tour est joué.
    Avec ATL/COM, vous ferez toute cette tuyauterie à la main, mais les limitations sont les mêmes, le TLB doit être connu à l'avance.
    Le seul avantage d'ATL/COM, c'est que vous n'avez pas besoin de la TLB sous la main, mais dans une documentation blindée de GUID dans tous les coins.

    Que cela soit avec #import ou ATL/COM, vous ne pouvez pas être compatible avec une version "Alien" venant du turfu de SkyNet.

    Mais bon, on ne va pas se mentir, utiliser Excel pour créer des fichiers ".xlsx", c'est une super très mauvaise idée.

    Le format des fichiers ".xlsx" n'est pas propriétaire, contrairement aux fichiers ".xls".
    Donc, contrairement aux fichiers ".xls" où l'on devait utiliser des composants pondus à coups de reverse-engineering tout moisi, on dispose de l’embarras du choix des SDKs/frameworks/composants pour la génération de fichiers ".xlsx".
    Comme énormément de ces composants se basent sur .NET et que l'utilisation de code C++/CLI depuis VS est des plus aisé, je vous conseille de le faire en C++/CLI.
    SDK officiel pour Office :https://www.microsoft.com/en-us/down....aspx?id=30425

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par bacelar Voir le message
    Pour moi, "smart Pointer", cela n'a rien à voir avec "Import Directive".
    C'est fort dommage, parce que la directive #import déclare, en plus des interfaces COM, des pointeurs intelligents vers celles-ci.
    Et ce, indépendamment d'ATL: Il s'agit à la place du Compiler COM Support, qui contrairement à ATL, est pris en charge par les éditions Express de Visual Studio.

    Citation Envoyé par Ender75 Voir le message
    En revanche, à moins que j'ai mal compris, avec les smart pointer, il faut explicitement déclarer une version d'Excel précise.
    par exemple #import "C:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE" \

    Ca me semble contraignant question pérennité, il suffit qu'une nouvelle version d'Excel soit installée pour que cela cesse de fonctionner.

    Il y a un moyen de contourner cette contrainte ? Des import conditionnés par version d'Excel ?
    Si j'en crois la documentation de la directive #import, tu peux importer en spécifiant le ProgID d'un objet supporté par la TypeLib (Au hasard: Excel.Application) plutôt que d'avoir à faire quoi que ce soit de spécifique à une version ou à un chemin sur le disque.
    Mais ça ne marche pas pour Excel, car ses objets n'ont pas de lien vers la typelib dans le registre.

    Il te reste l'option d'utiliser le LibID à la place, parce qu'apparemment, contrairement aux CLSID, celui-ci ne change pas d'une version à l'autre.

    Donc, un #import "libid:00020813-0000-0000-C000-000000000046" devrait marcher (malheureusement il ne suffit pas).

    Après quelque recherches sur Internet, j'ai réussi à trouver les bonnes directives d'import:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <Windows.h>
    #include <stdio.h>
     
    #import "libid:2DF8D04C-5BFA-101B-BDE5-00AA0044DE52" rename("DocumentProperties", "MSODocumentProperties") rename("RGB", "MSORGB") //MSO.dll
    #import "libid:0002E157-0000-0000-C000-000000000046" no_namespace rename("Reference", "ignorethis"), rename("VBE", "testVBE") //VBE6Ext.olb
    #import "libid:00020813-0000-0000-C000-000000000046" exclude("IFont", "IPicture") rename("RGB", "ignorethis"),\
    	rename("DialogBox", "ignorethis"), rename("VBE", "testVBE"), rename("ReplaceText", "EReplaceText"), rename("CopyFile","ECopyFile"),\
    	rename("FindText", "EFindText"), rename("NoPrompt", "ENoPrompt") //Excel.exe
     
    int main(void)
    {
    	return 0;
    }
    Il est possible que certains des exclude() et rename() soient superflus, notamment sur les deux derniers imports.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2012
    Messages : 21
    Points : 16
    Points
    16
    Par défaut
    Merci beaucoup Bacelar et Médinoc pour vos réponses détaillées !

    @Bacelar
    J'ai utilisé le terme de smart pointers parce que cela faisait référence dans une page du FAQ
    https://cpp.developpez.com/faq/vc/?p...sual-Cplusplus

    Pour les services COM, la solution proposée est d'utiliser les IDispatch et les fonctions Invoke.
    En tout cas, c'est assez indigeste.

    Donc, si la nouvelle version d'Office assure la compatibilité avec la version "Office12", votre code fonctionnera sans accro.
    Il ne pourra pas utiliser les nouvelles fonctionnalités de la nouvelle version, mais c'est tout.
    Je connais assez mal comment fonctionne ces répertoires d'Office / librairies
    Est-ce ces répertoires/Librairies seront créés à l'installation d'une version ultérieure qui assure la compatibilité descendante ?

    Une petite tambouille pour que le #import soient dans un "namespace{...}" différents (ou l'utilisation judicieuse des options de #import) pour éviter ces collisions et le tour est joué.
    Et je ne suis pas très à l'aise non plus sur les import (ok je cumule...) et namespace , quelle est cette tambouille en question ?

    @Médinoc
    Oui j'avais vu qu'on pouvait utiliser les libid, ça me semble effectivement plus propre.

    Encore merci à tous les deux d'avoir consacré du temps à me répondre !

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Utiliser IDispatch? Toutes les interfaces d'Excel sont duales, utiliser la version late-bound est une pure perte de temps et d'efficacité pour un programme en C++: ces versions sont prévues pour des langages de script. Utilise les interfaces normales, les smart pointers générés par #import sont faits pour ça.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2012
    Messages : 21
    Points : 16
    Points
    16
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Utiliser IDispatch? Toutes les interfaces d'Excel sont duales, utiliser la version late-bound est une pure perte de temps et d'efficacité pour un programme en C++: ces versions sont prévues pour des langages de script. Utilise les interfaces normales, les smart pointers générés par #import sont faits pour ça.
    En regardant dans les forums (y compris la FAQ de ce site), c'était l'une des 3 méthodes proposées.

    Mais sinon oui je compte utiliser les smart pointers parce que les services COM, ça m'avait semblé franchement pénible à coder.

    Merci pour le conseil, ça me conforte dans cette solution

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 068
    Points : 12 111
    Points
    12 111
    Par défaut
    C'est fort dommage, parce que la directive #import déclare, en plus des interfaces COM, des pointeurs intelligents vers celles-ci.
    No problemo, moi, j'appelle cela des "CCom pointers", mais c'est assez proche des smart pointers du C++11.

    Compiler COM Support, qui contrairement à ATL, est pris en charge par les éditions Express de Visual Studio.
    C'est pas fourni avec la version Community de Visual Studio ?

    Pourquoi l'option de générer des fichiers sans avoir à utiliser Excel ne vous convient pas ?

    Le #import via libid en dur ou en passant pas celle stockée dans les ressources de l'EXE, pour moi, c'est un peu du pareil au même. La compatibilité ascendante n'est pas assurée.

    Et je ne suis pas très à l'aise non plus sur les import (ok je cumule...) et namespace , quelle est cette tambouille en question ?
    C'est vraiment pas compliqué
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    namespace Excel12{
        #import "C:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE"
    }
    namespace Excel13{
        #import "C:\\Program Files\\Microsoft Office\\Office13\\EXCEL.EXE"
    }
    Chaque namespace aura les types correspondants à la version d'Excel.

    En regardant dans les forums (y compris la FAQ de ce site), c'était l'une des 3 méthodes proposées.
    Moi, je propose une quatrième, qui ne pose pas de problème de version, utiliser le format ouvert XLSX.

  8. #8
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2012
    Messages : 21
    Points : 16
    Points
    16
    Par défaut
    @Bacelar

    Pourquoi l'option de générer des fichiers sans avoir à utiliser Excel ne vous convient pas ?
    Moi, je propose une quatrième, qui ne pose pas de problème de version, utiliser le format ouvert XLSX.
    La solution proposée est d'utiliser OPEN XML avec C++/CLI ?
    Je suis en train de m'informer là dessus cependant, je travaille sur une application existante en C++/MFC.
    J'ai cru comprendre que ce n'est pas neutre de passer comme ça en C++/CLI ?

    Sinon pour les namespace, désolé d'insister (surtout quand ce n'est manifestement pas compliqué ) mais comment conditionner l'appel d'un import ou d'un autre à partir de ces namespaces ? En utilisant le mot clé using ?
    Et je pensais que les import se faisaient à la phase de preprocesseur ? Si oui c'est possible de les appeler conditionnellement ?

    Encore merci pour votre réponse.

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Pourquoi conditionner? Avec l'import du LIBID en dur, tu ne dépends ni de la version d'Excel, ni de son emplacement...
    Tout ce dont tu as besoin, c'est qu'Excel soit présent sur ta machine de dev, et sur la machine où tournera le programme.

    Par contre, bacelar a raison, quitte à dépendre d'un autre exécutable, autant faire directement un exécutable séparé (en C++/CLI ou en C#) qui génère un .xlsx en utilisant le OpenXml SDK plutôt qu'Excel. Ça ne changera rien au fait que tu aies besoin d'installer autre chose en plus de ton programme, mais cet "autre chose" permet la redistribution gratuite, contrairement à Office...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Inactif  

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2012
    Messages
    4 904
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 4 904
    Points : 10 168
    Points
    10 168
    Billets dans le blog
    36
    Par défaut
    Bonjour,

    Je ne connais pas Visualc++, donc j'espère que je ne dis pas d'ânerie. En VB.net et en C#, il y a moyen de créer des fichiers Excel, sans Excel avec l'une ou l'autre de ces bibliothèques (gratuites) :

    ClosedXML
    EPPLus
    À ma connaissance, le seul personnage qui a été diagnostiqué comme étant allergique au mot effort. c'est Gaston Lagaffe.

    Ô Saint Excel, Grand Dieu de l'Inutile.

    Excel n'a jamais été, n'est pas et ne sera jamais un SGBD, c'est pour cela que Excel s'appelle Excel et ne s'appelle pas Access junior.

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 068
    Points : 12 111
    Points
    12 111
    Par défaut
    Pas de soucis @clementmarcotte.
    Tes suggestions sont des assemblies .NET, comme le SDK OOXML de Microsoft.
    Donc c'est dans la même catégorie de solution.

    Je ne connais pas ClosedXML mais EPPLus est plus simple d'utilisation que le SDK OOXML pour des besoins simples sous Excel.

    Pourquoi conditionner? Avec l'import du LIBID en dur, tu ne dépends ni de la version d'Excel, ni de son emplacement...
    L'utilisation de LIBID ne réglera pas les problèmes de compatibilité ascendante future, et pour les versions actuelles, il faut quand même faire des tests.
    Je ne vous pas trop l'avantage de cette solution.
    Le plus simple, c'est de prendre la version minimale de l'Office exigé et d'utiliser que les types communs les plus basiques.
    Ça arrive au même.

    Pour "MFC + C++/CLI", c'est aussi casse-gueule que du C dans du MFC, faut juste savoir ce que l'on fait.
    MFC est un framework un peu relou, c'est comme ça.
    MFC gère assez bien COM, donc, en cas de problème, vous pouvez toujours encapsuler votre code C++/CLI dans des composant COM que l'application MFC utilisera comme des composants COM "standard".
    Donc, l'utilisation d'un programme externe pour utiliser C++/CLI, n'est, pour moi, pas obligatoire. Mais cela peut très bien être pratique pour une utilisation dans d'autres projets, en générateur de rapports par exemple.

    Il y a beaucoup d'outils .NET de génération de XLSX, mais il en existe aussi en natif/portable : https://sourceforge.net/projects/xlsxio/

    Pour les namespaces, l'astuce n'évite que les collisions de noms et permet de gérer les différents types des différentes versions d'Excel.
    Tout le code qui doit gérer dynamiquement/au runtime la version de l'Excel est à faire. Mais avec quelques Design Pattern, cela ne devrait représenter quelques lignes ou dizaines de lignes.

  12. #12
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2012
    Messages : 21
    Points : 16
    Points
    16
    Par défaut
    @Médinoc

    Pourquoi conditionner? Avec l'import du LIBID en dur, tu ne dépends ni de la version d'Excel, ni de son emplacement...
    Tout ce dont tu as besoin, c'est qu'Excel soit présent sur ta machine de dev, et sur la machine où tournera le programme.
    Ok je n'étais pas sûr du fonctionnement de cet import avec le LIBID mais ça me va parfaitement.
    Office étant un pré-requis (pour d'autres raisons), normalement, il n'y a pas de souci de ce côté là.

    @Bacelar

    L'utilisation de LIBID ne réglera pas les problèmes de compatibilité ascendante future, et pour les versions actuelles, il faut quand même faire des tests.
    Je ne vous pas trop l'avantage de cette solution.
    Le plus simple, c'est de prendre la version minimale de l'Office exigé et d'utiliser que les types communs les plus basiques.
    Ça arrive au même.
    Si cela fonctionne avec les versions actuelles, c'est déjà ça.

    Médinoc, Bacelar, Clementmarcotte, merci à votre contribution à cette discussion !

Discussions similaires

  1. [AC-2013] migration Automation vers Excel 2010
    Par DBSP94 dans le forum Access
    Réponses: 1
    Dernier message: 14/01/2014, 19h38
  2. Excel 2010 avec Office 2007
    Par adrian07 dans le forum Microsoft Office
    Réponses: 0
    Dernier message: 21/01/2013, 14h06
  3. [Toutes versions] compatibilité office excel 2003 2010
    Par CODYCO dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 28/11/2011, 15h35
  4. Réponses: 1
    Dernier message: 18/01/2008, 11h47
  5. Réponses: 9
    Dernier message: 20/09/2007, 12h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo