XL 2021 Excel/vba et vb.net: Propriété de type OBJECT "ingérable"

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

p'tit vieux

XLDnaute Occasionnel
Bonjour à tous
Je ne sais pas si parmi vous certains connaissent vb.net et COM avec VBA.
je suis en train de faire un portage de certaines parties d'un UDF VBA en vb.net.
Je suis débutant en .NET.
Mon problème est "simple" j'ai créé des classes en VB.Net et certaines propriétés doivent être des types Object. Pas le choix.
Devinez!!
Je bloque sur le fait que lorsque je veux passer une valeur à cette propriété de type Object je me fais "jeter".
pour exemple voici ce que j'ai fait:
<ComVisible(True)>
<ClassInterface(ClassInterfaceType.AutoDual)>
Public Property ValueMax As Object
Get
Return _ValueMax
End Get
Set
_ValueMax = Value
End Set
End Property
Quelqu'un peut il m'aider à résoudre ce souci?
Par avance merci à tous.
 
Solution
bonjour,
le problème n'est pas lié aux String mais au objet qui en vba.net sont des variants et des classes en VBA.

il faut bien considérer qu'en vb.net tout est classe. un string en est une.

il faudrait écrire
Code:
set obj.truc=123
ce qui n'est pas possible si truc est un object.

VB:
set obj.truc= me.textbox1
ça c'est ok

si on oublie les instructions com
<ComVisible(True), ClassInterface(ClassInterfaceType.AutoDual)>
ça fonctionne truc=123 mais on perd l'intestil.

il doit être possible de lui dire oublies le typage mais comme faire pour garder l'interopérabilité entre vb.net et VBA ?
bonjour,
en fait soit je ne mets pas
ClassInterfaceType.AutoDual
et ça fonctionne mais je perds l'intestil, soit je le mets et un object vb.net n'est plus un variant VBA.

j'ai tenté les interfaces vb.net mais rien y fait.
j'ai interrogé différents IA sans succès.

je continue à chercher car c'est intéressant.
 
Salut,
pourquoi tu veux retourner un objet ? . C'est quel genre d'objet ? Si c'est une classe il faut qu'elle soit AutoDual et Com visible. Exemple :
VB:
<ComVisible(True), ClassInterface(ClassInterfaceType.AutoDual)>
Public Class ClConfig
    Public Property Name As String
End Class
Côté VBA :
Code:
Dim mc As New MaClasse
Dim cfg As ClConfig
Set cfg = mc.Config
cfg.Name = "Test"
Nullosse
 
Je ne sais pas si parmi vous certains connaissent vb.net et COM avec VBA.
je suis en train de faire un portage de certaines parties d'un UDF VBA en vb.net.
Je suis débutant en .NET.
Pourquoi passer par VBA pour un UDF ? on peut faire l'UDF complet en vb.net avec ExcelDNA. ExcelDNA c'est un Addin dans lequel on met son code vb.net et on peut ainsi créer des fonctions UDF (avec intellisense ) , des fonctions que l'on peut appeler à partir du VBA .
 
bonjour,
le problème n'est pas lié aux String mais au objet qui en vba.net sont des variants et des classes en VBA.

il faut bien considérer qu'en vb.net tout est classe. un string en est une.

il faudrait écrire
Code:
set obj.truc=123
ce qui n'est pas possible si truc est un object.

VB:
set obj.truc= me.textbox1
ça c'est ok

si on oublie les instructions com
<ComVisible(True), ClassInterface(ClassInterfaceType.AutoDual)>
ça fonctionne truc=123 mais on perd l'intestil.

il doit être possible de lui dire oublies le typage mais comme faire pour garder l'interopérabilité entre vb.net et VBA ?
 
Dernière édition:
Bonsoir a tous
Les pourquoi?
Precision. C’est une dll utilisee dans mon udf pas l’udf lii meme.
Parce que des classrs de ma dll vb.net recoivent des datas varies et de plisieurs origines. La data peut etre un string, une date, une erreur. Etc. Voir un tableau ou meme une classe.
Donc pas le choix ll faut que la dll accepte.
Si on met autodual au moment de faore in Set ... on a une erreur vba "objet requis"
Si on l’autre ca marche mais on a plus la capacited’avoir lntellisense ni aito completion.ni fenetre espion.
Mais ca marche.
Bref je voulais tout le beure l’argent 😉
j’ai trouve ... je crois .... tout marche.
Je vous livre ca demain car je suis sur mon tel..
Vous dirai tout sur le . .. ma solution.
A demain
Merci encore.
 
