Problème de remplissage d'une colonne conditionné à d'autres valeurs
Bonjour,
Je suis nouvelle sur ce forum et en quelques sortes débutante avec Excel VBA.
J’ai créé une macro qui ne fonctionne pas comme je le souhaiterais.
Mon fichier de base est une liste de composants de 3 colonnes :
- Hierarchy = donne la relation enfant/parent de chaque ligne, est constitué de la même logique que pour un sommaire avec plusieurs chapitres et sous-chapitres.
- Level = lié au niveau hiérarchique, 1 = parent le plus haut, 5 = enfant le plus bas.
- Total Unit Weight = poids en kg de chaque ligne.
Dans la macro je souhaite créer une nouvelle colonne « Tempo » qui donne la valeur 1 ou 0 aux cellules de cette colonne selon :
- Règle 1 : Si Total Unit Weight est différent de zéro, alors Tempo est à 1
- Règle 2 : Si Total Unit Weight est égal à zéro alors :
- Si l’un de ses parents à un Total Unit Weight différent de zéro ou si tous ses enfants directs (dont avec un Level ayant une valeur de +1) ont une valeur 1 dans la colonne Tempo, alors la valeur Tempo est égale à 1.
- Sinon la valeur Tempo est égale à 0.
Le remplissage des lignes se fait par valeur Level décroissant, on remplit d’abord les enfants les plus bas pour remonter ensuite au parent le plus haut (essentiel pour pouvoir appliquer la première ligne de la règle 2).
Voici ce que j’ai écrit mais ça ne fonctionne pas comme je le souhaite.
La boucle hasNonZeroParent m’a l’air de fonctionner mais pas la boucle allChildrenFilled.
J’espère avoir été claire dans la présentation du problème. Je joins le fichier Excel et le code Macro ci-dessous.
Dans le fichier excel, j'ai ajouté une colonne "Ce que devrait afficher la macro" affichant le résultat que devrait me sortir la macro.
Merci à vous.
Fichier Excel :
Edit modo : le code est dans le fichier - Editeur VBA --> Module 2
Bonjour CathyLD
Il est indiqué dans la charte de ce forum que vous avez du lire, tout comme moi
- Ne postez pas la même question sur un autre forum pour éviter de faire perdre bêtement du temps aux membres sur un problème qui peut être déjà résolu sur l'autre forum. L'inverse est également valable, si vous avez déjà posé votre question sur un autre forum, ne créez pas un doublon sur ce forum (à moins d'avoir clôturé le sujet sur l'autre forum).
Bonjour, super projet sur la récursion j'ai adoré !
Je me suis permis d'implémenter votre fichier d'une classe "Node", représentant vos données. Un node est constitué :
d'une valeur (numéro),
un level (1 à 5, ou + si besoin),
un parent (autre node, récursion),
une liste d'enfants (autres nodes)
Votre problème permet d'utiliser le plein potentiel des fonctions récursives sur les paramètres de classe, par exemple lors de la recherche du Tempo.
J'ai adapté le code pour répondre à l'exemple que vous avez fourni. Ainsi la règle 2 n'est pas :
Règle 2 : Si Total Unit Weight est égal à zéro alors :
Si l’un de ses parents à un Total Unit Weight différent de zéro ou si tous ses enfants directs (dont avec un Level ayant une valeur de +1) ont une valeur 1 dans la colonne Tempo, alors la valeur Tempo est égale à 1.
Mais
Règle 2 : Si Total Unit Weight est égal à zéro alors :
Si l’un de ses parents à un Tempo différent de zéro, alors la valeur Tempo est égale à 1.
Vous trouverez ci-joint le fichier en question, et je poste ci-après le code de la classe Node pour les intéressés.
Le code ajouté se trouve donc dans les Modules Module1 et Node. J'ai mis un bouton d'exemple pour vous donner une idée des possibilités variées à partir du modèle. Je pense qu'au vu du niveau de votre module initial vous devriez savoir adapter sans trop de problèmes, mais si vous avez des questions n'hésitez pas.
Classe Node.cls
Option Explicit
Private Type tNode
value As Long
TUW As Double ' total unit weight
parent As Node
children() As Node
End Type
Private this As tNode
Private Sub Class_Initialize()
this.value = -1
this.TUW = 0#
Dim childList() As Node
ReDim childList(0 To 0)
this.children = childList
End Sub
Public Function HasNoParent() As Boolean
HasNoParent = this.parent Is Nothing
End Function
Public Function HasNoChildren() As Boolean
HasNoChildren = UBound(this.children) < 2
End Function
Public Function Tempo() As Long
If this.TUW <> 0 Then
Tempo = 1
Exit Function
ElseIf Not HasNoParent Then
If this.parent.Tempo <> 0 Then
Tempo = 1
Exit Function
End If
ElseIf Not HasNoChildren Then
' pour des questions de logique ce else ne sera jamais accédé mais je l'ai laissé
Dim child As Variant
For Each child In this.children
If child.Tempo <> 0 Then
Tempo = 1
Exit Function
End If
Next child
End If
Tempo = 0
End Function
Public Function Level() As Long
If HasNoParent Then
Level = 1
Else
Level = this.parent.Level + 1
End If
End Function
Public Function toStr() As String
If HasNoParent Then
toStr = this.value
Else
toStr = this.parent.toStr & "." & this.value
End If
End Function
Public Sub addChild(ByVal child As Node)
addToArray child, this.children
End Sub
' Getters and Setters
Public Property Get value() As Long
value = this.value
End Property
Public Property Get TUW() As Double
TUW = this.TUW
End Property
Public Property Get parent() As Node
Set parent = this.parent
End Property
Public Property Let value(ByVal value As Long)
this.value = value
End Property
Public Property Let TUW(ByVal TUW As Double)
this.TUW = TUW
End Property
Public Property Set parent(ByVal parent As Node)
Set this.parent = parent
End Property
' no set for children listBonjour JExcel2fr,
Pardon, je découvre le monde du forum et je ne voulais pas mal faire en postant mon problème sur différents forums (je n'avais pas pensé qu'une même personne pouvait être sur plusieurs forums pour aider les gens).
Je m'en excuse et ne le ferai plus dans le futur.
Merci et bonne journée.
Bonjour saboh12617,
Merci beaucoup pour votre réponse. Je vais regarder tout ça attentivement et ne manquerai pas de revenir vers vous ;)
Merci et bonne journée.