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 :

[MVSE 2008 - VBA 2007] - Créer une DLL VBNet et l'utiliser dans une macro VBA


Sujet :

VB.NET

  1. #1
    Membre actif
    Avatar de Golard
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 281
    Points : 289
    Points
    289
    Par défaut [MVSE 2008 - VBA 2007] - Créer une DLL VBNet et l'utiliser dans une macro VBA
    Bonjour à tous,

    Je suis déjà intervenu dans plusieurs posts à ce sujet, et vous m'avez donné différentes

    pistes que j'ai étudié.

    Aujourd'hui, je passe à la mise en pratique et comme je n'arrive toujours pas à réaliser le

    Set de ma classe, je me permets de créer ce sujet en espérant bientôt le marquer comme Résolu

    grâce à votre aide

    La solution que je tente de mettre en oeuvre est basée sur les interventions de rv26t dans ce

    post: http://www.developpez.net/forums/d13...cutables-lier/
    et sur l'article de Eric Vernié suivant : http://msdn.microsoft.com/fr-fr/library/bb727303.aspx.



    1ère étape: Création de la DLL sous Microsoft Visual Basic 2008 Express

    Edition


    Je lance l'environnement en tant qu'administrateur, et je créé un projet de type bibliothèque

    de classe.

    Le code est le suivant:

    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
    ''' <summary>L'interface représente un Wrapper de la classe Alarme pour les programmes exe vb6.</summary>
    ''' <remarks>Sera exportée dans la bibliothéque de type créé dans l'assembly.</remarks>
    Public Interface IAlarmes
        Property Nom() As String
        Sub GestAlarme()
    End Interface
     
    ''' <summary>La classe alarme visible.</summary>
    ''' <remarks>Les éléments public seront visible. 
    ''' Bien implémenter toutes les définitions de l'interface.</remarks>
    <ComClass(Alarme.ClassId, Alarme.InterfaceId, Alarme.EventsId)> _
    Public Class Alarme
     
        Implements IAlarmes ' contrat entre classe et interface.
     
    #Region "COM GUIDs"
        ' These  GUIDs provide the COM identity for this class 
        ' and its COM interfaces. If you change them, existing 
        ' clients will no longer be able to access the class.
        Public Const ClassId As String = "4a0e43b3-c03d-4a5e-a236-f2c5494e5325"
        Public Const InterfaceId As String = "19990bbb-65e8-4726-b01e-b1df1b120540"
        Public Const EventsId As String = "6e86907a-52d3-4087-8af6-c341a64a76eb"
    #End Region
     
        Private mNom As String
     
        ''' <summary>Une propriété pour exemple</summary>
        ''' <value>La nouvelle valeur de la propriété.</value>
        ''' <returns>La valeur de la propriété.</returns>
        ''' <remarks>Bien implémenter l'interface.</remarks>
        Public Property Nom() As String _
        Implements IAlarmes.Nom ' implémentation de la propriété définie dans l'interface
            Get
                Return mNom
            End Get
            Set(ByVal value As String)
                mNom = value
            End Set
        End Property
     
        Public Sub New()
            'MyBase.New()
        End Sub
     
        ''' <summary>Une procedure de test.</summary>
        ''' <remarks>Bien implémenter l'interface.</remarks>
        Public Sub GestAlarme() _
        Implements IAlarmes.GestAlarme ' implémentation de la procédure définie dans l'interface
            MsgBox("alarme")
            MsgBox("Mon nom est " & mNom)
        End Sub
     
    End Class
    Dans les propriétés du projet, onglet Application, bouton Assembly Information, je coche

    "Make Assembly code visible":

    Nom : 2-References_Test03_GuidIndependantDuCodeDeLaClass.png
Affichages : 1265
Taille : 22,0 Ko

    Je compile via le menu Build et j'obtiens le fichier Alarmes.dll



    2ème étape: Création du fichier .tlb

    A présent que je dispose du fichier Alarmes.dll, il faut construire la bibiothèque de type

    Alarmes.tlb (car celle-ci ne peut pas être générée automatiquement avec la version Express)

    Pour cela, j'ai testé 2 solutions qui donnent (à priori) le même résultat:

    a) En utilisant Regasm

    Je place Regasm.exe dans le même répertoire que Alarmes.dll
    J'ouvre la console "invite de commandes" en tant qu'administrateur
    Je tape la commande:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Regasm Alarmes.dll /tlb
    b) En utilisant l'outil mis à disposition par Eric Vernié (cf référence de l'article plus

    haut)

    Dans les 2 cas j'obtiens le fichier Alarmes.tlb



    3ème étape: Ecriture de la macro sous Excel Office 2007


    J'ajoute la référence à la DLL en utilisant le fichier Alarmes.tlb
    Dans un module VBA, je tape le code suivant :

    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
    Option Explicit
     
    Private monAlarme As Alarmes.Alarme ' la classe vb.net
    Private monAlInt As Alarmes.IAlarmes ' l'interface pour vb6
     
    ' programmation classique (miracle)
    Sub Bouton2_Clic()
    '
    ' Bouton2_Clic Macro
    '
    Set monAlarme = New Alarmes.Alarme ' implémente la classe alarme (nous avons un objet alarme)
    Set monAlInt = monAlarme ' récupère l'interface à partir de l'objet alarme (permet d'avoir 
     
    l'Intellisense ce qui est très pratique)
     
    MsgBox "clic sur le bouton"
    monAlInt.Nom = "alarme1" ' attribue un nom
    Call monAlInt.GestAlarme ' appele la sub
    'Call GestAlarme ' appele la sub
     
    Set monAlarme = Nothing
    Set monAlInt = Nothing
     
    End Sub
    Le code est donc déclenché par l'appui sur un bouton (Bouton2).

    Malheureusement, ça ne fonctionne pas.

    J'obtiens l'erreur suivante:

    Nom : 5a-Erreur_test03_AppelDepuisVBA.png
Affichages : 1099
Taille : 14,8 Ko

    L'erreur survient au Set de la classe:

    Nom : 5b-Erreur_test03_AppelDepuisVBA.png
Affichages : 1431
Taille : 109,3 Ko



    J'ai vraiment besoin de votre aide !!!

    Pour commencer, je ne comprends pas à quoi correspond le numéro GUID présent sur la fenêtre "Assembly Information" (cf image jointe), car il n'en est pas question dans les articles en référence. En y mettant le même numéro que celui de la ClassId du code de la classe, je n'arrive plus à générer le fichier .tlb

    Je tourne en rond depuis plusieurs jours et je compte sur vos lumières !



    (PS: Si l'emplacement de ce post est plutôt dans la section Office VBA, n'hésitez pas à me

    le signaler ou à le déplacer)

    Développement VBNet sous Visual Studio Community 2013 (environnement Windows 10)

  2. #2
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    Bonjour,

    En .net ton assembly s'appele Alarmes ?
    [Edit] Tes liens sont incorrects.
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

  3. #3
    Membre actif
    Avatar de Golard
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 281
    Points : 289
    Points
    289
    Par défaut
    Citation Envoyé par rv26t Voir le message
    Bonjour,

    En .net ton assembly s'appele Alarmes ?
    Oui, voici la copie d'écran de l'onglet Application :

    Nom : 2b-OngletApplication_Test03.png
Affichages : 1210
Taille : 110,0 Ko

    Dans le code VBA, l'implémentation fonctionne correctement :

    Nom : 5c-implementationCorrecteAlarmesAlarme_test03.png
Affichages : 960
Taille : 2,5 Ko

    Développement VBNet sous Visual Studio Community 2013 (environnement Windows 10)

  4. #4
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    Je ne vois pas le souci.
    Je viens de tester la ligne qui te pose problème passe chez moi, mais cela plante la ligne d'après pour l'interface, mais comme j'ai tout modifié dans la dll vb.net, il faut que je regarde.

    [Edit]J'ai corrigé par rapport à mes modif et cela fonctionne. (j'ouvre même un formulaire vb.net), j'ai lancé le code direct en debug, pas à travers un bouton.
    Note : dans mon projet, l'espace de noms racine s'appele aussi Alarmes

    [Edit2] L'erreur est bizarre et laisse penser à un problème d'accès fichier. ???
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

  5. #5
    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,

    As-tu ajouté la référence à Alarmes.dll dans le projet VBA ? (Outils-Références)

    Dans ce cas, sauf horreur de ma part, il faut ajouter la référence, comme pour toute autre bibliothèque COM externe


    Oupss! À la relecture il semblerait que la référence est bien là.

    Je laisse quand même le message au cas où...
    À 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.

  6. #6
    Membre actif
    Avatar de Golard
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 281
    Points : 289
    Points
    289
    Par défaut
    Tout d'abord, merci de vous pencher sur mon problème, j'espère qu'on va y arriver

    Citation Envoyé par rv26t Voir le message
    [Edit]J'ai corrigé par rapport à mes modif et cela fonctionne. (j'ouvre même un formulaire vb.net), j'ai lancé le code direct en debug, pas à travers un bouton.
    Note : dans mon projet, l'espace de noms racine s'appele aussi Alarmes
    J'ai renommé mon espace de noms racine Alarmes comme toi:
    Assembly name = Alarmes
    Root namespace = Alarmes (au lieu de ClassLibrary1)

    ça ne change rien, même erreur (même en lançant le code direct en debug)

    Citation Envoyé par rv26t Voir le message
    [Edit2] L'erreur est bizarre et laisse penser à un problème d'accès fichier. ???
    J'ai ouvert Excel en administrateur, ça ne change rien

    Citation Envoyé par clementmarcotte Voir le message
    As-tu ajouté la référence à Alarmes.dll dans le projet VBA ? (Outils-Références)
    Oui, voici les références du projet VBA:

    Nom : 5c-References-VBAProject_test04.png
Affichages : 1238
Taille : 37,0 Ko

    Manquerait-il une référence nécessaire au fonctionnement de l'interopérabilité COM ?

    Sinon, que pensez-vous du fait qu'il y ait 4 GUIDs différents dans mon projet vbnet ? est-ce pareil chez vous ?

    Développement VBNet sous Visual Studio Community 2013 (environnement Windows 10)

  7. #7
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    Je n'ai pas de GUId dans le code.
    Par contre j'ai un fichier de signature (propriété du projet, onglet signature), je ne sais pas si cela a un impact, mais j'ai vu que c'était conseillé. (je ne me souvient plus comment je l'avais généré, mais on doit pouvoir le retrouver)
    Je ne peux pas voir les autres points pour l'instant, je reprend cela plus tard.
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

  8. #8
    Membre actif
    Avatar de Golard
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 281
    Points : 289
    Points
    289
    Par défaut
    Peux-tu poster ton code sans GUID (le code de la classe) afin que je le teste ?
    Tu n'as donc pas la ligne "<ComClass ..." dans ton code ?
    Si il ne fonctionne pas chez moi, j'essayerais de créer un fichier signature.

    Pour complément, je suis sous windows 7 64 bits, Visual Basic Express 2008 et Office 2007... et toi ?

    Développement VBNet sous Visual Studio Community 2013 (environnement Windows 10)

  9. #9
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    Vista, VS2010 pro, excel 2007

    Voici le code simplifié
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ''' <summary>L'interface représente un Wrapper de la classe Alarme pour les programmes exe vb6. (elle expose les propriétés et les méthodes)</summary>
    ''' <remarks>Sera exportée dans la bibliothéque de type créé dans l'assembly.</remarks>
    <InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> Public Interface IAlarmes
      Sub GestAlarme()
    End Interface
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ''' <summary>La classe qui implémentes les méthodes et les évènements.</summary>
    <ClassInterface(ClassInterfaceType.None)> _
    Public Class InterfaceAlarme
      Implements IAlarmes ' contrat entre classe et interface.
     
      Private fenAlarmes As frmAlarmes = New frmAlarmes
     
        ''' <summary>Ouvre la fenêtre des alarmes.</summary>
      Public Sub GestAlarme() Implements IAlarmes.GestAlarme
          fenAlarmes.Show() 'fenAlarmes.ShowDialog()
        End Sub
     
    End Class
    un formulaire frmAlarmes

    Le code vba dns un module
    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
     
     
     Private monAlarme As Alarmes.InterfaceAlarme  ' la classe vb.net
     Private monAlInt As Alarmes.IAlarmes ' l'interface pour vb6
     
    Sub dllvbnet()
     
    Set monAlarme = New Alarmes.InterfaceAlarme ' implémente la classe alarme (nous avons un objet alarme)
    ' monAlarme pourrait être utilisé directement
    Set monAlInt = monAlarme ' récupère l'interface à partir de l'objet alarme (permet d'avoir l'Intellisense ce qui est très pratique)
    Call monAlInt.GestAlarme  ' appele la sub
     
    Set monAlarme = Nothing
    Set monAlInt = Nothing
     
    End Sub

    Le code complet complet
    Les interfaces
    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
    Imports System.Runtime.InteropServices
     
    ''' <summary>Cette interface expose les évènements.</summary>
    <InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> Public Interface _EventInterface
      ' Attention Danger : le type integer en vb.dll correspond au type long en vb6
      <DispId(1)> Sub UnEvent(ByVal test As String, ByVal x As Integer) ' un évènement qui sera disponible sous vb6 (NomInstanceClasse_UnEvent)
      <DispId(6)> Sub OnChangeEnabled(ByVal X As Integer, ByVal Y As Integer, ByVal Valeur As Boolean)
    End Interface
     
    ''' <summary>L'interface représente un Wrapper de la classe Alarme pour les programmes exe vb6. (elle expose les propriétés et les méthodes)</summary>
    ''' <remarks>Sera exportée dans la bibliothéque de type créé dans l'assembly.</remarks>
    <InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> Public Interface IAlarmes
      <DispId(2)> Sub GestAlarme()
      <DispId(3)> Sub AjoutAlarme(ByVal UnId As String, ByVal LaPriorite As Integer)
      <DispId(4)> Sub LitAlarmes(ByVal UnId As String, ByRef LaPriorite As Integer)
      <DispId(5)> Function existe() As Boolean
    End Interface
    les éléments <DispId...> ne sont pas indispensable (simplement dans certains cas on peut accéder par son numéro si présent)

    La classe d'implémentation de l'interface
    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
    ''' <summary>La classe qui implémentes les méthodes et les évènement.
    ''' Les évènement pour vb6 sont exposés par l'utilisation de l'attribut ComSourceInterfaces.</summary>
    <ClassInterface(ClassInterfaceType.None)> <ComSourceInterfaces(GetType(_EventInterface))> _
    Public Class InterfaceAlarme
      Implements IAlarmes ' contrat entre classe et interface.
      ' Attention Danger : le type integer en vb.dll correspond au type long en vb6
      Public Event OnChangeEnabled(ByVal X As Integer, ByVal Y As Integer, ByVal Valeur As Boolean)
      Public Event UnEvent(ByVal test As String, ByVal x As Integer)
     
      Private fenAlarmes As frmAlarmes = New frmAlarmes
      Private MesAlarmes As DesAlarmes = DesAlarmes.GetInstance ' pas de new, il sera fait une seule fois dans Getinstance, c'est cette sub qui vérifie l'unicité.
     
      ''' <summary>Abonne les évènement interne à la DLL.</summary>
      ''' <remarks>En automatique sur instanciation de la classe, ainsi le prog. vb6 n'a rien à faire</remarks>
      Public Sub New()
        AddHandler MesAlarmes.EventEtatFaux, AddressOf MesAlarmes_EventEtatFaux
        AddHandler MesAlarmes.OnChangeEnabled, AddressOf MesAlarmes_OnChangeEnabled
      End Sub
     
      ''' <summary>Déclenche un évènement pour le progr. vb6.</summary>
      Public Sub MesAlarmes_OnChangeEnabled()
        RaiseEvent UnEvent("teste", 10) ' Envoie l'évènement à vb6
        RaiseEvent OnChangeEnabled(10, 15, True) ' Envoie l'évènement à vb6
      End Sub
     
      ''' <summary>Déclenche un évènement pour le progr. vb6.</summary>
      Public Sub MesAlarmes_EventEtatFaux()
        RaiseEvent UnEvent("teste", 11) ' Envoie l'évènement à vb6
      End Sub
     
      ''' <summary>Ajoute une alarme au dictionnaire.</summary>
      ''' <param name="UnId">Identifiant d'une alarme.</param>
      ''' <param name="LaPriorite">Une priorité.</param>
      ''' <remarks></remarks>
      Public Sub AjoutAlarme(ByVal UnId As String, ByVal LaPriorite As Integer) Implements IAlarmes.AjoutAlarme
        Dim NouvelleAlarme As UneAlarme = New UneAlarme
        NouvelleAlarme.IdAlarm = UnId
        NouvelleAlarme.ChangeNiveauPriorite(LaPriorite)
        MesAlarmes.DicoAlarmes.Add(NouvelleAlarme.IdAlarm, NouvelleAlarme)
      End Sub
     
        ''' <summary>Ouvre la fenêtre des alarmes.</summary>
      Public Sub GestAlarme() Implements IAlarmes.GestAlarme
        fenAlarmes.MesAlarmes = MesAlarmes ' donne les alarmes à la fenêtre
        Try
          fenAlarmes.Show() 'fenAlarmes.ShowDialog()
        Catch ex As Exception
          fenAlarmes = New frmAlarmes
          fenAlarmes.MesAlarmes = MesAlarmes ' donne les alarmes à la fenêtre
          fenAlarmes.Show()
        End Try
        End Sub
     
      Public Sub LitAlarmes(ByVal UnId As String, ByRef LaPriorite As Integer) Implements IAlarmes.LitAlarmes
        LaPriorite = MesAlarmes.DicoAlarmes(UnId).Priority
      End Sub
     
      Public Function existe() As Boolean Implements IAlarmes.existe
        Return True
      End Function
     
      ''' <summary>Désabonne les évènement interne à la DLL.</summary>
      Protected Overrides Sub Finalize()
        RemoveHandler MesAlarmes.EventEtatFaux, AddressOf MesAlarmes_EventEtatFaux
      End Sub
     
    End Class
    La classe des alarmes
    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
    Public Class DesAlarmes
     
      Private Shared _InstanceAlarmesUnique As DesAlarmes
      Public Event EventEtatFaux As EventHandler
      Public Event OnChangeEnabled As EventHandler
     
      Public _X As Integer
      Public _Y As Integer
      Public _Value As Boolean
     
    #Region "Unicité singleton"
      ''' <summary>GetInstance permet de récupérer une instance unique de "DesAlarmes"</summary>
      ''' <returns>Une instance unique.</returns>
      ''' <remarks>Si l'instance n'existe pas renvoie celle créée, sinon renvoie celle qui existe</remarks>
      Public Shared Function GetInstance() As DesAlarmes
        If _InstanceAlarmesUnique Is Nothing Then _InstanceAlarmesUnique = New DesAlarmes()
        Return _InstanceAlarmesUnique
      End Function
    #End Region
     
      Private mDicoAlarmes As Dictionary(Of String, UneAlarme) = New Dictionary(Of String, UneAlarme)
      Public Property DicoAlarmes() As Dictionary(Of String, UneAlarme)
        Get
          Return mDicoAlarmes
        End Get
        Set(ByVal value As Dictionary(Of String, UneAlarme))
          mDicoAlarmes = value
        End Set
      End Property
     
      Private mLigneDGVTraitee As Integer
      Public Property LigneDGVTraitee() As Integer
        Get
          Return mLigneDGVTraitee
        End Get
        Set(ByVal value As Integer)
          mLigneDGVTraitee = value
        End Set
      End Property
     
      ''' <summary>Donne le nombre d'une priorité donnée.</summary>
      ''' <param name="LaPriorite">La priorité à compter.</param>
      ''' <returns>Le nombre d'alarme trouvé ayant cette priorité.</returns>
      ''' <remarks>Linq</remarks>
      Public Function LinqNbAlarmesDePriorite(ByVal LaPriorite As Integer) As Integer
        Return (From entree In DicoAlarmes Where (entree.Value.Priority = LaPriorite) Select entree).Count
      End Function
      'est équivalent à 
      Public Function NbAlarmesDePriorite(ByVal LaPriorite As Integer) As Integer
        Dim NbAlarmes As Integer
        Dim paire As KeyValuePair(Of String, UneAlarme)
        For Each paire In DicoAlarmes
          If paire.Value.Priority = LaPriorite Then NbAlarmes += 1
        Next
        Return NbAlarmes
      End Function
     
      Public Sub EtatFaux()
        RaiseEvent EventEtatFaux(Me, New System.EventArgs) ' évènement interne DLL
      End Sub
     
      Public Sub PositionneEtat(ByVal X As Integer, ByVal Y As Integer, ByVal Value As Boolean)
        _X = X
        _Y = Y
        _Value = Value
        RaiseEvent OnChangeEnabled(Me, New System.EventArgs) ' évènement interne DLL
      End Sub
     
     
      Public Sub Calcul()
        '...
      End Sub
     
    End Class
    La classe alarme
    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
    ''' <summary>Définie une alarme</summary>
    Public Class UneAlarme
      Const PrioriteMin As Integer = 0 ' pour exemple (doivent être en fichier de config ou BDD)
      Const PrioriteMax As Integer = 10
     
      Private mPriority As Integer
      ' en lecture seule, la fonction ChangeNiveauPriorite vérifie la validité de la nouvelle priorité avant de la placer dans la propriété Priority
      Public ReadOnly Property Priority() As Integer
        Get
          Return mPriority
        End Get
      End Property
     
      'vérifie la validité de la nouvelle priorité 
      Public Sub ChangeNiveauPriorite(ByVal Niveau As Integer)
        If (PrioriteMin <= Niveau <= PrioriteMax) Then mPriority = Niveau
      End Sub
     
      Private mIdAlarm As String
      Public Property IdAlarm() As String
        Get
          Return mIdAlarm
        End Get
        Set(ByVal value As String)
          mIdAlarm = value
        End Set
      End Property
     
        'autres prop non implémenté.
     
      'Etat = False
      Private mEtat As Boolean
      Public Property Etat() As Boolean
        Get
          Return mEtat
        End Get
        Set(ByVal value As Boolean)
          mEtat = value
        End Set
      End Property
     
      'Supprimer = False
      Private mSupprimer As Boolean
      Public Property Supprimer() As Boolean
        Get
          Return mSupprimer
        End Get
        Set(ByVal value As Boolean)
          mSupprimer = value
        End Set
      End Property
     
    End Class
    La fenêtre (2 datagridview, 2 boutons, 1 textbox, labels, contextmenu)
    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
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    Imports System.Windows.Forms
     
    Public Class frmAlarmes
     
      Private mMesAlarmes As DesAlarmes
      Public Property MesAlarmes() As DesAlarmes
        Get
          Return mMesAlarmes
        End Get
        Set(ByVal value As DesAlarmes)
          mMesAlarmes = value
        End Set
      End Property
     
        'pour test
      Private Sub ActionChangeNiveauA2()
        mMesAlarmes.DicoAlarmes("a1").ChangeNiveauPriorite(2)
      End Sub
     
      Private Sub frmAlarmes_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'ActionChangeNiveauA2()
        'Try
        '  Dim pair As KeyValuePair(Of String, UneAlarme)
        '  For Each pair In MesAlarmes.DicoAlarmes
        '    System.Windows.Forms.MessageBox.Show(" GestAlarme " & pair.Key & " " & pair.Value.IdAlarm)
        '  Next
        'Catch ex As Exception
        '  System.Windows.Forms.MessageBox.Show(ex.Message)
        'End Try
     
        'Label1.Text = mMesAlarmes.DicoAlarmes("a1").IdAlarm
        'Label2.Text = mMesAlarmes.DicoAlarmes("a1").Priority
     
        MonDGW.AutoGenerateColumns = True
        MonDGW.DataSource = MesAlarmes.DicoAlarmes.Select((Function(kv) New With {.LesCles = kv.Key, .LesPriorités = kv.Value.Priority})).ToArray
        dgvPri.AutoGenerateColumns = True
      End Sub
     
      Private Sub btnNbAlPArPri_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNbAlPArPri.Click
        lblNbAlPArPri.Text = "Nombre d'alarme de priorité (" & txtNbAlPArPri.Text & ") : " _
          & MesAlarmes.NbAlarmesDePriorite(Integer.Parse(txtNbAlPArPri.Text))
     
        lblLinq.Text = "Nombre d'alarme de priorité (" & txtNbAlPArPri.Text & ") Linq  : " _
          & MesAlarmes.LinqNbAlarmesDePriorite(Integer.Parse(txtNbAlPArPri.Text))
     
        dgvPri.DataSource = (From entree In MesAlarmes.DicoAlarmes Where (entree.Value.Priority = Integer.Parse(txtNbAlPArPri.Text)) Select entree).Select((Function(kv) New With {.LesCles = kv.Key, .LesPriorités = kv.Value.Priority})).ToArray
      End Sub
     
      Private Sub AffichierMenu_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles MonDGW.CellMouseDown
     
        If e.Button = MouseButtons.Right Then ' Lorsqu'on fait un click *droit*
          'un try ... catch pour eviter une exception au clic sur une entete        
          Try
            MonDGW.Rows(e.RowIndex).Selected = True
            MesAlarmes.LigneDGVTraitee = e.RowIndex
            OuvrirMenu(e.RowIndex) 'Ouvre un menu
          Catch ex As ArgumentOutOfRangeException
          End Try
     
        End If
     
      End Sub
     
      'Procedure qui permet d'ouvrir un menu
      Private Sub OuvrirMenu(ByVal e As Object)
        ' Create a new ContextMenuStrip control.
        Dim z As Integer
        ContextMenuStrip1 = New ContextMenuStrip()
        AddHandler ContextMenuStrip1.Opening, AddressOf cms_Opening
     
        For z = 0 To MonDGW.Rows.Count - 1
          If MonDGW.Rows(z).Selected = True Then
            MonDGW.Rows(z).ContextMenuStrip = ContextMenuStrip1
          End If
        Next
     
      End Sub
      'Procedure qui contient ce qui ce trouve dans le menu
      Private Sub cms_Opening(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs)
        ' Acquire references to the owning control and item.
        Dim c As Control = ContextMenuStrip1.SourceControl
        Dim tsi As ToolStripDropDownItem = ContextMenuStrip1.OwnerItem
     
        ' Clear the ContextMenuStrip control's 
        ' Items collection.
        ContextMenuStrip1.Items.Clear()
     
        ' Populate the ContextMenuStrip control with its default items.
     
        ContextMenuStrip1.Items.Add("Continue Updating")
        AddHandler ContextMenuStrip1.Items(0).Click, AddressOf cms_Click
        ContextMenuStrip1.Items.Add("-")
        ContextMenuStrip1.Items.Add("Acknowledge Single Alarm")
        AddHandler ContextMenuStrip1.Items(2).Click, AddressOf cms_Click
        ContextMenuStrip1.Items.Add("-")
        ContextMenuStrip1.Items.Add("Open Control Display")
        AddHandler ContextMenuStrip1.Items(4).Click, AddressOf cms_Click
        ContextMenuStrip1.Items.Add("Open Faceplate Display")
        AddHandler ContextMenuStrip1.Items(5).Click, AddressOf cms_Click
        ContextMenuStrip1.Items.Add("Open Detail Display")
        AddHandler ContextMenuStrip1.Items(6).Click, AddressOf cms_Click
        ContextMenuStrip1.Items.Add("-")
        ContextMenuStrip1.Items.Add("Suppress Alarm")
        AddHandler ContextMenuStrip1.Items(8).Click, AddressOf cms_Click
        ' Set Cancel to false. 
        ' It is optimized to true based on empty entry.
        e.Cancel = False
      End Sub
     
      Public Sub cms_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        If sender.text = "Suppress Alarm" Then
          Dim z As Integer
          'MessageBox.Show(sender.text & " = Suppress Alarm")
          For z = 0 To MonDGW.Rows.Count - 1
            If MonDGW.Rows(z).Selected = True Then
              'mMesAlarmes.DicoAlarmes(MonDGW.SelectedRows(0).Cells(3).EditedFormattedValue).Supprimer = True
              'MesAlarmes.DicoAlarmes(MonDGW.Rows(MesAlarmes.LigneDGVTraitee).Cells(3).EditedFormattedValue).Supprimer = True
              'MesAlarmes.DicoAlarmes(MonDGW.Rows(MesAlarmes.LigneDGVTraitee).Cells(3).EditedFormattedValue).Etat = False
              'mMesAlarmes.DicoAlarmes("a1").Etat = True
              'mMesAlarmes.DicoAlarmes(MonDGW.SelectedRows(0).Cells(3).EditedFormattedValue).Etat = False
              'MonDGW.Rows.RemoveAt(MesAlarmes.LigneDGVTraitee)
              MesAlarmes.EtatFaux()
              'FenPoubelle.MesAlarmes = MesAlarmes
              Exit Sub
            End If
          Next
        End If
      End Sub
     
      Public aInterfaceAlarme As InterfaceAlarme
      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Try
          'aInterfaceAlarme.aEventAlarme.OnChangeEnable()
          MesAlarmes.PositionneEtat(10, 15, True)
        Catch ex As Exception
          MessageBox.Show(ex.Message)
        End Try
      End Sub
    End Class

    Le code vba dans code feuille
    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
     
     Private monAlarme As Alarmes.InterfaceAlarme  ' la classe vb.net
     Private monAlInt As Alarmes.IAlarmes ' l'interface pour vb6
     
    Sub dllvbnet()
     
    Set monAlarme = New Alarmes.InterfaceAlarme ' implémente la classe alarme (nous avons un objet alarme)
    Call monAlarme.AjoutAlarme("1", 1)
    Call monAlarme.AjoutAlarme("2", 2)
    Set monAlInt = monAlarme ' récupère l'interface à partir de l'objet alarme (permet d'avoir l'Intellisense ce qui est très pratique)
    Call monAlInt.AjoutAlarme("3", 3)
    Call monAlInt.AjoutAlarme("4", 4)
    Call monAlInt.GestAlarme  ' appele la sub (ouvre une fenêtre)
     
    Set monAlarme = Nothing
    Set monAlInt = Nothing
     
    End Sub
    Après premier essai placer les ajout en commentaire

    Nom : alarmes.jpg
