Excel VBA - Le calcul renvoie la somme pour la dernière ligne au lieu de la première ligne

1

J'essaie de mettre en place un calcul qui additionne toutes les valeurs entre "M" et "X" dans chaque ligne. Cependant, lorsque j'exécute le code, il ne me donne que la somme de la dernière ligne de la feuille de calcul, alors qu'il devrait renvoyer la somme de la cinquième ligne de la feuille de calcul.

Le bloc en particulier où j'ai des problèmes d'écriture est le suivant:

For i = 5 To LastRow
  If Not IsEmpty(.Range(.Cells(i, 13), .Cells(i, 24))) Then
Orig2016Total = .Range("M" & i).Value + .Range("N" & i).Value + .Range("O" & i).Value + .Range("P" & i).Value _
+ .Range("Q" & i).Value + .Range("R" & i).Value + .Range("S" & i).Value + .Range("T" & i).Value _
+ .Range("U" & i).Value + .Range("V" & i).Value + .Range("W" & i).Value + .Range("X" & i).Value
  End If
Next I

La ligne .Range("Z" & i).Value = Orig2016Total, qui apparaît en gras dans le bloc de code ci-dessous, devrait renvoyer 780 000 pour la somme de la cinquième ligne, mais renvoie plutôt la somme de 1 144 669 de la dernière ligne.

Est-ce que quelqu'un pourrait m'aider à comprendre pourquoi je reçois la somme de la dernière ligne alors qu'elle devrait afficher la somme de la cinquième rangée? Merci!!

