Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

XL 2016 Procédures et arguments

shanon7

XLDnaute Junior
Bonjour !

Je suis tombée sur ce morceau de code qui illustre la notion de procédures et arguments en VBA, mais je ne comprends pas son exécution. Voici le code en question :
VB:
Sub exemple()

    Dim nom As String, prenom As String, age As Integer
    
    nom = Range("A1")
    prenom = Range("B1")
    age = Range("C1")

  
  boiteDialogue nom
    

End Sub

Private Sub boiteDialogue(nom As String, Optional prenom, Optional age)

    'Si l'âge est manquant
    If IsMissing(age) Then
        
        If IsMissing(prenom) Then 'Si le prénom est manquant, on n'affiche que le nom
            MsgBox nom
        Else 'Sinon, on affiche le nom et le prénom
            MsgBox nom & " " & prenom
        End If

    'Si l'âge a été renseigné
    Else

        If IsMissing(prenom) Then 'Si le prénom est manquant, on affiche le nom et l'âge
            MsgBox nom & ", " & age & " ans"
        Else 'Sinon on affiche le nom, le prénom et l'âge
            MsgBox nom & " " & prenom & ", " & age & " ans"
        End If
    
    End If
      
End Sub

1/ Je ne comprends pas pourquoi la sub "exemple" est entrée avant la sub "boitedialogue" alors que la sub exemple fait appel à la sub boitedialogue. Bon, cela ne semble pas être un souci dans VBA car la macro s'exécute bien mais cela me semble illogique comme ordre ?

2/ Je pensais que lors du lancement de la macro "exemple", la macro "boitedialogue" allait se lancer et donc que les ifs allaient être testés et donc que en fonction de l'issue, on aurait tel ou tel résultat. Par exemple, si je n'entre pas d'âge en cellule C1 (mais j'entre un nom et un prénom en A1 et B1 resp.) , seule la condition If ismissing(age) est vraie donc je m'attendais à ce que s'affiche le message "nom, prenom" or seul le nom s'affiche. Je sais que le nom s'affiche car dans la sub Exemple il y a boitedialogue nom mais même si je mets boitedialogue nom, prenom, age alors ce qui s'affiche est "nom, prenom, 0 ans".

En d'autres termes, je ne comprends pas vraiment cette macro et comment faudrait-il l'écrire afin qu'elle s'exécute correctement?

Merci pour votre aide,

Shanon
 
Solution
Bonjour Shanon,

Concernant l'ordre, le VBA n'en a que faire. Il exécute ce qu'on lui demande, chaque macro est indépendante.
Vous auriez même pu, pour simplifier la lecture mettre la macro boiteDialogue dans un autre module.

Concernant la réponse c'est normal car les paramètres prenom et age sont déclarés optionnel et vous passer la commande boiteDialogue nom donc prénom et age ne sont pas traités par la boite de dialogue.
Vous pouvez l'améliorer en faisant :
1- boiteDialogue nom, prenom, age
2- If IsMissing(age) Or age = 0 Then
VB:
Sub exemple()
    Dim nom As String, prenom As String, age As Integer
    nom = Range("A1")
    prenom = Range("B1")
    age = Range("C1")
    boiteDialogue nom, prenom, age
End Sub
Private Sub...

patricktoulon

XLDnaute Barbatruc
bonjour
je peux jouer moi aussi?(au risque de rendre les chose plus obscure )
VB:
Sub exemple()
    Dim nom As String, prenom As String, age As String
    nom = Range("A1")
    prenom = Range("B1")
    age = Range("C1")
    boiteDialogue nom
    boiteDialogue nom, prenom
    boiteDialogue prenom:=prenom
    boiteDialogue nom, prenom, age
    boiteDialogue age:=age
End Sub
Private Sub boiteDialogue(Optional nom As String = "", Optional prenom As String = "", Optional age As String = "")
'Si l'âge est manquant
    Dim critere As Boolean, ans$
    ans = Array("", " ans")(Abs(age <> ""))

    critere = nom = "" Or prenom = "" Or age = ""

    If critere Then MsgBox "il y a des manquants" & vbCrLf & Trim(nom & " " & prenom & " " & age & ans)

    If Not critere Then MsgBox " pas de manquant" & vbCrLf & Trim(nom & " " & prenom & " " & age & ans)

End Sub
 

mapomme

XLDnaute Barbatruc
Supporter XLD
Re,
On doit pouvoir faire beaucoup plus court :
VB:
Sub exemple()
Dim nom As String, prenom As String, age As String

   nom = Range("A1")
   prenom = Range("B1")
   age = Range("C1")
   boiteDialogue nom, prenom, age
   boiteDialogue nom, prenom
   boiteDialogue nom, , age
   boiteDialogue nom
End Sub

Private Sub boiteDialogue(nom As String, Optional prenom = "", Optional age As String = 0)
   MsgBox nom & IIf(prenom = "", "", " " & prenom) & IIf(Val(age) = 0, "", ", " & Val(age) & " an(s)")