Affichages : 1179
Taille : 64,0 Ko

    Comme cela était des essais, le code est un peu en vrac
    J'ai mis le projet en pièce jointe.
    Fichiers attachés Fichiers attachés
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

  10. #10
    Membre actif
    Avatar de Golard
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 281
    Points : 289
    Points
    289
    Par défaut
    Merci pour ton suivi

    Je vais tester ton code de ce pas.
    Mais je vais devoir le recréer dans MVBE2008 car j'ai le message suivant à l'ouverture:
    Nom : CannotBeOpenedByMVBE2008.png
Affichages : 1015
Taille : 12,4 Ko

    Toi par contre, tu devrais pouvoir ouvrir ma solution que je te mets en pièce jointe (si tu as le temps de la tester).
    Alarmes-Golard.7z

    Je te tiens rapidement au courant.

    Développement VBNet sous Visual Studio Community 2013 (environnement Windows 10)

  11. #11
    Membre actif
    Avatar de Golard
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 281
    Points : 289
    Points
    289
    Par défaut
    Toujours la même erreur...

    Je passe en détail toutes les étapes de mon test, au cas où tu remarques quelque-chose qui cloche

    J'ai réécris ton code simplifié dans un nouveau projet de type class library:
    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
    Imports System.Runtime.InteropServices
    ''' <summary>L'interface représente un Wrapper de la classe Alarme pour les programmes exe vb6. (elle expose les propriétés et les méthodes)</summary>
    ''' <remarks>Sera exportée dans la bibliothéque de type créé dans l'assembly.</remarks>
    <InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> Public Interface IAlarmes
        Sub GestAlarme()
    End Interface
    ''' <summary>La classe qui implémentes les méthodes et les évènements.</summary>
    <ClassInterface(ClassInterfaceType.None)> _
    Public Class InterfaceAlarme
        Implements IAlarmes ' contrat entre classe et interface.
     
        Private fenAlarmes As frmAlarmes = New frmAlarmes
     
        ''' <summary>Ouvre la fenêtre des alarmes.</summary>
        Public Sub GestAlarme() Implements IAlarmes.GestAlarme
            fenAlarmes.Show() 'fenAlarmes.ShowDialog()
        End Sub
     
    End Class
    Public Class Alarme
    End Class
    J'ai coché la case "Make assembly COM-visible"
    J'ai buildé la solution (avec mvbe2008 ouvert en administrateur) ==> Alarmes.dll

    J'ai recopié la dll dans le dossier où je vais créé le xlsm
    J'ai ensuite créé le tlb avec Regasm ==> Alarmes.tlb

    J'ai créé un nouveau xlsm et j'ai ajouté la référence en pointant sur Alarmes.tlb
    J'ai écrit le code suivant dans un nouveau module:
    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
     
     Private monAlarme As Alarmes.InterfaceAlarme  ' la classe vb.net
     Private monAlInt As Alarmes.IAlarmes ' l'interface pour vb6
     
    Sub dllvbnet()
     
    Set monAlarme = New Alarmes.InterfaceAlarme ' implémente la classe alarme (nous avons un objet alarme)
    'Call monAlarme.AjoutAlarme("1", 1)
    'Call monAlarme.AjoutAlarme("2", 2)
    Set monAlInt = monAlarme ' récupère l'interface à partir de l'objet alarme (permet d'avoir l'Intellisense ce qui est très pratique)
    'Call monAlInt.AjoutAlarme("3", 3)
    'Call monAlInt.AjoutAlarme("4", 4)
    Call monAlInt.GestAlarme  ' appele la sub (ouvre une fenêtre)
     
    Set monAlarme = Nothing
    Set monAlInt = Nothing
     
    End Sub
    Pour qu'il n'y ait aucun doute, je te joins la solution de la classe: Alarmes-ReecritEn2008Express-VersionLight.zip

    Et aussi le fichier xlsm, ainsi que les fichiers Alarmes.dll Alarmes.tlb: Dll_Test06.zip

    Pourrais-tu regarder voir si ça fonctionne chez toi ?
    Le contenu du fichier tlb est-il correctement généré ?

    Merci Merci pour le temps que tu me consacres !!!

    Développement VBNet sous Visual Studio Community 2013 (environnement Windows 10)

  12. #12
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    Citation Envoyé par Golard Voir le message
    Pour qu'il n'y ait aucun doute, je te joins la solution de la classe: Alarmes-ReecritEn2008Express-VersionLight.zip

    Pourrais-tu regarder voir si ça fonctionne chez toi ?
    Le contenu du fichier tlb est-il correctement généré ?
    J'ai régénéré la solution sous vs2010, ouvert un classeur excel et copié le code d'appel à la dll, cela fonctionne.
    Avec ton xls et le tlb régénéré aussi.
    Je ne peux pas savoir si ton fichier tlb est correct.

    (en lancant excel en admin, il me semble que tu as essayé)
    Peux-tu tester en mode compatibilité vista

    En p.j. le fichier tlb régénéré sous vs2010
    Fichiers attachés Fichiers attachés
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

  13. #13
    Membre actif
    Avatar de Golard
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 281
    Points : 289
    Points
    289
    Par défaut
    Citation Envoyé par rv26t Voir le message
    En p.j. le fichier tlb régénéré sous vs2010
    En plaçant ma dll, mon xlsm et ton tlb dans un même dossier, je n'arrive pas à ajouter la référence à la dll dans le projet VBA.
    Quand je sélectionne le fichier tlb, aucun message d'erreur n'apparait, mais rien ne se passe

    Citation Envoyé par rv26t Voir le message
    (en lancant excel en admin, il me semble que tu as essayé)
    Peux-tu tester en mode compatibilité vista
    Lancer EXCEL.EXE en tant qu'administrateur semble en effet ne rien changer.
    Par contre que dois-je mettre en mode compatibilité Visa et comment... je ne comprends pas.

    Ce qui se passe avec ton fichier tlb est-il une piste ?
    Le Regasm.exe que j'utilise provient d'internet car il n'est pas inclus dans Visual Studio Express...
    D'où l'hypothèse que mon tlb ne serait peut-être pas bien construit...
    Mais pourquoi ne puis-je pas utiliser ton tlb ??? Faut-il que j'installe un SDK particulier ?
    Crois-tu que ça vaille la peine que j'installe Visual Studio Express 2012 ou ça risque de ne rien changer ?

    Désolé pour toutes ces questions, mais je me sens un peu perdu !

    Développement VBNet sous Visual Studio Community 2013 (environnement Windows 10)

  14. #14
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    Citation Envoyé par Golard Voir le message
    En plaçant ma dll, mon xlsm et ton tlb dans un même dossier, je n'arrive pas à ajouter la référence à la dll dans le projet VBA.
    Quand je sélectionne le fichier tlb, aucun message d'erreur n'apparait, mais rien ne se passe :marteau
    ...
    Ce qui se passe avec ton fichier tlb est-il une piste ?
    Le Regasm.exe que j'utilise provient d'internet car il n'est pas inclus dans Visual Studio Express...
    D'où l'hypothèse que mon tlb ne serait peut-être pas bien construit...
    Mais pourquoi ne puis-je pas utiliser ton tlb ??? Faut-il que j'installe un SDK particulier ?
    Crois-tu que ça vaille la peine que j'installe Visual Studio Express 2012 ou ça risque de ne rien changer ?

    Désolé pour toutes ces questions, mais je me sens un peu perdu !
    Pas de souci pour les questions.

    Pour Visual Studio Express 2012 , je ne sais pas trop, mais je ne pense pas que cela change quelques chose. (après tu peux toujours essayer)

    J'aurai peut-être du mettre aussi la dll (mais bon ça il faut éviter c'est comme un exe, passe un coup d'antivirus), le tlb n'est peut-être qu'un wrapper qui permet d'utiliser la dll. Je te met les 2.
    Part bien d'un excel vide et rajoute la référence (qu'il ne pointe pas sur autre chose) en allant bien dans le répertoire ou tu places le tlb et la dll.

    Après, il y a peut être des restrictions d'utilisation de fichier sous windows 7. Je ne sais pas s'il faut l'enregistrer avec "regasm.exe" pour que windows 7 le prenne en compte (inscrire le composant sur l'ordinateur) ou un autre utilitaire. Le message est toujours l'erreur sur l'accès fichier ?
    N'ayant pas l'erreur difficile de tester, je ne peux que supposer. Je vais chercher un peu sur internet.

    [Edit]Tes liens du 1er post sont incorrects.
    Fichiers attachés Fichiers attachés
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

  15. #15
    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,


    Citation Envoyé par Golard Voir le message
    Le Regasm.exe que j'utilise provient d'internet car il n'est pas inclus dans Visual Studio Express...
    RegAsm est fourni par le Framework et non pas par VisualStudio. Je ne serais pas surpris que tu ais ramassé le mauvais RegAsm pour le mauvais Framework.

    Chez-moi, le Framework le plus récent est 4.5.2

    En version 32 bits Regasm est à:

    C:\windows\Microsoft.NET\Framework\v4.0.30319

    En version 64 bits c'est :

    C:\windows\Microsoft.NET\Framework64\v4.0.30319

    J'ai regardé sommairement les Frameworks plus anciens et il semble que Regasm a été effacé au moment de l'installation de 4.5.2 parce qu'il ne semble plus être là.
    À 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.

  16. #16
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    bien vu clementmarcotte.
    Celui de ton framework devrait enregistrer la dll et générer le tlb correctement.
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

  17. #17
    Membre actif
    Avatar de Golard
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 281
    Points : 289
    Points
    289
    Par défaut
    On avance !

    J'utilise à présent le Regasm.exe présent dans C:\Windows\Microsoft.NET\Framework64\v4.0.30319
    J'ai choisi celui-ci car je suis sous seven 64 bits ... est-ce bien ce qu'il faut faire ?
    Est-ce que le xlsm ne fonctionnera ensuite que pour des postes 64 bits ???

    Bref, j'ai repris mon test initial (post #1) ainsi que la version "light" de rv26t (post #9).
    Dans les 2 cas, l'erreur est à présent la fameuse erreur 429
    Nom : ErreurVBA-429.png
