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 :

Remplir un tableau avec plusieurs formulaires


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2019
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2019
    Messages : 2
    Par défaut Remplir un tableau avec plusieurs formulaires
    Bonjour,

    Je cherche à remplir un tableau excel en passant par plusieurs formulaires. J'ai donc dans le 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
    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
     
    Sub variables()
     
    Dim var1 As Integer
    Public A, B, C, D, E, F
     
    End Sub
     
     
    Sub enregistre()
     
        Dim EntreePlus As Worksheet, ZZ As Range, Erg, i As Integer, AA As Range, BB As Range, EE As Range, XX As Range, YY As Range, FF As Range, GG As Range
     
     
        Set EntreePlus = ThisWorkbook.Worksheets("Feuil1")
     
     Application.ScreenUpdating = True
     
     
     
        Set XX = EntreePlus.Cells(16384, 1).End(xlUp).Offset(1, 0) 'civilité
        Set ZZ = EntreePlus.Cells(16384, 2).End(xlUp).Offset(1, 0) 'nom
        Set YY = EntreePlus.Cells(16384, 3).End(xlUp).Offset(1, 0) 'prénom
        Set AA = EntreePlus.Cells(16384, 4).End(xlUp).Offset(1, 0) 'adresse
        Set BB = EntreePlus.Cells(16384, 5).End(xlUp).Offset(1, 0) 'code postal
        Set EE = EntreePlus.Cells(16384, 6).End(xlUp).Offset(1, 0) 'ville
     
     
        XX.Offset(0, i).Value = A
        ZZ.Offset(0, i).Value = UserForm004.TextBox3.Text
        YY.Offset(0, i).Value = C
        AA.Offset(0, i).Value = D
        BB.Offset(0, i).Value = E
        EE.Offset(0, i).Value = F
     
     
     
     
     
    Application.ScreenUpdating = True
     
        MsgBox "Les données ont été enregistrées avec succés"
     
    End Sub
    Et dans le 1er Userform

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     
    Sub Image8_Click()
     A = "NCE01"
     B = UserForm004.TextBox4.Text
     C = ""
     D = ""
     E = UserForm004.TextBox3.Text
     F = UserForm004.TextBox2.Text
     
    Module1.enregistre
    End Sub
    Un deuxième pour exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     
    Sub Image8_Click()
     A = "NCE02"
     B = ""
     C = "UserForm005.TextBox4.Text"
     D = ""
     E = UserForm005.TextBox6.Text
     F = UserForm005.TextBox2.Text
     
    Module1.enregistre
    End Sub



    J'aimerai donc facilement pouvoir changer le contenu des variables A, B, C à intégrer au tableau selon le userform utilisé (16 au total). Si vous avez des idées ou si je suis pas clair hésitez pas !

    Merci

  2. #2
    Expert confirmé
    Homme Profil pro
    retraité
    Inscrit en
    Juin 2012
    Messages
    3 423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : retraité
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Juin 2012
    Messages : 3 423
    Par défaut
    Bonjour,

    L'instruction Public ne doit pas être placée dans une routine, mais en tête du module.
    Ceci devrait fonctionner:
    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
    Public A, B, C, D, E, F
     
    Sub Enregistre()
        Dim EntreePlus As Worksheet, XX As Range
        Set EntreePlus = ThisWorkbook.Worksheets("Feuil1")
        Set XX = EntreePlus.Cells(16384, 1).End(xlUp)
        With XX
            .Offset(1, 0).Value = A 'civilité
            .Offset(1, 1).Value = B 'nom
            .Offset(1, 2).Value = C 'prénom
            .Offset(1, 3).Value = D 'code postal
            .Offset(1, 4).Value = E 'ville
        End With
        MsgBox "Les données ont été enregistrées avec succès"
        Set XX= Nothing
        Set EntreePlus = Nothing
    End Sub
    Bonne continuation.

  3. #3
    Expert confirmé Avatar de Patrice740
    Homme Profil pro
    Retraité
    Inscrit en
    Mars 2007
    Messages
    2 478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2007
    Messages : 2 478
    Par défaut
    Bonjour,

    Les variables publiques sont à utiliser avec prudence, il est préférable d'utiliser des variables locales (niveau procédure) et de les transmettre en argument aux procédures appelées.
    Pour faciliter la lecture du code il est aussi conseillé d'utiliser des nom de variables, d'objets, de procédure, ... représentatifs et préfixés
    Exemple avec un type de variable personnalisé (on aurait aussi pu utiliser un tableau de string mais ce serait moins compréhensible) :

    Dans un module standard :
    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
    Option Explicit
    Public Type Untel
      Civilité As String
      Nom As String
      Prénom As String
      Adresse As String
      CP As String
      Ville As String
    End Type
     
    Public Sub Enregistre(Quidam As Untel)
    Dim EntreePlus As Worksheet
      Set EntreePlus = ThisWorkbook.Worksheets("Feuil1")
      Application.ScreenUpdating = True
      With EntreePlus
        With .Cells(.Rows.Count, "B").End(xlUp).Offset(1) 'Colonne B (Nom) obligatoire
          .Offset(0, 0) = Quidam.Civilité
          .Offset(0, 1) = Quidam.Nom
          .Offset(0, 2) = Quidam.Prénom
          .Offset(0, 3) = Quidam.Adresse
          .Offset(0, 4) = Quidam.CP
          .Offset(0, 5) = Quidam.Ville
        End With
      End With
      Application.ScreenUpdating = True
      MsgBox "Les données ont été enregistrées avec succés"
    End Sub
    Dans l'userform Contact :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Option Explicit
    Private Sub btnEnregistrer_Click()
    Dim Contact As Untel
     Contact.Civilité = Me.tbxCivilité.Text
     Contact.Nom = Me.tbxNom.Text
     Contact.Prénom = Me.tbxPrénom.Text
     Contact.Adresse = Me.tbxAdresse.Text
     Contact.CP = Me.tbxCP.Text
     Contact.Ville = Me.tbxVille.Text
     Call Module1.Enregistre(Contact)
    End Sub
    Dans l'userform Personne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Option Explicit
    Private Sub btnEnregistrer_Click()
    Dim Personne As Untel
     Personne.Civilité = Me.tbxCivilité.Text
     Personne.Nom = Me.tbxNom.Text
     Personne.Prénom = Me.tbxPrénom.Text
     Personne.Adresse = Me.tbxAdresse.Text
     Personne.CP = Me.tbxCP.Text
     Personne.Ville = Me.tbxVille.Text
     Call Module1.Enregistre(Personne)
    End Sub
    Le fichier : empiresailor.xlsm

  4. #4
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Billets dans le blog
    8
    Par défaut re
    re
    bonjour
    transférer des donnée formulaire dans un sheets il y a beaucoup plus simple
    EXEMPLE 1
    tu a 5 textbox (nom,prenom,adresse,CP ,ville)
    dans le tag de ces textbox (dans l'éditeur vbe) tu leur met la/les lettre(s) des colonnes correspondantes
    et puis c'est tout le reste est très simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Private Sub CommandButton1_Click()
    Dim EntreePlus As Worksheet, ro&
      Set EntreePlus = ThisWorkbook.Worksheets("Feuil1")
    ro = EntreePlus.Cells(Rows.Count, "B").End(xlUp).Offset(1).Row
    For Each txt In Me.Controls
    If txt.Tag <> "" Then EntreePlus.Cells(ro, txt.Tag) = txt
    Next
    End Sub
    après encore plus simple tu envoie l'array d'un coup dans la première ligne dispo(xlup).offset(1)
    EXEMPLE 2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Private Sub CommandButton2_Click()
    Dim EntreePlus As Worksheet, ro&, newitem
      Set EntreePlus = ThisWorkbook.Worksheets("Feuil1")
    ro = EntreePlus.Cells(Rows.Count, "B").End(xlUp).Offset(1).Row
    newitem = Array(tbxNom, tbxPrénom, tbxAdresse, tbxCP, tbxVille)
    EntreePlus.Cells(ro, "B").Resize(1, 5) = newitem
    End Sub
    un autre exemple avec un tableau structuré similaire a l'exemple 1 (même principe)sauf que dans le tag on mettrait les indexs de colonnes par rapport au tableau!!!!!!!! (pas du sheet)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Private Sub CommandButton3_Click()
    With Sheets("Feuil1").Range("Tableau1").ListObject
     .ListRows.Add
    For Each txt In Me.Controls
    If txt.Tag <> "" Then .ListRows(.ListRows.Count).Range.Cells(Val(txt.Tag)) = txt
    Next
    End With
    End Sub
    j'ai parlé d'écriture dans le sheets mais avec ce procédé tu peut faire l'inverse
    a savoir récupérer les données du sheets pour remplir le formulaire
    le principe est tout simplement inverse
    tu détermine ta ligne

    et chaque textbox = .cells(lalignedeterminé,lettre du tag).value 'pour un range
    ou pour un tableau structuré
    textbox = range("tableau1").listobject .listrows(lalignedeterminé).range.cells(index dans le tag du textbox).value

    c'est juste une question de conception au départ
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  5. #5
    Expert confirmé
    Avatar de Arkham46
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    5 865
    Détails du profil
    Informations personnelles :
    Localisation : France, Loiret (Centre)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 5 865
    Par défaut
    Bonjour,

    Citation Envoyé par patricktoulon Voir le message
    il y a beaucoup plus simple
    La simplicité est tout relative et n'est pas une finalité.
    Elle ne se mesure pas non plus en nombre de lignes de code.

    Beaucoup plus simple ? Je ne comprends pas.

  6. #6
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Billets dans le blog
    8
    Par défaut re
    bonjour arkham

    beaucoup plus simple dans le sens ou:
    1. pas besoins d'associer une variable quelconque a un textbox que se soit dans un module ou le UserForm
    2. économie de mémoire
    3. l'utilisation du tag permet justement de ne pas faire appel a la mémoire ce qui permet de ne pas perdre la donnée en cas de bug ailleurs dans vba qui réinitialiserait vba


    et puis quoi de plus simple que de récupérer le tag du control pour déterminer la colonne
    c'est la plus vielle recette et c'est pas moi qui l'ai inventé
    c'est d'ailleurs un sujet qui a été demandé plusieurs fois et certains membre éminents seraient d'accords avec moi


    un exemple pour te faire comprendre mon raisonnement

    qu'elle est l'utilité de ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    sub test
    dim valeur as string ,valeur2 as string,lig as long
    lig=sheets(1).range("A:A").end(xlup).offset(1).row
    valeur=textbox1.value
    valeur2=textbox2.value
    sheets(1).cells(lig,1)=valeur
    sheets(1).cells(lig,2)=valeur2
    end sub
    par rapport a ca par exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    sub test
    lig=sheets(1).range("A:A").end(xlup).offset(1).row
    for i=1 to 5 
    sheets(1).cells(lig,me.controls("textbox" & i).tag)=me.controls("textbox" & i).value
    next
    end sub
    a mon sens seule la variable représentant l'index de la first ligne dispo doit être variable dans un formulaire d'enregistrement de données (personne)
    et c'est pareil en lecture
    et pour finir je conclurais que la simplicité de ce procédé ne réside pas que dans le nombre faible de lignes, mais dans son raisonnement tout court
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  7. #7
    Expert confirmé
    Avatar de Arkham46
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    5 865
    Détails du profil
    Informations personnelles :
    Localisation : France, Loiret (Centre)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 5 865
    Par défaut
    La solution de Partice740 me convient mieux.
    C'est structuré, on sait le rôle de chaque contrôle par son nom...

    Gagner 2 lignes de codes en passant par un tag et un appel de contrôle par nom dans une variable n'est pas plus simple à mon goût.
    Peut-être à très court terme à l'écriture, mais pour la maintenance bof bof..

  8. #8
    Expert confirmé Avatar de Patrice740
    Homme Profil pro
    Retraité
    Inscrit en
    Mars 2007
    Messages
    2 478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2007
    Messages : 2 478
    Par défaut
    Citation Envoyé par patricktoulon Voir le message
    ... 3. l'utilisation du tag permet justement de ne pas faire appel a la mémoire ...
    D'après-toi où donc est stockée l'information contenue dans le tag ?
    Si on peut se passer de la mémoire on va pouvoir faire des miracles avec un ZX81 !!!

    Citation Envoyé par patricktoulon Voir le message
    ...ce qui permet de ne pas perdre la donnée en cas de bug ailleurs dans vba qui réinitialiserait vba
    Et si VBA plante au point qu'il faut le réinitialiser, comment comptes-tu accéder au tag ????

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    Salut.

    Je me demande en quoi il est intéressant de remplir la même table avec des données provenant de formulaires différents (titre de la discussion)

    Perso, je n'aime pas hardcoder les positions de colonne dans les tags des contrôles. Si, au hasard du développement de l'application, on ajoute ou permute des colonnes, on va devoir aller modifier les tags de tous les contrôles ou presque. De plus, travailler avec des Textbox1, textbox2 etc va vite devenir un véritable casse-tête pour savoir comment appairer les colonnes et les textbox. Il est toujours préférable de travailler avec des contrôles nommés de façon à en comprendre rapidement le contenu. Pour finir, l'exemple de Patrick part du principe que l'on travaille uniquement avec des textbox. Derrière donc cette apparente simplicité se cache une difficulté de lecture, de compréhension rapide, de maintenance et d'évolution. Si la plage de données qui reçoit les infos est déplacée, c'est également la galère. Je préfère de loin un code bien écrit, compréhensible et maintenable à du hardcoding et du code mal torché, surtout sous le prétexte d'une utilisation rationnelle de la mémoire

    En 2019, Je n'arrive pas à comprendre pourquoi on propose encore des solutions avec plages, car on utilise évidemment les tables de données pour le stockage de ce genre de choses (voir mon tuto sur les tableaux structurés).

    Au passage, comme Patrice740, je n'aime pas les variables publiques. Je les bannis systématiquement de mon code.


    Perso, j'utilise une table de mappage pour réaliser l'opération. Elle est constituée d'une table de données contenant la paire de valeurs Nom de colonne / Contrôle. Une simple boucle sur un tableau issu de cette table de mappage permet de retrouver la concordance Colonne / Contrôle.

    Nom : 2019-07-28_192112.png
Affichages : 787
Taille : 3,2 Ko

    La table de données contiendra bien entendu les colonnes dont les noms sont renseignés dans la table de mappage.

    Nom : 2019-07-28_205027.png
Affichages : 765
Taille : 2,5 Ko



    On peut alors utiliser un userform dans lequel sont présents les contrôles renseignés dans cette table. En faisant abstraction du code du userform qui valide la saisie, un clic sur le bouton de validation du userform modifie simplement la valeur d'une propriété publique du userform qui sera utilisée par la suite:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Option Explicit
     
    Public Result As String
     
    Private Sub btnValidate_Click()
      Result = "Validate"
      Me.Hide
    End Sub

    Une procédure de module standard appelle le userform et traite les infos par la suite si validation. En cas d'ajout de colonnes/contrôles, cette procédure reste inchangée:

    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
    Sub Test()
      Dim Map
      Dim Counter As Long
      Dim NewRow As ListRow
     
      With usfContact
        .Show
        If .Result = "Validate" Then
          Map = Range("t_Map").Value
          Set NewRow = Range("t_Contacts").ListObject.ListRows.Add()
          For Counter = 1 To UBound(Map)
            NewRow.Range.Cells(NewRow.Parent.ListColumns(Map(Counter, 1)).Index).Value = .Controls(Map(Counter, 2)).Value
          Next
        End If
      End With
    End Sub
    On pourrait bien sûr variabiliser les noms des tables de données (t_Contacts et t_Map), dans le cas où on devrait pousser des données du même formulaire dans des tables différentes.

    A cette solution, je préfère ajouter des propriétés publiques au userform pour pouvoir gérer plus facilement les données dont le type est différent de String, et utiliser la table de mappage avec les propriétés du userform, mais une chose à la fois.




    Citation Envoyé par patricktoulon Voir le message
    [...]
    1. [...]
    2. l'utilisation du tag permet justement de ne pas faire appel a la mémoire ce qui permet de ne pas perdre la donnée en cas de bug ailleurs dans vba qui réinitialiserait vba
    [...]
    La non-utilisation des variables publiques, l'écriture de procédures/fonctions courtes à responsabilité unique et une bonne gestion des On Error permet d'éviter cela. Si ce problème survient, c'est uniquement parce que le code est mal conçu et mal écrit
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  10. #10
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Billets dans le blog
    8
    Par défaut re
    re
    bonsoir pierre

    une matrice dans un TS pour les correspondances(controls/colonnes) !!! ???
    souhaitons ne pas avoir a faire la même chose avec d'autres tableaux
    cela dit je préfère au variables car comme je l'ai dis vba peut planter ailleurs et tout perdre

    perso j'ai utilisé le tag pour la correspondance pendant très longtemps et même encore aujourd'hui sur certains fichiers dont j'ai la flemme d'updater qui me servent moins souvent

    sinon j'utilise l'array direct (exemple2)
    et j'ai pas des noms de serie dans l'USF
    je peux parfaitement modifier l'ordre,un des noms, ajouter, supprimer
    un formulaire avec un tableau du genre conctact ;c'est quoi 10/15 données maxi


    ce que j'ai essayé de dire tout a l'heure ;c'est de donner a une variable string ou autre la valeur d'un textbox (ou autre) et de donner a une cellule la valeur
    la non je pige pas: on donne la valeur du textbox a une cellule par le textbox c'est tout
    surtout si leur nom sont évocateurs comme il a été présenté ici

    perso maintenant les variables me servent uniquement a déclarer des Object ou faire voyager des valeurs entre fonction ou module ou variables d'incrémentation dans une macro
    et dans certaine occasion diminuer le code répétitif
    après chacun fait sa soupe
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  11. #11
    Inactif  

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2012
    Messages
    4 903
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 4 903
    Billets dans le blog
    36
    Par défaut
    Bonjour,

    Citation Envoyé par Pierre Fauconnier Voir le message
    Salut.


    Au passage, comme Patrice740, je n'aime pas les variables publiques. Je les bannis systématiquement de mon code.

    Ça, ça marche quand les paramètres sont passés par référence (ByRef); le paramètre par défaut de VBA. Quand les paramètres sont passés par valeur (ByVal), la valeur par défaut dans d'autres langages, c'est beaucoup moins vrai. Sinon, dès que la valeur d'une variable passée en paramètre est modifiée, on se retrouve avec deux valeurs pour la même variable. La seule solution, à part ajouter un paramètre "vide" qui va retourner la valeur modifiée à la procédure appelante, demeure les variables publique. Ou bien, on accepte la perte de productivité en ajoutant systématiquement ByRef. Pour quelques lignes, cela demeure vivable, mais cela peut se révéler coûteux à la longue. Ou bien, il faut jouer avec des fichiers externes temporaires ou le registre. Et que cela te plaise ou non, je le sais par expérience avec un langage que tu ne veux pas voir.

  12. #12
    Expert confirmé Avatar de Patrice740
    Homme Profil pro
    Retraité
    Inscrit en
    Mars 2007
    Messages
    2 478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2007
    Messages : 2 478
    Par défaut
    Bonjour,
    Citation Envoyé par clementmarcotte Voir le message
    ...Ou bien, on accepte la perte de productivité en ajoutant systématiquement ByRef. Pour quelques lignes, cela demeure vivable, mais cela peut se révéler coûteux à la longue.
    Celle là il fallait l'oser !!!
    A comparer avec la perte de productivité à cause d'un code mal écrit par fainéantise !!!

  13. #13
    Inactif  

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2012
    Messages
    4 903
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 4 903
    Billets dans le blog
    36
    Par défaut
    Citation Envoyé par Patrice740 Voir le message
    Bonjour,

    Celle là il fallait l'oser !!!
    A comparer avec la perte de productivité à cause d'un code mal écrit par fainéantise !!!
    Avant de dire des âneries, prend n'importe quel de tes programmes VBA et utilise systématiquement ByReh dans tes macros. Tu va voir le bordel de passer de un à l'autre samns variables publiques. Avant d'insulter les autres, vérifie joualvert.

    J'ai assez expérimenté la différence entre ByVal et Byref pour voir la différence jouyalvert

    Quand tu auras essayé et vérifié la différence, tu pourras parler, et pas avant.

    Et puis, dans VB.net, tu dois déclarer des variables et des procédures publiques ou Friend, pour pour les appeler d'une autre classe. Mais comme tu ne veux juste pontifier et pas vérifier, tu peur continuer tes commérages.

  14. #14
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    Citation Envoyé par clementmarcotte Voir le message
    [...]
    Rigolo ton intervention sur les byref/byval, au regard de ton premier commentaire qui critiquait notre "débat technique" sur une question de débutant Cela étant dit, je ne vois pas le rapport entre ByRef/ByVal et les variables globales... On peut se passer des variables globales en utilisant les paramètres, qu'ils soient ByRef ou ByVal, et on utilisera ByRef ou ByVal en fonction du besoin dans la procédure appelée qui reçoit le paramètre. Tout développeur VBA doit savoir que par défaut, les paramètres sont ByRef et doit donc coder en conséquence.



    Citation Envoyé par clementmarcotte Voir le message
    [...]
    Ça, ça marche quand les paramètres sont passés par référence (ByRef); le paramètre par défaut de VBA. Quand les paramètres sont passés par valeur (ByVal), la valeur par défaut dans d'autres langages, c'est beaucoup moins vrai.[...]
    On s'en fout des autres langages, on parle de VBA, ici. Cela étant, ça ne change rien à l'affaire, je ne vois pas en quoi "c'est moins vrai" avec des paramètres passés en ByVal. Même avec ByVal, on peut se passer des variables globales.



    Citation Envoyé par clementmarcotte Voir le message
    [...]
    Sinon, dès que la valeur d'une variable passée en paramètre est modifiée, on se retrouve avec deux valeurs pour la même variable.[...]
    C'est faux car évidemment techniquement impossible. Lorsque l'on passe une variable en paramètre, on se retrouve toujours avec deux variables. Avec Byval, on se retrouve avec deux variables appartenant à des procédures différentes, chacune vivant sa propre vie, et qu'elles aient ou pas la même valeur par la suite n'a plus aucune espèce d'importance. Avec ByRef, on se retrouve aussi avec deux variables appartenant à des procédures différentes, celle de la procédure appelée faisant référence à celle de la procédure appelante. De sorte que lorsque tu modifies (enfin, que tu crois modifier) la valeur de celle de la procédure appelée, tu modifies en fait celle de la procédure appelante. Par illusion d'affichage, VBA affiche la valeur de variable initiale comme valeur de la variable de la procédure appelée, mais c'est un leurre car son vrai contenu est l'adresse mémoire de la variable à laquelle elle fait référence. Mais dans tous les cas, tu as deux variables différentes.


    Citation Envoyé par clementmarcotte Voir le message
    [...]Ou bien, on accepte la perte de productivité en ajoutant systématiquement ByRef.[...]
    A nouveau, en vba (nous sommes sur un forum VBA), il n'est pas nécessaire de préciser le ByRef, donc pas de perte de productivité (au passage, je serais curieux de savoir combien ça coûte en productivité de taper ByRef, surtout que je répète que ByRef n'est pas nécessaire en VBA pour se passer de variables publiques. Je suppose que tu as des liens vers les grandes études scientifiques qui ont quantifié en millions de dollars la perte de productivité dont tu parles). .



    Citation Envoyé par clementmarcotte Voir le message
    Avant de dire des âneries, prend n'importe quel de tes programmes VBA et utilise systématiquement ByReh dans tes macros. Tu va voir le bordel de passer de un à l'autre samns variables publiques.[...]
    Au delà de la grossièreté du message, je n'ai rien compris de ce passage. A nouveau, en quoi ByRef crée-t-il un bordel lorsque l'on se passe de variables publiques? Ca veut dire quoi passer de un à l'autre samns variables publiques. En quoi ByRef et ByVal sont-ils liés à l'absence de variables publiques? Mystère et boule de gomme


    Citation Envoyé par Patrice740 Voir le message
    [...]

    Celle là il fallait l'oser !!!
    A comparer avec la perte de productivité à cause d'un code mal écrit par fainéantise !!!
    En effet... Sacrifier la qualité du code à la "productivité" et accepter de produire du code de merde, c'est faire preuve d'un grand professionnalisme...



    Citation Envoyé par clementmarcotte Voir le message
    [...]
    C'est aussi une ineptie de croire que le demandeur ne reverra pas son code dans quelques mois, quand il aura plus d'expérience.[...]
    ... Manifestement, certains ici n'ont jamais entendu parler de dette technique.



    De façon générale, ca n'a pas de sens de programmer dans un langage en faisant comme si on était dans un autre, et ça en a encore moins lorsqu'un langage est POO et pas l'autre. En VBA, je raisonne en VBA, en vb.net, je raisonne en vb.net. En PHP, je raisonne en PHP.




    Citation Envoyé par clementmarcotte Voir le message
    [...]
    Et que cela te plaise ou non, je le sais par expérience avec un langage que tu ne veux pas voir.
    On se croirait à Poudlard. Quelles gamineries! (je ne relève même pas le ton ni le manque de courtoisie du message)
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  15. #15
    Inactif  

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2012
    Messages
    4 903
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 4 903
    Billets dans le blog
    36
    Par défaut
    Et puis tiens. J'ai fais quelque tests avec ByRef et ByVal. C'est bien beau de parler de paramètres. Encore faut-il savoir les utiliser de la bonne façon, et encore faut-il savoir quelle différence cela fait.

    Et puis, les paramètres semblent avoir priorité sur les variables publiques.

    Et puis, ce que l'ont faut machinalement avec des paramètres ByRef risque de ne plus être vrai quand on passe en ByVal. Et cela, que vous le vouliez ou non, et que ce soit en VBA ou non

    Que ce soeint des variables publiques ou des paramètres, les deux ont leur place. Tout dépend des besoins et des circonstances. ET moi, je me fie du dogmatisme à tout crin.
    Fichiers attachés Fichiers attachés

  16. #16
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    Alors là, c'est du plus haut comique.

    Citation Envoyé par clementmarcotte Voir le message
    [...]C'est bien beau de parler de paramètres. Encore faut-il savoir les utiliser de la bonne façon, et encore faut-il savoir quelle différence cela fait.[...]
    Venir faire la leçon comme tu le fais puis nous proposer tes "démonstrations". Tu serais débutant, je prendrais le temps de t'expliquer. Mais vu le ton de tes réponses et la suffisance de tes propos...


    Citation Envoyé par clementmarcotte Voir le message
    [...]
    Et puis, les paramètres semblent avoir priorité sur les variables publiques.[...]
    Ben oui, c'est comme cela depuis toujours, la variable locale (un paramètre est une variable locale) a priorité sur la variable de module et sur la variable publique. Tu sembles le découvrir alors que tu pérores sur ta longue expérience des paramètres... (et dire que ça s'appelle développeur .net... Quelle pitié!!)


    Je n'ai pas pu tester tes exemples car il n'y a pas Option Explicit en début de module. Ce n'est même pas du travail d'amateur de proposer du code sans Option Explicit. Perso, j'appelle cela du n'importe quoi. Appelle cela du dogmatisme si tu veux, mais il est impératif de travailler avec Option Explicit. Sans cela, les tests amènent inévitablement à des conclusions erronées et ne peuvent rien prouver...De ce fait, les tests que tu as publiés ne veulent rien dire. Que cherches-tu à démontrer?

    De plus, en quoi ces tests contredisent-ils ma position? Tu veux nous montrer à quoi servent ByRef et ByVal? On sait bien ce qu'on peut faire avec un ByRef et un ByVal, t'inquiète. Tu n'es pas le seul à avoir une longue expérience de ces trucs-là. Montre un code où tu penses que l'on ne peut pas s'en sortir sans variable publique puisque cela semble être ta quête du Graal, et je tenterai de démonter qu'on peut s'en passer (et je suis CERTAIN que je pourrai démontrer l'ineptie des variables publiques en VBA). Ca aurait un peu plus de sens que tes codes précédés de commentaires ampoulés qui frisent le bac à sable. Perso, je n'en démords pas, utiliser les variables publiques n'est à mon avis jamais nécessaire et est potentiellement source de gros problèmes dans le code. J'expliquerai ma position avec quelques exemples dès que j'aurai un peu de temps.

    Je rappelle, comme déjà dit précédemment, que les notions ByRef et ByVal ne sont pas directement à la notion de variable publique. Si la procédure appelée doit modifier une variable de la procédure appelante, elle la reçoit en ByRef (comportement par défaut en VBA), et si on veut s'assurer qu'on ne pourra pas la modifier dans la procédure appelante, on la passe en ByVal... Mais bien entendu, pour "singer" le mécanisme de modification d'une variable publique (et donc se passer de celle-ci), il faudra passer le paramètre en ByRef pour en permettre la modification (ce que fait le VBA par défaut). C'est d'autant plus vrai lorsqu'on oublie, comme toi, d'utiliser Option Explicit. D'ailleurs, comment fais-tu, Môôsieur le développeur .net de baraque de foire, pour utiliser en .net des variables non déclarées? Manifestement, la bouffonnerie ne te fait pas peur: Clément Marcotte, le grand codeur .net devant l'éternel qui ne déclare pas ses variables et ne connaît manifestement pas la différence en byref et byval... Tu fais pitié, vraiment.)

    Arrête de venir parler de ta grande expérience si c'est pour la conterdire par des exemples foireux qui ne prouvent rien. Franchement, venir pourrir une discussion qui, jusqu'à ta première intervention et tes inepties, restait au niveau technique en illustrant différentes façons de réaliser la demande initiale. Pitoyable!


    PS: Je précise que j'utilise ce ton uniquement en réplique à la suffisance dont tu fais preuve dans la majorité de tes interventions sur le forum, prouvant que la notion de débat technique courtois t'est totalement étrangère. A force, j'avoue que je perds patience.
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  17. #17
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 364
    Par défaut
    Bonjour …

    Ce qui est simple pour l’un peut ne pas l’être pour l’autre et réciproquement. Tout dépend, d’abord, de leur niveau de connaissances puis de leur volonté d’en acquérir de nouvelles, non ?


    Il n’y aurait sans doute pas eu de discussions théoriques, si le demandeur avait répondu au questionnement de Pierre.

    Citation Envoyé par Pierre Fauconnier Voir le message
    Je me demande en quoi il est intéressant de remplir la même table avec des données provenant de formulaires différents (titre de la discussion)

  18. #18
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    Je ne comprends pas bien ta remarque sur les matrices et les TS avec d'autres tableaux. Si tu as x tableaux associés à x formulaires, soit tu as x tables de mappage, soit tu as une seule table avec une colonne supplémentaire. En quoi ça gêne? Dans ta solution avec arrays, il te faudra bien x arrays hardcodés. Tu parles d'une solution

    Il te suffit de nommer proprement tes tables et tu t'y retrouves sans problèmes. Cette approche permet la systématisation du processus, et donc l'utilisation de code générique basé sur du paramétrage. Comme je l'ai dit, la procédure Test que j'ai proposée ne doit en rien être modifiée lors de l'ajout, la suppression, la permutation ou le renommage des colonnes ou des contrôles. Dans le userform, il ne faudra pas modifier les contrôles déjà en place (ni leurs tags, ni leurs noms,...). Seules les tables de mappage doivent être modifiées, ainsi bien sûr que le code du userform afférant aux nouveaux contrôles qui seraient ajoutés. Pour moi, le fait qu'il y ait peu ou beaucoup de données à modifier n'entre pas en ligne de compte. Ce qui est important, c'est la systématisation de l'approche et du codage. C'est le super pied, surtout lorsque, justement, tu as plusieurs paires table/userform à gérer

    Cela dit, désolé, mais pour moi, coder des textbox & i et des lettres de colonnes dans des tag de contrôles, ce n'est pas propre du tout. L'utilisation de tags non plus, et les arrays de mappage hardcodés non plus, pour les raisons que j'ai invoquées:
    • Listbox1, listbox2 sont des termes incompréhensibles de prime abord (on ne sait pas à quoi ils se réfèrent;
    • Si on déplace, ajoute, permute des colonnes, il faut mettre les mains dans le cambouis et modifier inutilement du code (ce qui implique risques d'erreurs et tests supplémentaires);
    • Hardcoding, ce qui n'est vraiment pas une bonne manière de coder;
    • La non-utiliation des tableaux structurés (qui facilitent l'appairage colonne/contrôle) est pour moi un non-sens en 2019.


    Ceci dit, tu proposes effectivement l'exemple 2 avec un array qui évite les noms suffixés des contrôles, mais je préfère une table de mappage que le hardcoding. Cela dit, si tu préfères la solution de l'array, pourquoi proposes-tu l'histoire des textbox & i dans ton message suivant? En programmation, la constance dans une solution à laquelle on croit est préférable à des solutions qui varient tout le temps.


    Comme dit précédemment, la perte des valeurs lors d'un bug représente un faux problème lorsque l'on sait gérer correctement les On Error....


    Après, comme tu le dis, chacun sa soupe, mais je préfère un million de fois la mienne à la tienne
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  19. #19
    Inactif  

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2012
    Messages
    4 903
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 4 903
    Billets dans le blog
    36
    Par défaut
    Bonjour,

    Ouais,

    On a quelqu'un qui pose visiblement sa première question sur le forum, ou à peu près; et vous lui balancez un débat de vieux spécialistes. À ce que je pense et ce que je sache, son besoin c'est d'une solution qui fonctionne. Sans nier la nécessité de débattre à certains moments, il faudrait peut-être ajouter un lien entre le sujet et un sous-forum consacré au(x) débat(s) qui émergerai(ent) à la suite d'une réponse à une question

    Parce que là, à mon avis, et ce n'est pas la première fois, vos débats très (peut-être même trop) "pointus" ne sont pas vraiment à la portée des gens qui posent leur question sur un problème terre-à-terre.

    Parce que, entre comprendre à fond vos arguments et apprendre un nouveau langage...

  20. #20
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut Pourquoi je n'aime pas les variables publiques
    Voici un petit code à placer dans un module standard. On notera l'indispensable Option Explicit en début de module. Il suffit de lancer CallingProc et de regarder le résultat dans la fenêtre d'exécution

    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
    Option Explicit
     
    Public PV As Long
     
    Sub CallingProc()
      Dim RefValue As Long
      Dim ValValue As Long
     
      PV = 5
      RefValue = 5
      ValValue = 5
      CalledProc RefValue, ValValue
      Debug.Print "Valeur PV après CalledProc appelée: ", , PV
      Debug.Print "Valeur RefValue CalledProc appelée: ", , RefValue
      Debug.Print "Valeur ValValue CalledProc appelée: ", , ValValue
      WrongUsingPublicValue
      Debug.Print "Valeur PV après WrongUsingPublicValue appelée: ", PV
      Debug.Print "Valeur RefValue WrongUsingPublicValue appelée", RefValue
      Debug.Print "Valeur ValValue WrongUsingPublicValue appelée", ValValue
      WrongUsingLocalVariable
      Debug.Print "Valeur PV après WrongUsingLocalVariable appelée: ", PV
      DualPVInProc
      Debug.Print "Valeur PV après DualPVInProc appelée: ", , PV
    End Sub
     
     
    Sub CalledProc(RefArg As Long, ByVal ValArg As Long)
      PV = 10
      RefArg = 10
      ValArg = 10
    End Sub
     
    Sub WrongUsingPublicValue()
      Dim VP As Long
      PV = 20
    End Sub
     
    Sub WrongUsingLocalVariable()
      Dim PV As Long
     
      PV = 50
    End Sub
     
    Sub DualPVInProc()
      Dim PV As Long
     
      PV = 50
      Module1.PV = 100
    End Sub
    Valeur PV après CalledProc appelée: 10
    Valeur RefValue CalledProc appelée: 10
    Valeur ValValue CalledProc appelée: 5
    Valeur PV après WrongUsingPublicValue appelée: 20
    Valeur RefValue WrongUsingPublicValue appelée 10
    Valeur ValValue WrongUsingPublicValue appelée 5
    Valeur PV après WrongUsingLocalVariable appelée: 20
    Valeur PV après DualPVInProc appelée: 100
    Que nous apprend ce code?

    Après CalledProc, on constate que l'argument ByRef s'est comporté comme la variable globale. L'argument ByVal, lui, n'a pas modifié la valeur dans CallingProc. On peut donc considérer que ByRef permet de se passer de la variable publique, et que le ByVal permet d'utiliser une variable "en lecture seule" puisque la variable côté appelant n'a pas été modifiée. Avec une variable publique, ce mécanisme de la variable "en lecture seule" est tout simplement impossible, n'importe quelle procédure pouvant la modifier.

    La procédure WrongUsingPublicValue nous montre que si nous nous trompons dans l'utilisation de la variable locale (PV au lieu de VP), VBA ne gueule pas malgré le Option Explicit car une variable publique PV existe. Donc, nous modifions la mauvaise variable sans aucune alerte. Le débogage de ce genre d'erreur est délicat et chronophage.

    La procédure WrongUsingLocalVariable pose aussi problème car nous pourrions croire que l'on va modifier la variable publique (la déclaration de PV peut se situer plus haut dans la proc et être "oubliée"), alors qu'en fait, on modifie la variable locale.

    La procédure DualPVInProc montre que si l'on a une variable locale du même nom qu'une variable publique et que l'on veut modifier la publique, on doit la préfixer de son module, ce qui n'est guère pratique lorsque l'on a plusieurs modules.

    Dans tous les cas présentés ci-dessus, la non-utilisation d'une variable publique au profit d'arguments (ByRef ou ByVal selon que l'on veut pouvoir modifier ou non la variable côté appelant) évite ces erreurs et ces ambiguïtés.

    Je n'aime pas les variables globales parce que:
    • Si un module a une VP nommée de la même manière que celle d'un autre module, il va falloir les préfixer du nom du module (elles ne seront donc plus publiques, au sens usuel du terme);
    • Pas de libération de mémoire;
    • Risque de manipuler une variable en croyant en manipuler une autre;
    • Procédures/fonctions/properties sont fortement couplées à ces variables publiques, et donc peu réutilisables;
    • Procédures/fonctions/properties sont fortement couplées à ces variables publiques, et donc difficilement testables;
    • Risque de confusion entre variables globales et variables locales;
    • Je pense que l'on peut s'en passer au profit d'arguments passés à des Sub/Function/Property petites, concises et qui ont une et une seule responsabilité pour éviter les désagréments exposés plus haut.


    Je pense sincèrement et sans esprit de polémique que les bonnes pratiques de programmation amènent à éviter les variables publiques, à écrire des procédures/fonctions les plus courtes et concises possibles avec une et une seule responsabilité, ce qui les rend génériques, facilement testables, réutilisables et maintenables. C'est juste le fruit de mon expérience d'autodidacte, mêlée à une formation théorique suivie "sur le tard" de trois ans durant laquelle j'ai pu confronter mes pratiques avec d'autres, les affiner et parfois, voire souvent, les corriger, qui me font dire, pratiquer et partager cela sur nos forums.

    [EDIT]
    Cela ne veut pas dire qu'il ne faut jamais de variables publiques, mais je pense qu'il faut les limiter aux variables d'application, c'est-à-dire des variables qui permettent à l'application de fonctionner, et les bannir systématiquement pour les variables métier. Comme exemple d'une variable d'application, je prendrai un flag booléen dont l'état (VRAI ou FAUX) est modifié par différentes procédures, notamment événementielles, et utilisé par d'autres (notamment événementielles). Je pense qu'il serait sage de limiter autant que faire se peut les variables publiques à des variables booléennes. Il faut toutefois être conscient que le problème de ces variables est que, lors du test d'une procédure qui les utilise, on ne pourra pas toujours envisager tous les cas possibles. Si le caractère binaire d'une variable booléenne permet le test de ses deux états, il n'en va pas de même pour d'autres variables dont l'amplitude des valeurs possibles rend l'exhaustivité des tests illusoire, amenant inévitablement à un bug à un moment donné (Loi de Murphy).




    Je souhaiterais que les débats techniques ne soient pas des combats de coq et qu'ils puissent de dérouler de manière courtoise à coups d'arguments et de démonstrations. Je pense que c'est ainsi que nos échanges pourront servir au mieux la communauté des utilisateurs/programmeurs/essayeurs/bidouilleurs VBA.
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

Discussions similaires

  1. [WD20] Remplir tableau avec plusieurs requetes
    Par Ylusson dans le forum WinDev
    Réponses: 5
    Dernier message: 01/12/2016, 10h52
  2. Réponses: 1
    Dernier message: 13/04/2011, 09h44
  3. Remplir une table avec plusieurs formulaires
    Par morgane32 dans le forum IHM
    Réponses: 1
    Dernier message: 08/05/2009, 12h19
  4. remplir un tableau avec des références à plusieurs feuilles
    Par Amiral19 dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 22/07/2007, 22h26
  5. Focus sur les boutons avec plusieurs formulaire
    Par davids21 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 19/04/2005, 15h48

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