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

Macros et VBA Excel Discussion :

Boucle sur une structure personnalisée ? [XL-2003]


Sujet :

Macros et VBA Excel

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 3
    Par défaut Boucle sur une structure personnalisée ?
    Bonjour,

    Est-il possible de faire une boucle, en VBA Excel, sur une structure personnalisée?

    Exemple:
    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
     
    'Définition du type
    Type DetailFacture
        Numero As String
        CreateDate As String
        NameClient As String
        TypeFacture As String
        Conserv As Double
        Rech As Double
        TriAss As Double
        Transport As Double
        Delegation As Double
        Rayonnage As Double
        Divers As Double
        Conten As Double
        Boites As Double
        HT As Double
        TVA As Double
        TTC As Double
        PaiementDate As String
    End Type
     
     
    Sub recupFacture()
     
      'Initialisation de la structure
      Dim myFacture As DetailFacture
     
      Dim myFactureElement As Variant
      Dim myCpt As Integer
     
      'Boucle pour remplir la structure
      For Each myFactureElement In myFacture
        myFactureElement = ActiveCell.Offset(0,myCpt).Value
        myCpt = myCpt + 1
      Next
     
     
    End Sub
    Bon, c'est un exemple. Donc ici je définis une structure, ou type (apparemment c'est la même chose, merci de m'indiquer si je me trompe) et ensuite je remplis tous les éléments de cette structure dans une boucle.

    Bien évidemment cette exemple ne fonctionne pas, j'ai une erreur de compilation qui m'indique que For Each ne peut itérer que sur des Collections et des Array.

    Pourtant il me semblais qu'une structure était plus ou moins du même type qu'un array, d'où ma question:
    Est-il possible d'effectuer une boucle (For, For Each ou autre) pour remplir ou lire une structure définie?

    Par avance, merci.

  2. #2
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 3
    Par défaut
    Je me permets de relancer mon post.

    En effet je ne pense pas être le seul à m'être poser cette question.
    Je trouve que l'utilisation d'une structure personnalisée permet une bien meilleur lisibilité du code mais par contre si à chaque fois que je veux le remplir je dois remettre toute la liste ça rajoute vraiment beaucoup de ligne au code.

    N'hésiter pas à demander des précisions si ma question n'est clair:

    Est-il possible d'effectuer une boucle sur les éléments d'une structure personnalisée?

    Merci

  3. #3
    Expert éminent


    Profil pro
    Inscrit en
    Juin 2003
    Messages
    14 008
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 14 008
    Par défaut
    je ne pense pas cela possible...

    mais tu peu utiliser une collection :

    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
    Sub MaCollection()
     Dim Macol As New Collection
     Dim element
       Macol.Add "00001", "DetailFacture"
       Macol.Add "20/09/1985", "CreateDate"
       Macol.Add "Pierre Henri", "NameClient"
       For Each element In Macol
         Debug.Print element
       Next
    ' Parcours avec un index
     Dim i As Integer
     For i = 1 To Macol.Count
      Debug.Print i & " : " & Macol(i)
     Next
    'Parcours par le nom
     Debug.Print "DetailFacture : " & Macol("DetailFacture")
     Debug.Print "CreateDate : " & Macol("CreateDate")
     Debug.Print "NameClient : " & Macol("NameClient")
    End Sub

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    141
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 141
    Par défaut Accès par itération aux champs d'un User-Defined Type en Excel VBA
    UDT de belle facture

    Citation Envoyé par pedritodelgado Voir le message
    Est-il possible d'effectuer une boucle (For) pour remplir ou lire une structure définie?
    Après avoir décrit la feuille Excel par des constantes en terme de rangées et de colonnes, on peut dans une boucle classique For Next faire des itérations pour remplir votre User-Defined-Type (UDT) grâce à un Select Case sur l'indice de colonne.

    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
     Option Explicit ' Enumération des champs d'un User-Defined Type
    Public Const rowFacture = 2 ' Rangée de la première facture à cause de l'entête
    Public Const colNumero = 3 ' Première colonne C de la facture. Pas forcément en A.
    Public Const col_First = colNumero
    Public Const colDatePaid = colNumero + 1
    Public Const colNameClient = colDatePaid + 1
    Public Const col_Last = colNameClient ' Dernière colonne
    Type FactureType
        Numero As Long
        DatePaid As Date
        NameClient As String
    End Type
     
    Public Sub InvoiceMain() ' Point d'entrée de la maquette
    Dim indRow As Long, factureUdt As FactureType
     
        indRow = rowFacture ' Première facture
        While Cells(indRow, col_First) <> ""
            InvoiceRead indRow, factureUdt  ' Copie chaque valeur des cellules dans l'UDT
            InvoiceDo factureUdt   ' Traite la facture
            indRow = indRow + 1 ' Facture suivante
        Wend
    End Sub
     
    ' Copie Cells vers User-Defined-Type
    Sub InvoiceRead(ByVal indRow As Long, ByRef factureUdt As FactureType)
    Dim indCol As Integer
        For indCol = col_First To col_Last ' Iteration de la première à la dernière colonne
            InvoiceSet indCol, Cells(indRow, indCol).value, factureUdt
        Next
    End Sub
     
    ' Affecte le champ indCol de la facture UDT
    Private Sub InvoiceSet(ByVal indCol As Integer, ByVal value As Variant, ByRef factureUdt As FactureType)
        Select Case indCol
            Case colNumero: factureUdt.Numero = value
            Case colDatePaid: factureUdt.DatePaid = value
            Case colNameClient: factureUdt.NameClient = value
            Case Else: Stop ' Gestion d'erreur
        End Select
    End Sub
     
    ' Trouve la valeur du champ indCol de la facture UDT
    Public Sub InvoiceGet(ByVal indCol As Integer, factureUdt As FactureType, ByRef varCell As Variant)
        Select Case indCol
            Case colNumero: varCell = factureUdt.Numero
            Case colDatePaid: varCell = factureUdt.DatePaid
            Case colNameClient: varCell = factureUdt.NameClient
            Case Else: Stop ' Gestion d'erreur
        End Select
    End Sub
     
    ' Traitement de la facture
    Private Sub InvoiceDo(ByRef factureUdt As FactureType)
        InvoicePrint "Avant modification", factureUdt
        factureUdt.Numero = -factureUdt.Numero ' Inverse le signe du n° de facture
        factureUdt.NameClient = IIf(factureUdt.Numero > 0, UCase(factureUdt.NameClient), _
            LCase(factureUdt.NameClient)) ' bascule MAJUSCULE / minuscule
        InvoicePrint "Après modification", factureUdt
    End Sub
     
    ' Affiche la facture UDT dans la fenêtre d'Exécution immédiate (Ctrl+G) du VBE d'Excel
    Sub InvoicePrint(ByVal strMsg As String, factureUdt As FactureType)
    Dim indCol As Integer, strLine As String, varValue As Variant
        strLine = strMsg + " : "
        For indCol = col_First To col_Last ' Iteration de la première à la dernière colonne
            InvoiceGet indCol, factureUdt, varValue
            strLine = strLine & varValue & " "
        Next
        Debug.Print strLine
    End Sub
    InvoiceRead() boucle dans la rangée courante de la première à la dernière colonne.
    InvoiceSet() affecte le champ d'indice indCol de la facture UDT.

    InvoiceDo() fait un traitement sur la facture UDT avec la syntaxe "."
    InvoicePrint() affiche les modifications de la facture UDT en accédant dans une boucle à chaque champ de la facture UDT.

    Dans la feuille Excel, mettre 123 en C2, une date en D2, la chaîne "CLIENT" en E2.
    Dans la fenêtre d'Exécution immédiate (Ctrl+G) du VBE d'Excel, copier-coller et valider par ENTER :
    Avant modification : 123 07/08/2011 CLIENT
    Après modification : -123 07/08/2011 client

    ___________

    Si la discussion est résolue, vous pouvez cliquer sur le bouton

    En bas de ce message s'il vous a apporté des éléments de réponse pertinents, pensez également à voter en cliquant sur le bouton vert ci-dessous.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 3
    Par défaut Apparemment pas de possibilité de boucle directe sur un UDT
    @bbil: C'est vrai qu'une collection répond tout a fait mon besoin: lisibilité et possibilité de boucler dessus. Actuellement je suis plus en train d'étudier les Dictionary. Je vais regarder les Collections.

    @MattChess: Je ne pensais pas développer une classe complète pour définir ma Facture mais effectivement si je définis un UDT(merci pour le vocabulaire) il lui faut bien ses accesseurs. En tout cas beau travaille et merci beaucoup, cette exemple de classe me sera certainement utile.

    Sinon j'avais pensé, pour effectuer une boucle sur un UDT, utiliser un array contenant tous les noms de propriété dans l'ordre. Ensuite il suffirait de boucler sur ce array mais ça impose des noms de propriété dynamiques et je ne sais pas si VBA le permet. Encore une piste à tester.

    Enfin, d'après vos réponses je pense que l'on peut conclure qu'il n'est pas possible de boucler directement sur un UDT. Je clôture donc le sujet.

    Merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XSLT] Faire une boucle sur une variable [i]
    Par PoT_de_NuTeLLa dans le forum XSL/XSLT/XPATH
    Réponses: 8
    Dernier message: 07/06/2010, 12h45
  2. Réponses: 8
    Dernier message: 15/06/2006, 20h56
  3. vecteur sur une structure
    Par sam_123 dans le forum C++
    Réponses: 6
    Dernier message: 25/01/2006, 07h30
  4. Memset sur une structure
    Par ghostdogpr dans le forum C
    Réponses: 4
    Dernier message: 16/12/2005, 13h43
  5. Réponses: 2
    Dernier message: 13/12/2005, 16h48

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