Affichages : 1086
Taille : 10,0 Ko

    Je pense que ceci va nous donner de nouvelles pistes ...

    Je me pose toujours la question concernant les GUID de mon post initial : Est-ce normal de préciser 3 numéros GUID dans la ligne <ComClass... de la classe + un 4ème GUID dans la fenêtre "Assembly Information" ? Ce dernier devrait-il correspondre à l'un des 3 autres ?

    En tout cas merci à vous 2 pour vos efforts !!!
    En attendant demain, et peut-être la solution, bonne nuit !

    PS: j'ai corrigé les 2 liens du post #1

    Développement VBNet sous Visual Studio Community 2013 (environnement Windows 10)

  18. #18
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    As-tu fait cette étape dans VS (as tu accès dans la version express ?)

    compléter au niveau des propriétés du projet
    * Application
    bouton information de l'assembly
    cocher : rendre l'assembly visible par COM
    Titre et Description (ok).

    Celle-la
    * Compiler
    cocher : inscrire pour COM Interop
    Etant faite manuellement avec regasm, puisque tu n'as pas la case à cocher

    Pour les GUID, je n'ai que celle du projet, présent dans "information de l'assembly".

    Tu devrais essayer en 32.
    [Edit] Ton excel est en qu'elle version ?
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

  19. #19
    Membre actif
    Avatar de Golard
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 281
    Points : 289
    Points
    289
    Par défaut
    Citation Envoyé par rv26t Voir le message
    As-tu fait cette étape dans VS (as tu accès dans la version express ?)

    compléter au niveau des propriétés du projet
    * Application
    bouton information de l'assembly
    cocher : rendre l'assembly visible par COM
    Titre et Description (ok).
    Oui

    Citation Envoyé par rv26t Voir le message
    Celle-la
    * Compiler
    cocher : inscrire pour COM Interop
    Etant faite manuellement avec regasm, puisque tu n'as pas la case à cocher
    Non. Je te rappelle que cette case à cocher n'existe pas dans la version studio express 2008 (et je pense dans toutes les versions express).
    C'est pourquoi j'utilise manuellement le regasm.exe pour créer le fichier .tlb
    Mais peut-être y a-t'il une autre étape que j'oublie ?

    Citation Envoyé par rv26t Voir le message
    Pour les GUID, je n'ai que celle du projet, présent dans "information de l'assembly".
    Tu as bien quelques GUID qui "trainent" à la fin de ton module Alarme.vb, comme par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <Guid("C58721B1-15B3-4eeb-9E1E-BCDA33D38EE6")>
    Fait une recherche sur "Guid" et tu va rapidement les trouver.

    Citation Envoyé par rv26t Voir le message
    Tu devrais essayer en 32.
    [Edit] Ton excel est en qu'elle version ?
    Le problème c'est qu'en ce moment mon poste 32 bits est en panne (carte mère ou processeur ko depuis une semaine).
    Concernant ma version précise d'Excel, je ne suis pas chez moi actuellement, mais je sais que l'exécutable est dans un sous-dossier de C:/Program Files (x86), donc il s'agit je pense obligatoirement d'une version 32 bits... non ?

    En référence à ton post #12, as-tu essayer d'exploiter mon fichier .dll plutôt que de régéner la solution ?
    Cela permettrait de valider que la dll créer par Visual studio express est bien capable de communiquer à travers COM !

    Merci pour tes conseils
    Crois-tu qu'on va y arriver ?

    Développement VBNet sous Visual Studio Community 2013 (environnement Windows 10)

  20. #20
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    Citation Envoyé par Golard Voir le message
    Non. Je te rappelle que cette case à cocher n'existe pas dans la version studio express 2008 (et je pense dans toutes les versions express).
    C'est pour ça que je dis
    Citation Envoyé par rv26t Voir le message
    Etant faite manuellement avec regasm, puisque tu n'as pas la case à cocher

    Citation Envoyé par Golard Voir le message
    Tu as bien quelques GUID qui "trainent" à la fin de ton module Alarme.vb, comme par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <Guid("C58721B1-15B3-4eeb-9E1E-BCDA33D38EE6")>
    Fait une recherche sur "Guid" et tu va rapidement les trouver.
    C'est un élément que j'avais téléchargé pour faire des essais, et il n'est pas pris en compte.
    Encore moins dans la version juste avec la fenêtre qui est le tien
    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
    Imports System.Runtime.InteropServices
    ''' <summary>L'interface représente un Wrapper de la classe Alarme pour les programmes exe vb6. (elle expose les propriétés et les méthodes)</summary>
    ''' <remarks>Sera exportée dans la bibliothéque de type créé dans l'assembly.</remarks>
    <InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> Public Interface IAlarmes
        Sub GestAlarme()
    End Interface
    ''' <summary>La classe qui implémentes les méthodes et les évènements.</summary>
    <ClassInterface(ClassInterfaceType.None)> _
    Public Class InterfaceAlarme
        Implements IAlarmes ' contrat entre classe et interface.
     
        Private fenAlarmes As frmAlarmes = New frmAlarmes
     
        ''' <summary>Ouvre la fenêtre des alarmes.</summary>
        Public Sub GestAlarme() Implements IAlarmes.GestAlarme
            fenAlarmes.Show() 'fenAlarmes.ShowDialog()
        End Sub
     
    End Class
    Public Class Alarme
    End Class
    et
    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
    Imports System.Windows.Forms
     
    Public Class frmAlarmes
     
        Private Sub OK_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK_Button.Click
            Me.DialogResult = System.Windows.Forms.DialogResult.OK
            Me.Close()
        End Sub
     
        Private Sub Cancel_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Cancel_Button.Click
            Me.DialogResult = System.Windows.Forms.DialogResult.Cancel
            Me.Close()
        End Sub
     
    End Class
    et qui fonctionne bien.

    Je regarde les autres questions plus tard

    [Edit] Je suis en system 32 bits.
    Relance sur le forum vb6 (en indiquant le lien ici), il me semble qu'un des intervenants connait bien ce type de problème.
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

Discussions similaires

  1. [GSL] Utilisation dans une DLL
    Par guillaumeFLAM dans le forum Bibliothèques
    Réponses: 1
    Dernier message: 07/08/2013, 17h19
  2. [MySQL] recuperer une valeur dans une liste deroulante pour l'utiliser dans une seconde liste
    Par tortue_22 dans le forum PHP & Base de données
    Réponses: 12
    Dernier message: 12/05/2010, 12h50
  3. Réponses: 4
    Dernier message: 04/07/2008, 11h34
  4. Réponses: 4
    Dernier message: 07/05/2007, 22h38
  5. Réponses: 16
    Dernier message: 07/08/2006, 00h45

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