Problème de valeur de variables public
Bonjour à tous,
J'ai un problème car je souhaite attribuer des valeurs à mes variables public de type Range dans une sub (data), puis appeler cette sub dans une autre sub(main) et ensuite utiliser ces variables dans une fonction(split). (j'espère être clair
Seul problème, le résultat de ma fonction change en fonction de si je "set" les valeurs de mes variables dans la sub data, puis je l'appelle dans la sub main(ce que je cherche à faire) , et si je les set directement dans la procédure main qui appelle également la fonction dans laquelle je veux utiliser les variables...
Pourquoi ce changement? et comment y remedier?
Voici mon fichier en pj (ce sont les variables C q et d que je veux set dans la sub data)
Bonjour,
Utiliser des variables publiques est, à mon avis, une très mauvaise méthode de programmation : Elle rend chaque procédure dépendante de l'initialisation de ces variables effectuée (ou oubliée) par une autre procédure.
La bonne méthode consiste à déclarer, et initialiser des variables locales dans la procédure principale et à transmettre ces variables en argument des autres procédures.
Bonjour Newbie14
@Patrice33740, je sais que tu es fortement allergique aux variables publiques
Mais dans certains développements tu es obligé de passer par elles, il faut juste savoir ce qu'on fait et quel est le besoins réel
@Newbie14, pas tout compris je vais regarder le fichier voir si c'est plus explicit
Re,
Ce code semble bien fonctionner
Option Explicit
Option Base 1
Sub Main()
Dim n As Long
Dim W As Long
Dim L As Long
Dim Noeud As Range
n = Application.WorksheetFunction.CountA(Range("A6:A5000"))
Range("B2").Value = n
W = Range("C2").Value
L = Range("D2").Value
Set Noeud = Range("A6", Range("A6").Offset(n - 1, 0))
resultat = Split(n, W, L, Noeud)
MsgBox "Le coût de la tournée géante est " & resultat
End Sub
Function Split(ByVal n As Long, ByVal W As Long, ByVal L As Long, ByVal Noeud As Range)
Dim d, q, C As Range
Dim Charge As Long
Dim Coût As Long
Dim tournée As String
Dim V() As Long 'label
Dim Pred() As Long 'Prédecesseurs
Dim j As Integer
Set C = Range("g6", Range("G6").Offset(n - 1, n - 1))
Set d = Range("e6", Range("E6").Offset(n - 1, 0))
Set q = Range("d6", Range("D6").Offset(n - 1, 0))
ReDim V(n)
ReDim Pred(n)
'Initialisation
V(1) = 0 'Label du noeud dépôt
For i = 2 To n
V(i) = 10000 'On initialise les labels à l'infini
Next
j = 2
For i = 2 To n
Charge = 0 'La charge totale
Coût = 0 'Le coût total
tournée = "0"
Do Until j > n Or Charge > W Or Coût > L
Charge = Charge + q(j) 'q(j) = charge du noeud j
If Coût = 0 Then
Coût = C(1, j) + d(j) + C(j, 1) 'C(1,j) = coût du noeud dépot 1 au noeud j
Else
Coût = Coût - C(j - 1, 1) + C(j - 1, j) + d(j) + C(j, 1)
End If
If Charge <= W And Coût <= L Then
If V(i - 1) + Coût < V(j) Then
V(j) = V(i - 1) + Coût 'Label du noeud j
Pred(j) = i - 1 'Prédecesseur du noeud j
End If
tournée = tournée & "-" & Noeud(j)
Range("F2").Offset(0, i - 1).Value = Coût
Range("F1").Offset(0, i - 1).Value = Charge
If j = n Then
tournée = tournée & "-0"
Range("F3").Offset(0, i - 1).Value = tournée
End If
j = j + 1
Else
tournée = tournée & "-0"
Range("F3").Offset(0, i - 1).Value = tournée
End If
Loop
Next i
Worksheets("Split").Range("c6").Resize(UBound(V), 1) = Application.Transpose(V)
Worksheets("Split").Range("f6").Resize(UBound(Pred), 1) = Application.Transpose(Pred)
Split = WorksheetFunction.Sum(Range("G2", Range("G2").Offset(0, n - 1)))
End Function
@+
Bonjour
Vous devez déclarer votre variable n en public puisqu'elle est utilisée dans la sub Data
Donc au dessus vous devez avoir ceci :
Public d As Range, q As Range, C As Range
Public n As Long
Vous pouvez alors déplacer les 3 set dans votre Sub Data
N'oubliez pas de supprimer Dim n as long de la sub main évidemment
Attention que si vous déclarez Public d, q, c as range, d et q sont en variant et non en Range. D'où le changement que je vous donne ci-dessus
Cordialement
Edit: oups il y avait déjà du monde qui a répondu là...
Merci à tous pour vos réponses.
En fait je suis obligé de déclarer C, q et d en public parce que c'est ce qui m'est demandé. Donc la solution de Dan me convient le mieux .
Merci beaucoup à bientôt
@Patrice33740, je sais que tu es fortement allergique aux variables publiques
Mais dans certains développements tu es obligé de passer par elles, il faut juste savoir ce qu'on fait et quel est le besoins réel
Ce n'est pas une allergie, leur nécessité dans un module standard est extrêmement rare, ce n'est pas le cas du code objet de ce post.
Et dans les modules de classe ce ne sont pas des "variables publiques" mais des méthodes ou des propriétés de l'objet : c'est très différent, je suis même incitatif à leur utilisation.