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 :
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.
Code :
Sub TempoColumn()
Dim lastRow As Long
Dim i As Long
Dim j As Long
Dim k As Long
Dim m As Long
Dim currentLevel As Long
Dim hierarchy As String
Dim parentHierarchy As String
Dim totalUnitWeight As Double
Dim parentWeight As Double
Dim childWeight As Double
Dim maxLevel As Long
Dim levels As Range
Dim allChildrenFilled As Boolean
Dim hasNonZeroParent As Boolean
Dim hierarchyColumn As Long
Dim weightColumn As Long
Dim levelColumn As Long
' Trouver la dernière colonne utilisée dans la première ligne
lastColumn = Cells(1, Columns.Count).End(xlToLeft).Column
' Initialiser les variables
levelColumn = 0
hierarchyColumn = 0
weightColumn = 0
' Trouver les colonnes level, weight et hierarchy
For k = 1 To lastColumn
If Cells(1, k).Value = "Level" Then
levelColumn = k
ElseIf Cells(1, k).Value = "Hierarchy" Then
hierarchyColumn = k
ElseIf Cells(1, k).Value = "Total Unit Weight" Then
weightColumn = k
End If
Next k
lastRow = Cells(Rows.Count, levelColumn).End(xlUp).Row
' Initialiser maxVal avec la première valeur de la colonne Level
maxLevel = Cells(2, levelColumn).Value
' Parcourir toutes les lignes de la colonne Level pour trouver la valeur maximale
For m = 3 To lastRow
If Cells(m, levelColumn).Value > maxLevel Then
maxLevel = Cells(m, levelColumn).Value
End If
Next m
' Ajout d'une colonne "Tempo"
Columns(weightColumn + 1).Select
Selection.Insert
Cells(1, weightColumn + 1).Value = "Tempo"
Columns(weightColumn + 1).NumberFormat = "0"
' Loop du Level le plus haut au plus bas
For currentLevel = maxLevel To 1 Step -1
For i = 2 To lastRow
' Process rows with the current level
If Cells(i, 2).Value = currentLevel Then
' Get the hierarchy and weight from the current row
hierarchy = Cells(i, 1).Value
totalUnitWeight = Cells(i, 3).Value
' Règle 1 : Si Total Unit Weight est différent de zéro, alors Tempo est à 1
If totalUnitWeight <> 0 Then
Cells(i, weightColumn + 1).Value = 1
Else
' Règle 2 : vérifie parents et enfants
hasNonZeroParent = False
parentHierarchy = hierarchy
' Vérif si l’un de ses parents à un Total Unit Weight différent de zéro
Do While InStrRev(parentHierarchy, ".") > 0
parentHierarchy = Left(parentHierarchy, InStrRev(parentHierarchy, ".") - 1)
For j = 2 To lastRow
If Cells(j, 1).Value = parentHierarchy Then
If Cells(j, weightColumn).Value <> 0 Then
hasNonZeroParent = True
Exit Do
End If
End If
Next j
If hasNonZeroParent Then Exit Do
Loop
' Vérif si tous ses enfants directs (dont avec un Level ayant une valeur de +1) ont une valeur 1
allChildrenFilled = True
For m = 2 To lastRow
If Left(Cells(m, 1).Value, Len(hierarchy) + 1) = hierarchy & "." And Cells(m, levelColumn).Value = currentLevel + 1 Then
If Cells(m, weightColumn + 1).Value <> 1 Then
allChildrenFilled = False
Exit For
End If
End If
Next m
If hasNonZeroParent Or allChildrenFilled Then
Cells(i, weightColumn + 1).Value = 1
Else
Cells(i, weightColumn + 1).Value = 0
End If
End If
End If
Next i
Next currentLevel
MsgBox "Macro terminée."
End Sub
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.
- 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.
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.
Code :
Sub TempoColumn()
Dim lastRow As Long
Dim i As Long
Dim j As Long
Dim k As Long
Dim m As Long
Dim currentLevel As Long
Dim hierarchy As String
Dim parentHierarchy As String
Dim totalUnitWeight As Double
Dim parentWeight As Double
Dim childWeight As Double
Dim maxLevel As Long
Dim levels As Range
Dim allChildrenFilled As Boolean
Dim hasNonZeroParent As Boolean
Dim hierarchyColumn As Long
Dim weightColumn As Long
Dim levelColumn As Long
' Trouver la dernière colonne utilisée dans la première ligne
lastColumn = Cells(1, Columns.Count).End(xlToLeft).Column
' Initialiser les variables
levelColumn = 0
hierarchyColumn = 0
weightColumn = 0
' Trouver les colonnes level, weight et hierarchy
For k = 1 To lastColumn
If Cells(1, k).Value = "Level" Then
levelColumn = k
ElseIf Cells(1, k).Value = "Hierarchy" Then
hierarchyColumn = k
ElseIf Cells(1, k).Value = "Total Unit Weight" Then
weightColumn = k
End If
Next k
lastRow = Cells(Rows.Count, levelColumn).End(xlUp).Row
' Initialiser maxVal avec la première valeur de la colonne Level
maxLevel = Cells(2, levelColumn).Value
' Parcourir toutes les lignes de la colonne Level pour trouver la valeur maximale
For m = 3 To lastRow
If Cells(m, levelColumn).Value > maxLevel Then
maxLevel = Cells(m, levelColumn).Value
End If
Next m
' Ajout d'une colonne "Tempo"
Columns(weightColumn + 1).Select
Selection.Insert
Cells(1, weightColumn + 1).Value = "Tempo"
Columns(weightColumn + 1).NumberFormat = "0"
' Loop du Level le plus haut au plus bas
For currentLevel = maxLevel To 1 Step -1
For i = 2 To lastRow
' Process rows with the current level
If Cells(i, 2).Value = currentLevel Then
' Get the hierarchy and weight from the current row
hierarchy = Cells(i, 1).Value
totalUnitWeight = Cells(i, 3).Value
' Règle 1 : Si Total Unit Weight est différent de zéro, alors Tempo est à 1
If totalUnitWeight <> 0 Then
Cells(i, weightColumn + 1).Value = 1
Else
' Règle 2 : vérifie parents et enfants
hasNonZeroParent = False
parentHierarchy = hierarchy
' Vérif si l’un de ses parents à un Total Unit Weight différent de zéro
Do While InStrRev(parentHierarchy, ".") > 0
parentHierarchy = Left(parentHierarchy, InStrRev(parentHierarchy, ".") - 1)
For j = 2 To lastRow
If Cells(j, 1).Value = parentHierarchy Then
If Cells(j, weightColumn).Value <> 0 Then
hasNonZeroParent = True
Exit Do
End If
End If
Next j
If hasNonZeroParent Then Exit Do
Loop
' Vérif si tous ses enfants directs (dont avec un Level ayant une valeur de +1) ont une valeur 1
allChildrenFilled = True
For m = 2 To lastRow
If Left(Cells(m, 1).Value, Len(hierarchy) + 1) = hierarchy & "." And Cells(m, levelColumn).Value = currentLevel + 1 Then
If Cells(m, weightColumn + 1).Value <> 1 Then
allChildrenFilled = False
Exit For
End If
End If
Next m
If hasNonZeroParent Or allChildrenFilled Then
Cells(i, weightColumn + 1).Value = 1
Else
Cells(i, weightColumn + 1).Value = 0
End If
End If
End If
Next i
Next currentLevel
MsgBox "Macro terminée."
End Sub