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?
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...
Pour l'ordre des sub et function dans un (des) module(s), vba s'en fiche...
Pour le reste, à vue de nez, si vous n'appelez 'boiteDialogue' qu'avec le nom, ce comportement est normal !
La macro exemple recolte les valeurs des cellules dans des variables, mais vous n'en envoyez qu'une (nom) en paramètre (boiteDialogue nom)
D'un autre côté, si vous envoyez à 'boiteDialogue' des variables n'ayant reçu aucune valeur elles ne seront plus 'missing' et auront leur valeur par défaut (0 pour Integer et "" pour string).
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 boiteDialogue(nom As String, Optional prenom, Optional age)
'Si l'âge est manquant
If IsMissing(age) Or age = 0 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
Pour faire fonctionner votre exemple original suivant des cas différents, c'est la macro exemple qu'il faut changer pour que l'autre fonctionne correctement :
VB:
Sub exemple()
Dim nom As String, prenom As String, age As Integer
nom = Range("A1")
prenom = Range("B1")
age = Range("C1")
boiteDialogue nom
boiteDialogue nom, prenom
boiteDialogue nom, prenom, age
boiteDialogue nom,,age
End Sub
Le code initial fonctionne bien sans y toucher.
Si on met "optional", c'est bien pour pouvoir se passer d'un ou deux des derniers arguments (en passer 1, 2 ou 3)
Je me suis dit : Evidemment car on ne passe que le nom en paramètre dans la macro, donc ni le prénom ni l'âge ne peuvent être analyser, si bien même B1 et C1 contiennent quelque chose.
Peut être est ce une interprétation erronée des propos de Shanon. Attendons sa réponse.
Pour faire fonctionner votre exemple original suivant des cas différents, c'est la macro exemple qu'il faut changer pour que l'autre fonctionne correctement :
VB:
Sub exemple()
Dim nom As String, prenom As String, age As Integer
nom = Range("A1")
prenom = Range("B1")
age = Range("C1")
boiteDialogue nom
boiteDialogue nom, prenom
boiteDialogue nom, prenom, age
boiteDialogue nom,,age
End Sub
Lorsque j'exécute cette macro néanmoins, je n'ai pas le résultat escompté. J'ai successivement le nom, puis le nom & prénom, puis le nom prénom age puis nom et age qui s'affichent. Et si par exemple je ne mets rien dans "prénom" alors j'ai successivement le nom, le nom, le nom et age, le nom et l'age. Or ce que je veux est que selon le résultat du if on ait l'affichage correspondant.
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 boiteDialogue(nom As String, Optional prenom, Optional age)
'Si l'âge est manquant
If IsMissing(age) Or age = 0 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
Donc si j'ai bien compris (cf réponse @Roblochon) si je mets boitedialogue nom, prenom, age et qu'ensuite dans ma feuille excel je remplis nom et prénom mais pas l'age par exemple, on considère que age prend sa valeur par défaut donc 0 vu que je l'ai déclaré comme integer. D'où l'affichage du "0 ans" dans mon premier exemple lorsque rien n'était entré dans C1 pour prénom ?
Oui oui c'est bien cela le code que vous avez mis en post 3 correspond bien à mon besoin !
Je répondais au post 5 de @Roblochon qui me disait de modifier la macro Exemple
Le code initial fonctionne bien sans y toucher.
Si on met "optional", c'est bien pour pouvoir se passer d'un ou deux des derniers arguments (en passer 1, 2 ou 3)
oui mais si par exemple je mets boitedialogue nom en omettant age et prénom qui sont effectivement optionnels, alors le résultat n'est pas le résultat attendu