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

VB.NET Discussion :

Utiliser fonctions VB.Net depuis VBA dans Excel


Sujet :

VB.NET

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 13
    Par défaut Utiliser fonctions VB.Net depuis VBA dans Excel
    Bonjour,

    Je vous précise un peu tout ça, car j'ai du mal à trouver de la documentation là-dessus. Soit une application Windows Forms réalisée en VB.Net. L'objectif est de pouvoir faire appel aux fonctions de la classe "Excel" de cette application depuis une macro VBA dans un classeur Excel.

    Comment faire ?

  2. #2
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 048
    Par défaut
    A priori ça doit être possible vu que lorsque j'ouvre un fichier avec l'objet ExcelApplication le code d'ouverture de fichier s'exectue (dans le cas qui me revient en tête ce code affichait un formulaire).

    Pour executer une macro on peut passer par:


  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 13
    Par défaut
    Citation Envoyé par sinople Voir le message
    A priori ça doit être possible vu que lorsque j'ouvre un fichier avec l'objet ExcelApplication le code d'ouverture de fichier s'exectue (dans le cas qui me revient en tête ce code affichait un formulaire).

    Pour executer une macro on peut passer par:

    Merci sinople, mais en fait c'est l'inverse que je veux faire. Dans une macro du fichier Excel, je veux pouvoir appeler une fonction écrite dans une classe VB.Net.

    Mais je retiens quand même, ça pourra me servir plus tard.

  4. #4
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 048
    Par défaut
    Ah...

    Il y a 2 solutions (qui peuvent être mélangées!):

    Soit tu utilises la technologie VSTO (pas possible avec les version express de Visual Studio), ce qui consiste à utiliser du .Net à la place de VBA.

    Autrement faut que ta fonction .Net soit balancée dans une fichier de librairie (.dll) ou objet (COM)? que tu dois pouvoir attaquer depuis ta macro en VBA. Mais n'ayant jamais fait ce genre de truc mon aide s'arrête là.

    Je me souviens d'un collègue qui utilisait un prog .net pour envoyer des mail depuis Access, donc c'est possible!

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 13
    Par défaut
    Citation Envoyé par sinople Voir le message
    Autrement faut que ta fonction .Net soit balancée dans une fichier de librairie (.dll) ou objet (COM)? que tu dois pouvoir attaquer depuis ta macro en VBA. Mais n'ayant jamais fait ce genre de truc mon aide s'arrête là.
    Oui, c'est ce que je cherche à faire, mais c'est pas évidement et très peu documenté. Merci quand même pour ta réponse.

  6. #6
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut UDF dans excel,fonctions utilisateurs en vb.net
    bonjour
    Creer les fameux UDF en vb.net et les integrer à Excel?
    Oui c'est possible, et c'est une des lacunes des VSTO dont beaucoup d'utilisateurs Excel se plaignent.

    1/creer un projet librairies de classes normal
    2/renommer la classe dans le nom que vous voulez.
    3/mettre un namespace avec un nom court de preference(il faciltera la recherche de la lib)
    4/pas la peine de mettre visible pour com(il est mis par code)
    voici un exemple avec une fonction chaine,2 fonctions numeriques.
    ici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
     
    '1/ Imports InteropService est necessaire pour permettre l'interactiion avec
    ' une application com(excel)
    '2/noter qu'il ne s'agit que de fonctions utilisateurs UDF(user defined function)
    '3/si l'on veut des sub on utilise les add-in VSTO
    Imports System.Runtime.InteropServices
    <ClassInterface(ClassInterfaceType.AutoDual), ComVisible(True)> _
        Public Class LibFonctionsExcel
        'fonction chaine
        Public Function EchoInput(ByVal v1 As Integer) As String
            Return "You entered " & v1.ToString
        End Function
        'fonction numerique 1
        Public Function DiviserParDeux(ByVal D As Double) As Double
            Return D / 2
        End Function
        'fonction numerique 2
        Public Function DivideParQuatre(ByVal D As Double) As Double
            Return D / 4
        End Function
        'cree un guid et une cle sur le serveur
        <ComRegisterFunctionAttribute()> _
        Public Shared Sub RegisterFunction(ByVal type As Type)
            Microsoft.Win32.Registry.ClassesRoot.CreateSubKey("CLSID\\{" & _
    type.GUID.ToString().ToUpper() + "}\\Programmable")
        End Sub
        'supprime la cle sur le serveur
       <ComUnregisterFunctionAttribute()> _
        Public Shared Sub UnregisterFunction(ByVal type As Type)
            Microsoft.Win32.Registry.ClassesRoot.DeleteSubKey("CLSID\\{" & _
    type.GUID.ToString().ToUpper() + "}\\Programmable")
        End Sub
    End Class
    4/ creer l'executable dll
    5/ lancer excel à l'exterieur de visual studio
    6/outils excel->macro complementaires->automatisation
    7/dans la boite de dialogue rechercher la lib :namespace.nomclasseUDF
    8/OK (si le message mscoree.dll cannot be found,repondre non et ok)
    9/allez dans la feuille 1 ,function et rechercher vos functions bien pretes.

    Une autre approche est de creer une librairie normale en .net,visible com , de la referencer en vba(car interopcom creer un fichier TBL pour ce faire) ,de mettre en place une macro qui appelle cette fonction...

    bon code..............

  7. #7
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut Utiliser fonctions VB.Net depuis VBA dans Excel
    rebonjour
    quand j'ai bien vu ta replique à sinople,eh bien je te confirme la 2eme approche utiliser une lib .net en vba (une classe complete quoi ...creer en .net )
    voici comment proceder simplement:
    1/projet lib .net normal
    2/supprimer la classe cree
    3/ajouter un nouvel element->class com
    Nota-Bene:ne touche pas au constructeur cree sous peine de deboire pour ta classe com(lit preambule genere vs 2008 ou vs2010)

    4/ici le code VB.NET de la classe complete par 2 proprietes et une methode

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
    <ComClass(ComClass1.ClassId, ComClass1.InterfaceId, ComClass1.EventsId)> _
    Public Class ComClass1
     
    #Region "GUID COM"
        ' Ces GUID fournissent l'identité COM pour cette classe 
        ' et ses interfaces COM. Si vous les modifiez, les clients 
        ' existants ne pourront plus accéder à la classe.
        Public Const ClassId As String = "18ae69b0-ef5a-447e-91f7-8ccd5c328bef"
        Public Const InterfaceId As String = "782e5dbe-8665-4881-9f58-37c78f77f598"
        Public Const EventsId As String = "d68cf810-27dd-4e3d-9438-27f348800c11"
    #End Region
     
        ' Une classe COM pouvant être créée doit avoir Public Sub New() 
        ' sans paramètre, sinon, la classe ne sera pas 
        ' inscrite dans le Registre COM et ne pourra pas être créée 
        ' via CreateObject.
        Public Sub New()
            MyBase.New()
        End Sub
        Private x_nom As String
        Public Property NOM() As String
            Get
                Return x_nom
            End Get
            Set(ByVal value As String)
                x_nom = value
            End Set
        End Property
        Private x_valeur As Double
        Public Property VALEUR() As Double
            Get
                Return x_valeur
            End Get
            Set(ByVal value As Double)
                x_valeur = value
            End Set
        End Property
     
        Public Sub METHOD1()
            VALEUR = VALEUR * 2.0
        End Sub
    End Class
    5/generer la solution
    6/lance un excel
    7/dans le nouveau classeur cree un projet userform VBA avec un bouton command et un textbox
    7/dans l'editeur VBA fais Outils->References->click->boite de dialogue (cherche ta lib ComClass1 comme par exemple) ->coche->ok
    8/ dans l'edit VBA tapes ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Dim objNet As ComClass1
    Private Sub CommandButton1_Click()
    Set objNet = New ComClass1
    objNet.NOM = "paul"
    objNet.VALEUR = 150#
    Call objNet.METHOD1
    TextBox1.Text = CStr(objNet.VALEUR)
    End Sub
    Ainsi faisait Guillaume Tell avec son arc.............(la suisse me rappelle les bandes dessines et guillaume tell)....
    bon code............

  8. #8
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 048
    Par défaut
    Je pensais effectivement à un truc du style.

    Quand à Guillaume Tell, il avait une arbalète dans la légande :-)

    Merci pour la précision de l'UDF, c'est un exemple très pertinant (et de valeur pour ceux qui savent utiliser la fonction rechercher!)

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 13
    Par défaut
    Merci beaucoup MABROUKI. Cela me rassure, car ce sont les deux méthodes que j'avais envisagé. Et ça marche nickel sur mon poste en développement.

    Mais par contre, le déploiement sur le poste du client pose problème. On fait nos installations avec InstallShield Pro 2010 et il n'arrive pas à inscrire la DLL à la base de registre : il y a une erreur HRESULT -2147220473. Et quand j'essaye de rajouter la DLL en référence au fichier Excel, il n'apparaît pas dans la liste, et en essayant de le rajouter à la main il me dit qu'il est impossible d'y faire référence.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    <ComClass(MaClass.ClassId, MaClass.InterfaceId, MaClass.EventsId)> _
    Public Class MaClass
        Private O As MonProjetWindowsForms.MaClasse
     
    #Region "GUID COM"
        ' Ces GUID fournissent l'identité COM pour cette classe 
        ' et ses interfaces COM. Si vous les modifiez, les clients 
        ' existants ne pourront plus accéder à la classe.
        Public Const ClassId As String = "########-####-####-####-############"
        Public Const InterfaceId As String = "########-####-####-####-############"
        Public Const EventsId As String = "########-####-####-####-############"
    #End Region
     
        ' Une classe COM pouvant être créée doit avoir Public Sub New() 
        ' sans paramètre, sinon, la classe ne sera pas 
        ' inscrite dans le Registre COM et ne pourra pas être créée 
        ' via CreateObject.
        Public Sub New()
            MyBase.New()
            O = MonProjetWindowsForms.MaClasse.getInstanceDeMaClasse
        End Sub
     
        Public Function Fct1(ByVal Param1 As String, ByVal Param2 As String, ByVal Param3 As Integer, ByVal Param4 As String) As String
            Return O.Fct1(Param1, Param2, Param3, Param4)
        End Function
     
        Public Function Fct2(ByVal Param1 As String) As String
            Return O.Fct2(Param1)
        End Function
     
        Public Sub Mtd1(ByVal Param1 As String, ByVal Param2 As String, ByVal Param3 As Integer, ByVal Param4 As String, ByVal Param5 As Integer)
            O.Mtd1(Param1, Param2, Param3, Param4, Param5)
        End Sub
     
        Public Function Fct3(ByVal Param1 As String, ByVal Param2 As Integer, ByVal Param3 As String) As Double
            Return O.Fct3(Param1, Param2, Param3)
        End Function
     
        Public Function Fct4(ByVal Param1 As String) As String
            Return O.Fct4(Param1)
        End Function
     
        Public Sub Mtd2()
            O.Mtd2()
        End Sub
     
        Public Sub Mtd3(ByVal Param1 As Integer)
            O.Mtd3(Param1)
        End Sub
     
    End Class
    Vous avez une solution ?

  10. #10
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut deployer add-in com
    bonjour
    d'abord je tiens à faire une petite remarque au passage :un add-in com genere avec vb.net n'est pas un vrai "objet com" au sens de celui genere dans un environnement classique com (par exemple en vb6 ou vs 2006),a cause du wrapper RCW(com callable) inclus dans la dll.

    Tant et si bien que :
    - le deployement des add-in office qui sont des assembly net sont inspectes par le JIT au chargement pour examiner s'ils ont les droit d'execution sur machine user .
    Pour ce faire (octroi droit d'execution) il existe un modele de projet SetSecurite(2 fichiers SetSecurity et Update Manifeste à telecharger) disponible sur site microsoft en C# SHARP à integrer au projet
    Ensuite programmer les actions personnalisees sur le fichier SetSecurity qui est deploye avec l'addin.
    regarde sur ce poste du forum les etapes en plus en details.
    http://www.developpez.net/forums/d97...n-word-2003-a/

    Ignore le reste des etapes relatives aux add-in VSTO et les PIA offices.
    bon code..................

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 13
    Par défaut
    Merci MABROUKI pour ta réponse. J'ai fait pas mal de tests aujourd'hui et je désespère. Cela ne fonctionne pas. Mais j'ai un fait "nouveau" que je souhaiterais t'exposer.

    Je pense en effet que les projets SetSecurity et UpdateManifest ne sont pas utiles à partir d'Office 2007. Or, nous n'assurerons une compatibilité qu'à partir de cette version d'office, autrement dit on ignore les versions antérieures.

    Mais venons-en au fait. Je bataille depuis un moment à installer le fichier .dll, et j'ai vérifié sur mon poste en développement, c'est le .tlb qui est en référence.

    Donc j'ai ajouté le .tlb à Installshield pour l'installer et miracle, il apparaît dans les références. Et ce sans avoir à utiliser les projets SetSecurity et UpdateManifest. Par contre, j'ai une erreur d'exécution.

    Un composant ActiveX ne peut pas créer d'objet.

  12. #12
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut enregistrer un automation add-in,udf com
    bonjour devuranie
    excuse-moi pour le retard dans la reponse.
    tu parles de fichier .dll.lequel?
    il faut dans l'environnement com distinguer 2 types :
    1/ UDF => est un COM add-in c.a.d sans interaction avec l'Interface Excel(ca regroupe toutes les fonctions. l'interface est fourni par Excel).
    distinguo fondamental :il est destine à un utilisateur.
    2/la lib => est un Automation Add-In et il peut avoir meme une interface graphique(si tu appelles à l'interieur une classe form).
    distinguo fondamental :il est destine à un developpeur(sdk).

    Bien maintenant deployement:
    1/cas
    -signer l'assembly avec nom fort
    -copie le fichier dll (et le tlb est ajoute auto par le projet setup msi) dans dossier application.C'est ce dossier que tu deploies.
    -enregistrer le tlb sur la machine user
    -ajouter SetSecurity eventuellement.

    Sur une machine User Excel ne connait pas l'existence de cette dll et son tlb.
    (sur ta machine dev quand tu fais build VS enregistre à ton insu le tlb-coulisses).
    Il faut enregistrer l'assembly avec l'utilitaire Regasm.exe quand tu deploie chez un user (regsver32 est reserve pour le "vrai" monde Com-rappelle toi ce que j'ai dit dans premier post).
    Ici le code pour l'utilitaire regasm pour deployement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    'cette instruction command line cree tlb et l'enregistre sur la machine user 
    Regasm demo.dll /tlb: demo.tlb
    l'ennui est que pour un add-in Com on ne peut pas le faire par code.
    aussi faut-il avoir dans le dossier installation l'utilitaire regasm.exe

    2/cas
    -signer l'assembly avec nom fort
    -copie le fichier dll (et le tlb est ajoute auto par le projet setup msi) dans dossier application.C'est ce dossier que tu deploies.
    -ce cas est le cas du deploiement SDK qui est simplement copie dans un dossier de la machine dev du developpeur d'application .
    Celui-ci se chargera d'enregistrer la lib sur sa machine avec regasm et de referencer le tlb manuellement dans son projet.

    Il existe une autre approche plus sure et balise par microsoft pour creer un automation Add-In (2e cas) avec une classe COM
    C'est simplement utiliser un add-in VSTO Excel pour atteindre le meme objectif.Tu peux declarer ta classe avec prop et methodes dans l'add-in VSTO et l'appeler à partir de vba.
    Methode recommende par Microsoft.
    jette un coup d'oeil sur cet article de la MSDN LIB :http://www.google.fr/url?sa=t&source...jktoS44LCVbn-Q

    C'est pour cela que j'ai repondu dans le premier post en focalisant sur le 1er cas (UDF) que ne peut resoudre un add-in.

    Deploiement: ah ,au passage sur beaucoup de forums certains se meprennent en voulant deployer une SDK comme si c'etait une application destine à un utilisateur lambda.
    Deployer une app destine à un user lambda est effictivement plus delicat (application exe en general).

    je m'excuse de confondre une arbalete plus evolue qu'un arc....
    bon code.......

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 13
    Par défaut
    Bonjour,

    Merci MABROUKI pour cette réponse. En ajoutant Regasm.exe dans le répertoire d'installation, et en passant la commande citée ci-dessus il me créé bien le tlb accessible depuis Excel. On progresse donc.

    Cependant, j'ai toujours une erreur d'exécution.
    Variable objet ou variable de bloc With non défini.

  14. #14
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut appel a une classe com
    bonjour devuranie,
    uranus c'est mauvaise conjonction astrale,associe à lubies.
    1er point à verifier
    -----------------
    -en regardant ton premier code ce doute m'as pris.
    Est ce que tu as vire de ton code ceci (le premier code soumis par toi) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
     
    <ComClass(MaClass.ClassId, MaClass.InterfaceId, MaClass.EventsId)> _
    Public Class MaClass
        'vire moi ca svp,de surcroit prive donc inaccessible de l'exterieur? 
        Private O As MonProjetWindowsForms.MaClasse
     
    #Region "GUID COM"
        ' Ces GUID fournissent l'identité COM pour cette classe 
        ' et ses interfaces COM. Si vous les modifiez, les clients 
        ' existants ne pourront plus accéder à la classe.
        Public Const ClassId As String = "########-####-####-####-############"
        Public Const InterfaceId As String = "########-####-####-####-############"
        Public Const EventsId As String = "########-####-####-####-############"
    #End Region
     
        ' Une classe COM pouvant être créée doit avoir Public Sub New() 
        ' sans paramètre, sinon, la classe ne sera pas 
        ' inscrite dans le Registre COM et ne pourra pas être créée 
        ' via CreateObject.
        Public Sub New()
            MyBase.New()
            'vire moi svp c'est interdit par le compilo
            O = MonProjetWindowsForms.MaClasse.getInstanceDeMaClasse
        End Sub
     
        Public Function Fct1(ByVal Param1 As String, ByVal Param2 As String, ByVal Param3 As Integer, ByVal Param4 As String) As String
            Return Fct1(Param1, Param2, Param3, Param4)
        End Function
     
        Public Function Fct2(ByVal Param1 As String) As String
            Return Fct2(Param1)
        End Function
     
        Public Sub Mtd1(ByVal Param1 As String, ByVal Param2 As String, ByVal Param3 As Integer, ByVal Param4 As String, ByVal Param5 As Integer)
            Mtd1(Param1, Param2, Param3, Param4, Param5)
        End Sub
     
        Public Function Fct3(ByVal Param1 As String, ByVal Param2 As Integer, ByVal Param3 As String) As Double
            Return O.Fct3(Param1, Param2, Param3)
        End Function
     
        Public Function Fct4(ByVal Param1 As String) As String
            Return O.Fct4(Param1)
        End Function
     
        Public Sub Mtd2()
           'tu peux mettre Me tiens.
            Me.Mtd2()
        End Sub
     
        Public Sub Mtd3(ByVal Param1 As Integer)
            Me.Mtd3(Param1)
        End Sub
     
    End Class
    2eme point
    ----------
    -il faut desenregistrer la premiere version avec regasm et nettoyer le registrer (sinon tu vas avoir des problemes de version) .
    evidemment comme tu es en phase de test si tu as modifie demo.dll en tourne en rond,aussi microsoft a prevu ceci:
    -change le numero de version dans ton appli a chaque test (tous les appels iront à version 2.0,ou version 3.0 sur la machine user cobaye suivant phase test).

    (nb: il y une autre facon d'operer personnelle c'est creer une nouvelle version en changeant les codes ClassId, InterfaceId , EventsId car win travaille avec ses codes ca).

    quoique je soupconne beaucoup que l'origine de ton probleme ne vienne du premier point.
    bon code..........

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 13
    Par défaut
    Bonsoir,

    Merci MABROUKI pour ta réponse. Alors concernant tes commentaires sur les parties qui devraient être virées, je m'explique. En fait, j'ai ajouté en référence à la solution un projet Windows Forms VB.Net, "MonProjetWindowsForms".

    Dans ce projet Windows Forms, il y a une classe que je souhaiterais exploiter. C'est "MaClasse".

    Cette classe s'instancie grâce à un singleton, avec la fonction "getInstanceDeMaClasse".

    Mais pourquoi diable ? Car l'objectif est de pouvoir faire appel à des formulaires et objets de mon appli Windows Forms depuis Excel. Et je m'empresse de préciser que ce code fonctionne parfaitement sur une machine équipé de la plateforme de développement, Visual Studio Pro 2008 dans ce cas.

    Ce pourquoi tu avais des appels en O.SubOrFunction dans mes procédures et fonctions. "O" étant l'instance de ma fameuse classe dans l'appli Windows Forms, et c'est cette instance qui se charge d'ouvrir les formulaires appropriés dans les Sub.

  16. #16
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut automation com,formulaire à instancier
    bonjour,

    Il me semble qu'il faut se contenter d'une simple classe sans aspect visuel,parce que l'interaction d'un controle WinForm .Net avec un objet COM n'est pas simple meme pour un vrai objet COM.
    Une des difficultes est d'acceder aux proprietes du WinForm (textebox,bouton et autres ....pour gerer leurs valeurs ), comme illustrer ici dans cet article de la lib MSDN
    http://www.google.fr/url?sa=t&source...J2LlArCT36_i5A
    Pour utiliser un WinForm comme controle utilisateur et l'integrer dans ton application Excel VBA il vaut mieux utiliser Toolkit WinForms prevu à cet effet par Microsoft(comporte la majeure partie des controls courants .net).
    Petit defaut du toolkit: on integre les controles par code,pas par un designer.
    Disponible sur son site avec un assistant (toolkit gratuit).
    Il comporte des exemples de code tres clair et un run-time redistribuale.
    Ici le lien Microsoft pour WinForms Toolskit:
    http://www.google.fr/url?sa=t&source...KY9q9LF_NZ76Qg
    Je ne garantis rien dans ta facon de proceder,mais moi je prefere rester dans des demarches balises.

  17. #17
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 13
    Par défaut
    Non attention, ce n'est pas ma classe com qui contient les formulaires. Mais mon projet bibliothèque de classe contient une référence vers mon projet Windows Forms. Dans le projet Windows Forms, il y a une classe "MaClasse", c'est elle qui s'occupe des formulaires.

    Ma classe com n'est là que pour faire le lien entre Excel et l'application, elle prend les paramètres et les transmet. Et cela marche très bien sur mon poste, il y a seulement un problème d'installation sur la machine client.

  18. #18
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut appel de composants net via un classe com de VS
    Bonjour devuranie
    message 'Variable objet ou variable de bloc With non défini" .
    C'est un probleme d'instanciation d'un objet ou d'une simple variable(verifie le code .net si tu n' a pas oublie quelque chose)
    Verifie egalement le marshalling des types ,les erreur sur les types entrainent un rejet sans appel .
    Il ne faut s'attendre à des conversions forcees (genre je mets un entier il va convertir en reel)
    Aussi compiler en VB..NET en strict on et en VBA en strict on,par mesure de precaution.

    Enfin effectivement tu as raison ,tu peux appeler une autre Classe
    "MaClasse" et meme un Winform quoique c'est un peu acrobatique (j'ai fait surtout les add-in office) parce dans la tete il faut avoir "2 cases" etanches une Com et une Net.

    bon voici une autre piste que tu peux explorer et toujours dans la meme direction.
    une interface IDispatch COM au lieu d'une classe COM et des appels à des Winforms directement dans la classe Com pour echanger des donnees.

    code vb.net du projet ClassLibraryInterfaceCom:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
     
    '----------Attribut IntefaceIDispatch garantit que :---------------
    'les parameters et valeurs retour de ses methodes strictement compatible automation (type= VARIANT structure). 
    <Guid("2BE90767-90E8-454a-A9CD-5FD243862E6A"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> _
    Public Interface _ComClass1Inteface
        <DispId(1)> Property NOM() As String
        <DispId(2)> Property VALEUR() As Double
        <DispId(3)> Sub METHOD1()
        <DispId(4)> Function FNTITRE(ByVal NB As Integer, ByVal TITRE As String) As String
        <DispId(5)> Sub AfficheFrmComToNet()
        <DispId(6)> Sub UpdateFrmComToNet()
    End Interface
    'Interface pour les evenements(inutilise)
    <Guid("400FCE44-F9B7-415e-9925-AA9052FB7571"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> _
    Public Interface ComClass1Events
    End Interface
    'attribut ClassInterface(ClassInterfaceType.None) empeche l'exportation de la classe mais
    'laisse visible uniquement l'interface pour les appels clients pour eviter des desagrements 
    'en cas de rajout de proprietes ou methodes non-exportables
    'on peut l'appeler par "New" ou par son nom : "set myobject = createobject ("ComClassInteface") " 
    <Guid("D8493A7F-B03B-4ce5-B934-0333E3DE44CD"), ClassInterface(ClassInterfaceType.None), ProgId("ComClassInteface"), ComSourceInterfaces(GetType(ComClass1Events))> _
    Public Class ComClass1Inteface
        Implements _ComClass1Inteface
        ' Une classe COM pouvant être créée doit avoir Public Sub New() 
        ' sans paramètre, sinon, la classe ne sera pas 
        ' inscrite dans le Registre COM et ne pourra pas être créée 
        ' via CreateObject.
        '---------le WinForm----------------------------------------
        Dim formeToNet As frmComToNet
        Dim fn_titre As String = ""
     
        Public Sub New()
            MyBase.New()
            Me.fn_titre = ""
            Me.x_nom = ""
            Me.x_valeur = 0.0
            Me.formeToNet = New frmComToNet
     
        End Sub
     
        Public Function FNTITRE(ByVal NB As Integer, ByVal TITRE As String) As String Implements _ComClass1Inteface.FNTITRE
            fn_titre = TITRE & "Numero -> " & NB.ToString
            Return TITRE & "Numero -> " & NB.ToString
     
        End Function
     
        Public Sub METHOD1() Implements _ComClass1Inteface.METHOD1
            VALEUR = VALEUR * 2.0
        End Sub
        Private x_nom As String
        Public Property NOM() As String Implements _ComClass1Inteface.NOM
            Get
                Return x_nom
            End Get
            Set(ByVal value As String)
                x_nom = value
            End Set
        End Property
        Private x_valeur As Double
        Public Property VALEUR() As Double Implements _ComClass1Inteface.VALEUR
            Get
                Return x_valeur
            End Get
            Set(ByVal value As Double)
                x_valeur = value
            End Set
        End Property
        '---------------AFFICHE VALEURS DEPUIS Excel VBA---------------
        Public Sub AfficheFrmComToNet() Implements _ComClass1Inteface.AfficheFrmComToNet
            Me.formeToNet.Show()
     
            Me.formeToNet.txtNom.Text = Me.NOM
            Me.formeToNet.txtValeur.Text = Me.VALEUR.ToString
            Me.formeToNet.txtFNTITRE.Text = Me.fn_titre
     
        End Sub
        '---------------AFFECTE & AFFICHE VALEURS VERS Excel VBA ->SUITE AU CLICK BOUTON---------------
        Public Sub UpdateFrmComToNet() Implements _ComClass1Inteface.UpdateFrmComToNet
            Me.NOM = Me.formeToNet.x_Nom
            Me.VALEUR = Me.formeToNet.x_Valeur
        End Sub
    End Class
    '-------------FORME APPELEE DEPUIS CLASSE ComClass1Inteface------------ 
    Imports System
    Imports System.Windows.Forms
    Imports System.Runtime.InteropServices
    Public Class frmComToNet
        '2 parametre transmis à FNTITRE dans ComClass1Inteface
        Public x_Nom As String
        Public x_Valeur As Double
        Public x_paramNB As Integer
        Public x_paramTITRE As String
        Public Sub New()
     
            ' Cet appel est requis par le Concepteur Windows Form.
            InitializeComponent()
     
            ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
            'FENETRE AU DESSUS DES FENETRES VBA et EXCEL(pratique)
            '-----------------------------------------------------
            Me.TopMost = True
        End Sub
        'AFFICHE LES VALEURS DEPUIS ComClass1Inteface
        Private Sub btnDepuisCom_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDepuisCom.Click
            MessageBox.Show("Valeurs depuis ComClass1Inteface")
        End Sub
        'ENVOIE VALEURS CONTROLES NET vers EXCEL
        Private Sub btnVersCom_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnVersCom.Click
            Me.txtNom.Text = "FREDERIC depuis NET"
            Me.txtValeur.Text = "1500,0"
            Me.txtParam1Titre.Text = "255"
            Me.txtParam2Titre.Text = "TITRE depuis NET...."
            x_Nom = Me.txtNom.Text
            x_Valeur = Double.Parse(Me.txtValeur.Text, Globalization.NumberStyles.AllowDecimalPoint)
            x_paramNB = Integer.Parse(Me.txtParam1Titre.Text)
            x_paramTITRE = Me.txtParam2Titre.Text
        End Sub
    End Class
    code VBA du classeur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
     
     
    '-------------Code pour Classe COM avec Interface----------------
    Dim objNet As ClassLibraryInterfaceCom.ComClass1Inteface
     
    'AFFECTE DANS VBA & AFFICHE DANS WINFORM NET
    Private Sub cmdAffecteDansVBA_Click()
     'Appel  aux Prop et Methodes de ComClass1Inteface
        Set objNet = New ClassLibraryInterfaceCom.ComClass1Inteface
     
        objNet.NOM = "Paul"
        objNet.VALEUR = 150#
        Call objNet.METHOD1
        txtNOM.Text = objNet.NOM
        txtVALEUR.Text = CStr(objNet.VALEUR)
        txtFNTITRE.Text = objNet.FNTITRE(2, " Titre depuis EXCEL :")
        Call objNet.AfficheFrmComToNet
    End Sub
    'AFFICHE DEPUIS NET
    Private Sub cmdLitDepuisCOM_Click()
        Call objNet.UpdateFrmComToNet
        lblNOM_fromNet.Caption = objNet.NOM
        lblVALEUR_fromNet.Caption = objNet.VALEUR
    End Sub
    bon code..............

Discussions similaires

  1. Mailing en utilisant VBA dans Excel
    Par martyfourbe dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 28/03/2013, 12h35
  2. [XL-2007] Appeler Une fonction VBa Dans Excel
    Par stevekho dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 23/08/2010, 14h06
  3. piloter access depuis macro vba dans excel
    Par debmlc dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 01/04/2007, 13h41
  4. [VBA-E] Auto incrémentation en VBA dans Excel
    Par gantec dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 13/02/2007, 13h00
  5. Export automatique VBA dans Excel
    Par eddyG dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 20/12/2006, 23h34

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