XL 2013 [Résolu] Pb portée variable

TooFatBoy

XLDnaute Barbatruc
Bonjour,

J'ai une variable qui change de valeur alors qu'à mon avis elle ne devrait pas !
Et je ne comprends pas pourquoi. :(

VB:
Sub Verticaliser()

Dim ColS As Long, LigS As Long, ColD As Long, LigD As Long

ColS = 6
LigS = 5
ColD = 18
LigD = 14

Call Copier("Part-L", ColS, LigS, ColD, LigD)
Call Copier("Part-R", ColS, LigS, ColD, LigD)

End Sub

VB:
Sub Copier(FeuilSource As String, ColSource As Long, LigSource As Long, ColDestination As Long, LigDestination As Long)

If Sheets("Liste").Cells(LigDestination + 1, 3) <> "" Then
    LigDestination = Sheets("Liste").Cells(LigDestination, 3).End(xlDown).Row
End If
LigDestination = LigDestination + 1

End Sub

Ma variable "LigD" qui, à mon avis devrait avoir une portée limitée à la procédure "Verticaliser", change de valeur dans la procédure "Copier" ! :eek:

En effet, quand la ligne "LigDestination = LigDestination + 1" est exécutée, la variable "LigDestination" est bien sûr incrémentée, mais la variable "LigD" l'est aussi en même temps, ce qui ne me semble pas normal.

Pourriez-vous me dire si le comportement que je constate est normal ?
Et si celui-ci est normal, pourriez-vous m'expliquer pourquoi ?


Merci par avance pour vos futures réponses. ;)
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
Bonsoir.
Oui, c'est normal qu'un paramètre passé ByRef (assumé si non précisé) soit modifié par la Sub.
Ça vient de ce qu'elle reçoit en fait l'adresse de la variable du programme appelant, et du coup elle est maître de son contenu. Elle n'a même pas d'autre choix que de la modifier.
Si vous préférez que le programme appelant dépose, plutôt que son adresse, une copie de la valeur de la variable dans une variable locale de la procédure, vous devez préciser ByVal devant le nom du paramètre dans l'instruction Sub.
Remarques: 1) — Ce n'est pas possible pour un tableau, mais c'est possible pour un Variant contenant un tableau.
2) — Il faudrait toujours le faire pour un objet (ce n'est déjà qu'une simple adresse de l'exemplaire, on ne va pas spécifier en plus une adresse vers cette adresse, c'est idiot)
 
Dernière édition:

TooFatBoy

XLDnaute Barbatruc
Hier, juste après avoir ouvert cette question et en attendant des réponses, j'ai contourné le problème en déclarant les variables de ma premières procédures en tant que constantes.

VB:
Sub Verticaliser()

Const ColS As Long = 6
Const LigS As Long = 5
Const ColD As Long= 18
Const LigD As Long= 14

Call Copier("Part-L", ColS, LigS, ColD, LigD)
Call Copier("Part-R", ColS, LigS, ColD, LigD)

End Sub

VB:
Sub Copier(FeuilSource As String, ColSource As Long, LigSource As Long, ColDestination As Long, LigDestination As Long)

If Sheets("Liste").Cells(LigDestination + 1, 3) <> "" Then
    LigDestination = Sheets("Liste").Cells(LigDestination, 3).End(xlDown).Row
End If
LigDestination = LigDestination + 1

End Sub

Ca marche parfaitement. Mais après avoir lu la réponse de Dranreb, une nouvelle question m'est venue aujourd'hui :
Quand j'essaye d'incrémenter une constante, bien sûr j'ai une erreur qui survient.
Mais dans ma seconde procédure l'incrémentation se passe sans problème.
Or si la variable est passée par adresse, je devrais avoir le même problème dans ma seconde procédure que dans la première lors de l'incrémentation de la variable qui est une constante. Non ?
 

Dranreb

XLDnaute Barbatruc
Oui, ça parait logique, c'est même plutôt bien raisonné je trouve.
Mais on peut supposer que si le compilateur est contraint de passer ByRef une expression, non modifiable donc, il en prépare lui même une copie dans une zone dont il passe l'adresse, pour que ça puisse marcher sans endommager des constantes ou autres. Mais c'est toujours idiot. Il vaut mieux spécifier ByVal devant de tels paramètres.
 

TooFatBoy

XLDnaute Barbatruc
Mais on peut supposer que si le compilateur est contraint de passer ByRef une expression, non modifiable donc, il en prépare lui même une copie dans une zone dont il passe l'adresse, pour que ça puisse marcher sans endommager des constantes ou autres. Mais c'est toujours idiot. Il vaut mieux spécifier ByVal devant de tels paramètres.
C'est exactement ce que je me suis aussi dit.
Donc, 100 % d'accord avec ça.

J'avais tenté l'utilisation de constantes en attendant une réponse car ça me semblait logique pour bloquer la modification de ces variables.
Mais maintenant que j'ai la bonne réponse grâce à vous, l'utilisation de ByVal me semble en effet s'imposer.


Je conclurais en disant "Merci Bernard". ;)
 

Discussions similaires

Statistiques des forums

Discussions
312 488
Messages
2 088 862
Membres
103 979
dernier inscrit
imed