End Sub

edit : Salut @Roblochon
 

Pièces jointes

  • shanon7- Arguments optionnels- v1.xlsm
    16.1 KB · Affichages: 14
Dernière édition:

patricktoulon

XLDnaute Barbatruc
bonjour @mapomme
moi qui parlais d'obscurité ben voila maintenant des double iif
Quel est le résultat attendu ?

Code:
 If IsMissing(prenom) Then 'Si le prénom est manquant, on n'affiche que le nom
            MsgBox nom
        Else 'Sinon, on affiche le nom et le prénom
            MsgBox nom & " " & prenom
        End If
ben c'est simple nom?
si nom est manquant il veut afficher le nom
et pareil pour les autres

j'suis ptdr
 

shanon7

XLDnaute Junior
Quel est le résultat attendu ?
Le post qui correspond à mon besoin est celui de @sylvanu dans son post #3.

Le résultat attendu est simplement que lors de l'exécution de la sub exemple, la sub boitedialogue est correctement appelée et les ifs correctement testés.
Donc si par exemple j'entre "lb" en A1, "shanon" en B1 et rien du tout en C1. Puis je lance la macro exemple telle que décrite dans le post 5 (boite dialogue nom, prenom, age). Conformément aux ifs écrits dans la macro boite de dialogue, le message censé apparaitre à la fin est "lb shanon".

