[Catégorie modifiée VB6 -> VBA] Adresser l'élement d'un type par une variable

florentnostradamus Messages postés 3 Date d'inscription jeudi 21 avril 2011 Statut Membre Dernière intervention 22 avril 2011 - 21 avril 2011 à 15:37
foliv57 Messages postés 420 Date d'inscription vendredi 17 novembre 2006 Statut Membre Dernière intervention 15 juillet 2014 - 22 avril 2011 à 13:12
Bonjour à tous,

Je cherche à adresser dans une fonction l'élément d'un type défini par ailleurs par une variable qui est un argument de cette fonction.
Je m'explique:

J'ai une structure définie ainsi:
Type MonType
    DonneeA As Long
    DonneeB As Long
    DonneeC As Long
    ...

J'ai une fonction définie ainsi:
sub MaProcedure(Argument as string)
    Dim Temp as MonType
...
    Msgbox Temp.Argument
end sub

L'emploi de la fonction serait de la forme:
MaProcedure "DonneeB"

Ecrit ainsi, bien sur, ça ne fonctionne pas... Mais y a t'il moyen de faire ou bien c'est impossible ?

(Note: c'est du code VBA dans excel)
Je vous remercie par avance
Cordialement
Florent

5 réponses

foliv57 Messages postés 420 Date d'inscription vendredi 17 novembre 2006 Statut Membre Dernière intervention 15 juillet 2014 9
21 avril 2011 à 17:56
Bonjour,

A part faire :
Public Function MaProcedure(obj As MonType, Argument As String) As Long
    Select Case Argument
        Case "DonneeA"
          MaProcedure = obj.DonneeA
        Case "DonneeB"
          MaProcedure = obj.DonneeB
        Case "DonneeC"
          MaProcedure = obj.DonneeC
    End Select
End Function


Pour pouvoir faire :
Public Sub Test()
    Dim var As MonType
    var.DonneeA = 10
    var.DonneeB = 20
    var.DonneeB = 30
    MsgBox MaProcedure(var, "DonneeB")
End Sub


Je ne vois pas trop ...
0
florentnostradamus Messages postés 3 Date d'inscription jeudi 21 avril 2011 Statut Membre Dernière intervention 22 avril 2011
21 avril 2011 à 18:24
Oui, effectivement, il y a cette solution.
Sauf que ma structure fait dans la réalité une petite centaine de valeurs différentes et que c'est pas très propre dans le code avec un case sur autant de possibilités...
De plus, j'aimerais que le code soit facilement évolutif si la structure est modifiée (car elle est amenée à évoluer). Au quel cas la solution avec le case est encore moins performante (nécessité de faire évoluer cette partie du code à chaque évolution de la forme de la structure)
Merci néanmoins pour votre réponse
0
foliv57 Messages postés 420 Date d'inscription vendredi 17 novembre 2006 Statut Membre Dernière intervention 15 juillet 2014 9
21 avril 2011 à 22:58
Dans ce cas, je peux vous proposer une autre piste au cas ou.

Le principe et de créer un module de classe (PropertyList dans mon exemple) à la place de votre Type.

Voici un exemple de la forme que pourrait avoir ce module de classe
Option Explicit

Private propertyTable() As Variant

Private Sub Class_Initialize()
    
    'Création d'une table contenant les noms des propriétés dans
    'la première colonne et les valeurs dans la seconde
    ReDim propertyTable(2, 1)
    
    'Initialisation des noms des propriétés
    propertyTable(0, 0) = "DonneeA"
    propertyTable(1, 0) = "DonneeB"
    propertyTable(2, 0) = "DonneeC"
    
End Sub

'Accès direct à la proprété A
Public Property Get DonneeA() As Long
    DonneeA = CLng(propertyTable(0, 1))
End Property
Public Property Let DonneeA(value As Long)
    propertyTable(0, 1) = value
End Property

'Accès direct à la proprété B
Public Property Get DonneeB() As Long
    DonneeB = CLng(propertyTable(1, 1))
End Property
Public Property Let DonneeB(value As Long)
    propertyTable(1, 1) = value
End Property

'Accès direct à la proprété C
Public Property Get DonneeC() As Long
    DonneeC = CLng(propertyTable(2, 1))
End Property
Public Property Let DonneeC(value As Long)
    propertyTable(2, 1) = value
End Property

'Récupération de la valeur d'une propriété par son nom
Public Property Get Item(name As String) As Variant
    Dim index As Integer
    index = GetIndex(name)
    If index <> -1 Then
        Item = propertyTable(index, 1)
    Else
        Err.Raise vbObjectError + 10, , "La propriété " & name & " n'existe pas"
    End If
End Property

'Affectation de la valeur d'une propriété par son nom
Public Property Let Item(name As String, value As Variant)
    Dim index As Integer
    index = GetIndex(name)
    If index <> -1 Then
        propertyTable(index, 1) = value
    Else
        Err.Raise vbObjectError + 10, , "La propriété " & name & " n'existe pas"
    End If
End Property

'Récupération de l'index de ligne d'une propriété (à améliorer par exemple avec une recherche dicotomique)
Private Function GetIndex(name As String) As Integer
    Dim i As Integer
    For i = LBound(propertyTable, 1) To UBound(propertyTable, 1)
        If CStr(propertyTable(i, 0)) = name Then
            GetIndex = i
            Exit Function
        End If
    Next
    GetIndex = -1
End Function


De cette manière vous pourrez faire des choses comme cela
Public Sub Test()
    Dim var As New PropertyList
    var.DonneeA = 10
    var.DonneeB = 20
    var.DonneeC = 30
    
    MsgBox var.Item("DonneeB")
End Sub


Cette objet sera un peut plus simple à maintenir. Il est même largement améliorable, l'exemple est surtout pour vous donner un début de piste.
0
florentnostradamus Messages postés 3 Date d'inscription jeudi 21 avril 2011 Statut Membre Dernière intervention 22 avril 2011
22 avril 2011 à 08:51
Bonjour foliv57 et merci,
Effectivement, c'est une piste à creuser.
Je vais regarder ça (j'espère jusque que les fonctions Public property get et Public Property Let net sont pas indispensables sinon on retombe dans les désavantages du case select...
Bonne piste néanmoins !
Florent
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
foliv57 Messages postés 420 Date d'inscription vendredi 17 novembre 2006 Statut Membre Dernière intervention 15 juillet 2014 9
22 avril 2011 à 13:12
Les propriétés avec comme commentaire "Accès direct" ne sont pas indispensable non.

Avec uniquement la propriété "Item" vous pouvez faire
'Ecriture
var.Item("DonneeA") = 10

et
'Lecture
Msgbox var.Item("DonneeA")
0
Rejoignez-nous