Bonjour tous,
ci joint le fichier VS 2022. Il doit être en tant que Administrateur.
L'objectif:
1. Permettre d'utiliser des propriétés acceptant des variants Excel mais aussi, par exemple, une instance d'une autre classe.
2. Permettre de débuguer en affichant toutes les propriétés de la classe dans la fenêtre Espions de VBE.

Pour obtenir cela vous devez:
1. Créer une interface avec ceci:
a. <ComVisible(True)>
b. <InterfaceType(ComInterfaceType.InterfaceIsDual)>
c. <Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx")>
d. Public Interface iclsMaClasse
et déclarer celle ci PUBLIC

Ensuite toujours dans l'Interface:
- Declarer toutes les propriétés de votre classe
- Uniquement pour les propriétés recevant des Types Object:
- Pour la partie lecture de la propriété:
Declarer la
ReadOnly Property UnNom As <MarshalAs(UnmanagedType.Struct)> Object
- Pour la partie écriture faire un "Setter":
Sub Set_UnNom(<MarshalAs(UnmanagedType.Struct)> ByVal val As Object)

Passons à la classe elle même
1. <ComVisible(True)>

2. <ClassInterface(ClassInterfaceType.None)>
3.
Public Class clsMaClasse
4.
Implements iClsObjectTest '-> implémente votre interface
5.
Public ReadOnly Property UnNom As Object Implements iclsMaClasse.UnNom
6. Public Sub Set_UnNom(val
As Object) Implements IClsObjectTest.Set_UnNom

Maintenant vous pouvez lire votre propriété comme d'habitude
debug.? MaClasse.MaProp
et pour affecter une valeur:
Attention c'est une SUB, une méthode donc
Call Set_MaPropiété(MonVariant)
ou Set_MaPropiété MonVariant

Et comme voulu vous pourrez voir l'integralité de votre classe dans la fenetre espion

Voilà.
J'espère que cela vous sera utile et vous évitera de passer 4 jours à trouver
 

Pièces jointes

Dernière édition:
Des commentaires? des retours?
Salut,
moi je n'utilise pas l'usine à gaz de visual studio ( beaucoup de Go), mais un script pour compiler et enregistrer en base de registres la dll. Dans le framework dotnet 4.x (qui est inclus dans windows 10, windows 11) il y a un compilateur vb.net ( vbc.exe) et un enregistreur de dll (regasm.exe) .
Mon script cmd compile le fichier source .vb et enregistre dans la base de registres la dll générée pour utilisation 32 bits et utilisation 64 bits.
Mon source .vb ressemble fortement au code de p'tit vieux :
VB:
<ComVisible(True)>
<InterfaceType(ComInterfaceType.InterfaceIsDual)>
<Guid("12345678-C789-2345-0123-1234567890AB")>
Public Interface IClsObjectTest
    ' Propriétés en lecture seule (VBA peut lire)
    ReadOnly Property Name As Object
    ' Setter séparé (VBA peut écrire)
    Sub Set_Name(ByVal val As Object)
    ReadOnly Property Age As Object
    Sub Set_Age(ByVal val As Object)
End Interface

<ComVisible(True)>
<ClassInterface(ClassInterfaceType.None)>
<ProgId("ComServ.ClsObjectTest")>
<Guid("12345678-C789-3456-0123-1234567890AB")>
Public Class ClsObjectTest
    Implements IClsObjectTest
    Private _Name As Object
    Private _Age As Object
    ' Propriété en lecture seule
    Public ReadOnly Property Name As Object Implements IClsObjectTest.Name
        Get
            Return _Name
        End Get
    End Property
    ' Setter séparé
    Public Sub Set_Name(val As Object) Implements IClsObjectTest.Set_Name
        _Name = val
    End Sub
    Public ReadOnly Property Age As Object Implements IClsObjectTest.Age
        Get
            Return _Age
        End Get
    End Property
    Public Sub Set_Age(val As Object) Implements IClsObjectTest.Set_Age
        _Age = val
    End Sub
    Public Sub New()
        ' Optionnel : valeurs par défaut
        _Name = ""
        _Age = 0
    End Sub