Le code entier est:

    Function ReduceCost_Percentage()

    With Worksheets("Analysis Worksheet")

    Dim i As Long
    Dim LastRow As Long
    LastRow = Range("X" & Rows.Count).End(xlUp).Row

    Dim TodayDate As Date
    TodayDate = Format(Date, "DD/MM/YYYY")

    Dim Orig2016Total As Long
    Dim MonthsWithValues As Long


   For i = 5 To LastRow
      If Not IsEmpty(.Range(.Cells(i, 13), .Cells(i, 24))) Then
        Orig2016Total = .Range("M" & i).Value + .Range("N" & i).Value + .Range("O" & i).Value + .Range("P" & i).Value _
        + .Range("Q" & i).Value + .Range("R" & i).Value + .Range("S" & i).Value + .Range("T" & i).Value _
        + .Range("U" & i).Value + .Range("V" & i).Value + .Range("W" & i).Value + .Range("X" & i).Value
     End If
    Next i


    For i = 5 To LastRow
     If .Range("D" & i).Value > 0 And IsEmpty(.Range("B" & i).Value) _
     And IsEmpty(.Range("C" & i).Value) And Not IsEmpty(.Range("M" & i).Value) _
     And Not IsEmpty(Worksheets("Fixed Cost Test Data").Range("B" & i).Value) _
     And ((TodayDate >= Worksheets("Fixed Cost Test Data").Range("C" & i).Value And Worksheets("Fixed Cost Test Data").Range("C" & i).Value <= #12/31/2015#) Or Worksheets("Fixed Cost Test Data").Range("C" & i).Value <= #12/31/2015#) Then
      .Range("M" & i).Value = ((.Range("M" & i).Value - Worksheets("Fixed Cost Test Data").Range("B" & i).Value) - ((.Range("M" & i).Value - Worksheets("Fixed Cost Test Data").Range("B" & i).Value) * (.Range("D" & i).Value * 0.01))) + Worksheets("Fixed Cost Test Data").Range("B" & i).Value
    ElseIf .Range("D" & i).Value > 0 And IsEmpty(.Range("B" & i).Value) _
    And IsEmpty(.Range("C" & i).Value) And Not IsEmpty(.Range("M" & i).Value) _
    And (IsEmpty(Worksheets("Fixed Cost Test Data").Range("B" & i).Value) Or Worksheets("Fixed Cost Test Data").Range("C" & i).Value > TodayDate Or Worksheets("Fixed Cost Test Data").Range("C" & i).Value > #12/31/2015#) Then
     .Range("M" & i).Value = .Range("M" & i).Value - (.Range("M" & i).Value * (.Range("D" & i).Value * 0.01))
    End If
   Next I

    'The code continues the same for columns "N" through "X" then it picks up again as:

    For i = 5 To LastRow

    .Range("Y" & i).Formula = "=SUM(" & .Range(Cells(i, 13), Cells(i, 24)).Address(False, False) & ")"

    MonthsWithValues = Application.WorksheetFunction.CountIfs(Worksheets("Analysis Worksheet").Range(.Cells(i, 13), .Cells(i, 24)), "<>0", Worksheets("Analysis Worksheet").Range(.Cells(i, 13), .Cells(i, 24)), "<>""")

     If .Range("D" & i).Value > 0 And IsEmpty(.Range("B" & i).Value) And IsEmpty(.Range("C" & i).Value) Then
       If .Range("X" & i).Value > 0 And Not IsEmpty(Worksheets("Fixed Cost Test Data").Range("B" & i).Value) _
       And Worksheets("Fixed Cost Test Data").Range("C" & i).Value <= #11/30/2016# Then
        ***.Range("Z" & i).Value = Orig2016Total***
      ElseIf .Range("X" & i).Value > 0 And Not IsEmpty(Worksheets("Fixed Cost Test Data").Range("B" & i).Value) _
      And Worksheets("Fixed Cost Test Data").Range("C" & i).Value > #11/30/2016# Then
       .Range("Z" & i).Value = (Orig2016Total - (Worksheets("Fixed Cost Test Data").Range("B" & i).Value * (12 - Left(Worksheets("Fixed Cost Test Data").Range("C" & i).Value, 2)))) / MonthsWithValues
      ElseIf .Range("X" & i).Value > 0 And IsEmpty(Worksheets("Fixed Cost Test Data").Range("B" & i).Value) Then
       .Range("Z" & i).Value = Orig2016Total / MonthsWithValues
      ElseIf .Range("X" & i).Value = Worksheets("Fixed Cost Test Data").Range("B" & i).Value And Not IsEmpty(Worksheets("Fixed Cost Test Data").Range("B" & i).Value) _
      And Not IsEmpty(Worksheets("Fixed Cost Test Data").Range("C" & i).Value) Then
       .Range("Z" & i).Value = ((Orig2016Total - (Worksheets("Fixed Cost Test Data").Range("B" & i).Value * (12 - Left(Worksheets("Fixed Cost Test Data").Range("C" & i).Value, 2)))) / MonthsWithValues) + Worksheets("Fixed Cost Test Data").Range("B" & i).Value
     ElseIf (IsEmpty(.Range("X" & i).Value) Or .Range("X" & i).Value = 0) And Not IsEmpty(Worksheets("Fixed Cost Test Data").Range("B" & i).Value) _
     And Not IsEmpty(Worksheets("Fixed Cost Test Data").Range("C" & i).Value) Then
       .Range("Z" & i).Value = (Orig2016Total - (Worksheets("Fixed Cost Test Data").Range("B" & i).Value * (12 - Left(Worksheets("Fixed Cost Test Data").Range("C" & i).Value, 2)))) / MonthsWithValues
     ElseIf (IsEmpty(.Range("X" & i).Value) Or .Range("X" & i).Value = 0) And IsEmpty(Worksheets("Fixed Cost Test Data").Range("B" & i).Value) Then
      .Range("Z" & i).Value = Orig2016Total / MonthsWithValues
     End If
   End If
  Next i


   End With
   End Function
Bruyère
la source

Réponses:

1

Pendant que vous parcourez les lignes 5 ... LastRow dans la première boucle, calculant la somme des cellules avant de modifier leur contenu, vous enregistrez chaque ligne dans la même variable scalaire qui ne peut contenir qu'une seule valeur. Il est écrasé à chaque itération.

Au lieu de cela, créer Orig2016Totalcomme un tableau de taille de LastRowsorte que vous pouvez mettre chaque rowsum pour la ligne ien Orig2016Total(i). Ensuite, utilisez le i-ème élément de tableau dans les boucles suivantes.

utilisateur1016274
la source
Merci @ user1016274! Je ne sais pas exactement comment écrire ce que vous avez mentionné ci-dessus. Cela vous dérangerait-il d’écrire du code comme exemple d’écriture du mien? Merci!!
HeatherD
Je l'ai! Il vient de changer en: Dim Orig2016Total(68) As Longet ensuite For i = 5 To LastRow If Not IsEmpty(.Range(.Cells(i, 13), .Cells(i, 24))) Then Orig2016Total(i) = .Range("M" & i).Value + .Range("N" & i).Value + .Range("O" & i).Value + .Range("P" & i).Value _ + .Range("Q" & i).Value + .Range("R" & i).Value + .Range("S" & i).Value + .Range("T" & i).Value _ + .Range("U" & i).Value + .Range("V" & i).Value + .Range("W" & i).Value + .Range("X" & i).Value End If Next I
HeatherD
Génial! Vous pouvez remplacer 68pour LastRowle rendre universel. Je me demande pourquoi vous ne faites pas la somme au Range(Cells(i, 13), Cells(i, 24))lieu d'énumérer toutes les plages simples.
user1016274
J'ai essayé d'utiliser LastRowcomme vous l'avez mentionné, mais cela ne fonctionnerait pas. Qu'entendez-vous par "somme sur Range (Cells(i, 13), Cells(i, 24))"?
HeatherD
Je pense que cela va trop loin. Le code fonctionne comme il est, bon. Je ne voulais pas te déranger. Il y a toujours un codage "plus ordonné" mais ce n'est pas ce dont il s'agit.
user1016274