Function Cumul(xrg As Range, xColCout, Optional xColQuantite)
Application.Volatile
Dim i&, imax&, tablo, nivMax&, aux, j&, k&
If IsMissing(xColQuantite) Then
' 2 ième paramètre manquant -> on calcule les coûts cumulés sans notion de quantité
' initialisation de cumul par le coût de la ligne de xrg
Cumul = xrg(1, xColCout): i = 2
' on parcourt les lignes suivantes en ajoutant les coûts de chaque ligne
' tant que le niveau est supérieur à celui de xrg
Do While xrg(i, 1) > xrg(1, 1)
Cumul = Cumul + xrg(i, xColCout)
i = i + 1
Loop
' FIN de la 1ière forme
Else
' 2 ième paramètre présent -> on calcule les coûts cumulés avec les quantités
' calcul de imax à partir de la ligne de xrg
' imax est la ligne max du bloc relatif au niveau de xrg
imax = 1 'le bloc commence à la ligne de xrg
Do While xrg(imax + 1, 1) > xrg(1, 1)
' si la ligne suivante a un niveau sup. à celui de xrg, la ligne fait partie du bloc
imax = imax + 1
Loop
' recherche du rang de colonne max entre les colonnes xColCout et xColQuantite
If xColCout > xColQuantite Then i = xColCout Else i = xColQuantite
' déclaration du tablo correspondant au bloc de xrg
' le nombre de lignes est égal à imax
' le nombre de colonnes est égal à i (i = n° de colonne max)
ReDim tablo(1 To imax, 1 To i)
' remplissage de tablo
tablo = xrg.Parent.Range(xrg(1, 1), xrg(imax, i))
' on rajoute une colonne au tablo
ReDim Preserve tablo(1 To imax, 1 To i + 1)
' calcul du niveau max au sein du bloc de xrg (i.e. tablo)
nivMax = xrg(1, 1)
For i = 2 To UBound(tablo)
If xrg(i, 1) > nivMax Then nivMax = xrg(i, 1)
Next i
' on calcule le coût cumulé pour le dernier niveau (égal à nivMAx)
' c'est le coût de la ligne multiplié par la quantité
For i = UBound(tablo) To 1 Step -1
If tablo(i, 1) = nivMax Then tablo(i, UBound(tablo, 2)) = tablo(i, xColCout) * tablo(i, xColQuantite)
Next i
' la dernière ligne du bloc est remplie de la même manière
' quelque soit son niveau
tablo(UBound(tablo), UBound(tablo, 2)) = tablo(UBound(tablo), xColCout) * tablo(UBound(tablo), xColQuantite)
' on va boucler sur les niveaux. Du niveau max -1 au niveau de xrg
' rappel: pour les niveaux max, c'est déjà fait
For j = nivMax - 1 To xrg(1, 1) Step -1
' pour chaque niveau j , on boucle sur le bloc de xrg (moins la dernière ligne)
For i = 1 To imax - 1
If tablo(i, 1) = j Then
' si la ligne en cours est de niveau j
' on initialise le coût aux avec le coût de la ligne
aux = tablo(i, xColCout)
' on examine les lignes suivantes.
' tant que la ligne a un niveau supérieur au niveau j en cours
' si le niveau est égal à j+1, alors on ajoute à aux le coût de la ligne
' autrement dit: tant que le niveau est sup. au niveau en cours j et
' si ce niveau est le niveau immédiatement supérieur à j, alors on prend en
' compte le coût (coût précédemment calculé soit par la boucle sur les niveaux max,
' soit par une précédente boucle de j)
k = i
Do While tablo(k + 1, 1) > j
If tablo(k + 1, 1) = j + 1 Then aux = aux + tablo(k + 1, UBound(tablo, 2))
k = k + 1
' si k est sup à la dernière ligne du bloc, on quitte la boucle DO
If k = imax Then Exit Do
Loop
' le coût cumulé est donc le produit de aux par la quantité de la ligne en cours i
tablo(i, UBound(tablo, 2)) = aux * tablo(i, xColQuantite)
End If
Next i ' passage à la ligen suivante
Next j ' passage au niveau suivant
'le cumul correspondant à xrg est celui de la ligne 1 de table
Cumul = tablo(1, UBound(tablo, 2))
' FIN de la 2ième forme
End If
End Function