Or si dans la macro exemple je fais appel à boite de dialogue en omettant les arguments optionnels prenom et age, alors seul le nom s'affiche.
Et si je modifie exemple en mettant (comme suggéré dans l'une des réponses à mon post)
boitedialogue nom
boitedialogue nom, prenom
boitedialogue nom,,age
boite dialogue nom, prenom, age
Alors vont successivement s'afficher : le nom, le nom et prénom, le nom et l'age et nom prénom et age. Et si par exemple je ne remplis rien en C1 comme age, alors vont s'afficher successivement le nom, puis le nom et prénom, puis le nom, puis le nom et prénom. Ce qui là non plus ne correspond pas à ma demande

Merci

Shanon
 

patricktoulon

XLDnaute Barbatruc
@shanon7
quand tu a des arguments optionels et que tu traite l'information
les if else ne sont pas la bonne méthode tout du moins les if else compliquent la tache
utilise le booleeen de l’état c'est plus court ,propre et tu peux grouper
d'autant plus que tu concate une chaine avec les 3 données qui est la chaîne répondant aux 3 arguments due-ment renseignés

en gros ce que ton code fait c'est
si il en manque un des 3 tu affiche les deux autres

donc c'est pas la peine d'imbriquer des conditions

raisonne simplement
quelque chose + rien +encore moins = toujours ce quelque chose

j'attire ton attention sur le fait que manquants ou pas je compile les 3 a chaque tests
j'ai aussi mis toute les sortes d’écriture d'appel
VB:
Sub exemple()
    Dim nom As String, prenom As String, age As String
    nom = Range("A1")
    prenom = Range("B1")
    age = Range("C1")
    boiteDialogue nom
    boiteDialogue nom, , age
    boiteDialogue nom, age:=age
    boiteDialogue , prenom
    boiteDialogue prenom:=prenom
    boiteDialogue prenom:=prenom, age:=age
    boiteDialogue nom, prenom
    boiteDialogue , , age
    boiteDialogue age:=age
    boiteDialogue nom, prenom, age
End Sub
Private Sub boiteDialogue(Optional nom As String = "", Optional prenom As String = "", Optional age As String = "")

    Dim critere As Boolean, ans$
    ans = Array("", " ans")(Abs(age <> ""))'si age<>""  alors ans="ans" sinon ans=rien 

    critere = nom = "" Or prenom = "" Or age = ""'test des 3 groupés donc  critere sera false ou true 
'donc si critere = true il y a des manquants sinon critere=false 

    'si on veut que ca soit déclanché quand il y a des maquants: DONC SI TRUE !!!!
    If critere Then MsgBox "il y a des manquants" & vbCrLf & Trim(nom & " " & prenom & " " & age & ans)

    'si on veut que ca soit déclanché quand il manque rien:DONC SI FALSE !!!!
    'If Not critere Then MsgBox " pas de manquant" & vbCrLf & Trim(nom & " " & prenom & " " & age & ans)

End Sub
 

Hasco

XLDnaute Barbatruc
Repose en paix
Ce n'était que des exemples d'appel à une macro avec des paramètre optionels.
Dans la macro que vous avez choisie, les paramètres n'ont pas besoin d'être optionels.
Je crois que vous vous mélangez les pinceaux entre les paramètres et leurs valeurs à un instant T.
 

patricktoulon

XLDnaute Barbatruc
et pour tout te dire comme le but est de concaténer les arguments non omis
avec ma méthode tu n'a qu'a trimer le concat car mes argument( a l'inverse de ta méthode) ont une valeur par defaut qui est ""(soit vide)
exemple de ce raisonnement
VB:
Sub exemple()
    Dim nom As String, prenom As String, age As String
    nom = Range("A1")
    prenom = Range("B1")
    age = Range("C1")
    boiteDialogue nom
    boiteDialogue nom, , age
    boiteDialogue nom, age:=age
    boiteDialogue , prenom
    boiteDialogue prenom:=prenom
    boiteDialogue prenom:=prenom, age:=age
    boiteDialogue nom, prenom
    boiteDialogue , , age
    boiteDialogue age:=age
    boiteDialogue nom, prenom, age
End Sub
Private Sub boiteDialogue(Optional nom As String = "", Optional prenom As String = "", Optional age As String = "")
'Si l'âge est manquant
    Dim critere As Boolean, ans$
    ans = Array("", " ans")(Abs(age <> ""))
MsgBox Trim(nom & " " & prenom & " " & age & ans)

End Sub
c'est pas parce que tu a MsgBox Trim(nom & " " & prenom & " " & age & ans) que tu va voir les 3 a chaque fois tu verra ce que tu a injecté par les arguments
 

mapomme

XLDnaute Barbatruc
Supporter XLD
Ce qui là non plus ne correspond pas à ma demande
Ce n'est plus une question de syntaxe ou de savoir si les arguments sont présents ou non.
C'est une question de logique de construction de votre programme. Dans votre code, vous testez la présence ou non des arguments. Vous ne testez jamais la valeur des arguments (Oups! @Roblochon a déjà répondu ce que dis. Désolé!)

Avez-vous essayé le code de mon message #17 ?
 

patricktoulon

XLDnaute Barbatruc
@mapomme je le redis même tester les valeurs est inutile puisque le but est LE CONCAT !!!
mettre les argument avec une valeur par defaut("") et concaténer c'est tout

maintenant si le but était autre (si l'un ou l'autre) (faire ceci ou cela ) ça serait différent mais là non c'est inutile
 

shanon7

XLDnaute Junior

Oui j'ai essayé le code votre message #17 et comme je le dis, cela m'affiche successivement les différents éléments : supposons que j'entre "nom" dans A1, "prénom" en B1 et rien en C1
J'ai une boite de dialogue n°1 "nom prenom"
Une boite dialogue 2 "nom prénom"
Boite de dialogue 3 "nom"
Boite dialogue 4 "nom"
Qui s'affichent successivement.
Là où je voudrais seulement avoir "nom prénom" affiché une seule fois.

En revanche je comprends (je crois) où vous voulez en venir @patricktoulon en disant que cette méthode des ifs n'est pas la plus adéquate avec les arguments optionnels.

Je ne sais pas, peut-être me suis-je mal exprimée concernant ma demande initiale ou alors quelque chose m'échappe dans ce que vous me dites (je débute en VBA) car pour moi ce code ne correspond pas à ce que je veux. Contrairement au post #3. Peut-être pouvez-vous le lancer et vous aurez une idée d'où je veux en venir

Par ailleurs oui ce code a pour but de tester la présence ou non des arguments et non leur valeur. C'est bien l'objectif. Je n'ai pas écrit ce code, je l'ai trouvé sur un site de formation VBA en ligne et ce code a effectivement pour but de montrer comment tester la présence ou non d'arguments.

Merci pour votre temps

Shanon
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
re
en esprérant que j'arete d'etre invisible au yeux de shanon7
fait moi plaisir shanon7 test ça
VB:
Sub exempleNOM()
    Dim nom As String, prenom As String, age As string
       nom = Range("A1")
    prenom = Range("B1")
    age = Range("C1")
 boiteDialogue nom
End Sub

Sub exemplePRENOM()
    Dim nom As String, prenom As String, age As string
       nom = Range("A1")
    prenom = Range("B1")
    age = Range("C1")
 boiteDialogue prenom
End Sub

Sub exempleAGE()
    Dim nom As String, prenom As String, age As string
       nom = Range("A1")
    prenom = Range("B1")
    age = Range("C1")
 boiteDialogue age
End Sub

Sub exempleNOM_PRENOM_AGE()
    Dim nom As String, prenom As String, age As string
       nom = Range("A1")
    prenom = Range("B1")
    age = Range("C1")
 boiteDialogue nom,prenom,age
End Sub

Private Sub boiteDialogue(Optional nom As String = "", Optional prenom As String = "", Optional age As String = "")
    Dim  ans$
    ans = Array("", " ans")(Abs(age <> ""))
 MsgBox Trim(nom & " " & prenom & " " & age & ans)
End Sub
 

shanon7

XLDnaute Junior

Oui bien sûr je vais tester ça merci

Cest juste que je ne comprenais pas toujours vos posts précédents(certains morceaux de code) , étant assez novice en vba comme je l'ai dit

Il faut que je cherche à quoi correspondent trim et array que je ne connais pas

Shanon
 

Discussions similaires

Réponses
2
Affichages
198
Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…