End Class

ComServ.png


TestObj.png


Attention ne pas oublier de "désenregistrer" la dll si on ne l'utilise plus ou avant de changer des GUID, sinon dans la base de registres il restera des clés non utilisées. Les GUID que j'ai mis dans mon exemple sont faciles à repérer en base de registres.
Nullosse
 
1774970059162.png

Capture version simple
1774970121696.png

Là j'ai juste passé Name la propre instance de la classe

Là ou je suis surpris c'est que tu n'ai pas de plantage si tu passe un vrai object/variant.
Au départ j'ai fait comme toi sans utiliser "As <MarshalAs(UnmanagedType.Struct)> Object" ce que j'aurais préféré.
Mais j'ai eu de magnifiques plantages.
As tu essayé de passer une classe classe dans l'une de tes propriétés?
Si ça marche j'avoue que je vais rendre mon tablier de ... débutant .Net 😁

Le code basique:
Sub test2()
Dim tt As New ClassObjectTest.ClsObjectTest
Call tt.Set_Name("Toto")
Call tt.Set_Age("123")
Call tt.Set_Name(tt)
End Sub
 
Au départ j'ai fait comme toi sans utiliser "As <MarshalAs(UnmanagedType.Struct)> Object" ce que j'aurais préféré.
Mais j'ai eu de magnifiques plantages.
As tu essayé de passer une classe classe dans l'une de tes propriétés?
Si ça marche j'avoue que je vais rendre mon tablier de ... débutant .Net 😁
Le code basique:
Sub test2()
Dim tt As New ClassObjectTest.ClsObjectTest
Call tt.Set_Name("Toto")
Call tt.Set_Age("123")
Call tt.Set_Name(tt)
End Sub
ton code est bizarre car tu utilises le même objet dans un objet cela fait un bouclage, moi j'utilise un autre objet :
VB:
Sub TestObj2()
    Dim o As New ComServ.ClsObjectTest
    Dim o1 As New ComServ.ClsObjectTest
    o.Set_Name "Alice"
    o.Set_Age 42
    o1.Set_Name o
    o1.Set_Age "vingt ans"
    MsgBox o.Name & " - " & o.Age & " ans"
End Sub
TestObj2.png


pas de plantage avec Excel 2021 64 bits windows 11
 
meme config que toi sauf Windows 10 pro.
c'est bizarre que chez moi ca plantait. Sinon je ne me serais pas ... emmerder à faire une usine à gaz. 😨😰😪
je vais tester ton code aussi.
Je te tiens au courant
... tu me décourages là !! 😁😂
 
1774974074729.png

1774974110255.png

Impossible d'affecter l'objet Fils avec le code.
EN vb j'ai juste ajouté cela :
Dans l'interface:

ReadOnly Property Obj As Object
Sub Set_Obj(ByVal val As Object)

Dans la classe


Public ReadOnly Property Obj As Object Implements IClsObjectTest.Obj
Get
Return Nothing
End Get
End Property
Public Sub Set_Obj(val As Object) Implements IClsObjectTest.Set_Obj
_Obj = val
End Sub
Ca veut pas le pére rejete son fils 😪
 
Impossible d'affecter l'objet Fils avec le code.
EN vb j'ai juste ajouté cela :
Dans l'interface:

ReadOnly Property Obj As Object
Sub Set_Obj(ByVal val As Object)

Dans la classe

Public ReadOnly Property Obj As Object Implements IClsObjectTest.Obj
Get
Return Nothing
End Get
End Property
Public Sub Set_Obj(val As Object) Implements IClsObjectTest.Set_Obj
_Obj = val
End Sub
Ca veut pas le pére rejete son fils 😪
Pourquoi as-tu mis Return Nothing et pas Return _Obj ?
 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

A
Réponses
17
Affichages
4 K
Abdenour
A
G
Réponses
0
Affichages
1 K
guiboubou233
G
C
Réponses
1
Affichages
4 K
Conrad13
C
T
Réponses
11
Affichages
8 K
T
Réponses
2
Affichages
1 K
B
Réponses
4
Affichages
1 K
B
Retour