Se connecter avec
S'enregistrer | Connectez-vous

Insertion ligne en dessous du dernier élément de la condition

Dernière réponse : dans Programmation

Salut tout le monde,
J’aurai besoin d’une aide. J’ai un tableau avec une colonne H où se trouvent des montants. J’ai fait une macro qui fait la somme de ces montants s’ils sont < à 10 000, s’ils sont entre 4 000 et 10 000 et s’ils sont < à 4 000.
Et à chaque fois il faut insérer une ligne en dessous du dernier montant qui est < à 10 000, (pareil pour le dernier montant compris entre 4 000 et 10 000 et celui < à 4 000). Et c’est dans cette ligne insérée où il faut mettre la somme dans chaque cas.
Ma macro marche sauf pour ce qui est du dernier cas. Il me met la somme à 65536 ième ligne ; ce n’est pas terrible. A votre avis qu’est ce qui cloche ?
Au début je l’ai adapté à 390 lignes et pas de soucis. Mais mon nombre de lignes change toutes les semaines, c’est pour cela que j’ai mis de for i de 1 à 65536.

  1. Sub TrierEtSommeSI()
  2.  
  3. ' trier le tableau de données
  4. Sheets("Général").Select
  5. Range("A1:L390").Select
  6. Selection.Sort Key1:=Range("H2"), Order1:=xlDescending, Header:=xlGuess, _
  7. OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
  8. DataOption1:=xlSortNormal
  9. ' boucle
  10. For i = 2 To 65536
  11. If Range("H" & i).Value >= 10000 Then
  12. SommeSup = SommeSup + Range("H" & i).Value
  13. DernierSup = i
  14.  
  15. ElseIf Range("H" & i).Value >= 4000 And Range("H" & i).Value < 10000 Then
  16. SommeInf = SommeInf + Range("H" & i).Value
  17. DernierInf = i
  18. Else
  19. SommeReste = SommeReste + Range("H" & i).Value
  20. DernierReste = i
  21. End If
  22. Next i
  23.  
  24. Range("H" & DernierSup + 1).EntireRow.Insert
  25. Range("A" & DernierSup + 1).Value = "Somme des éléments >= 10000"
  26. Range("H" & DernierSup + 1).Value = SommeSup
  27.  
  28. Range("H" & DernierInf + 2).EntireRow.Insert
  29. Range("A" & DernierInf + 2).Value = "Somme des éléments >=4000 et < 10000"
  30. Range("H" & DernierInf + 2).Value = SommeInf
  31.  
  32. Range("H" & DernierReste + 3).EntireRow.Insert
  33. Range("A" & DernierReste + 3).Value = "Somme des éléments < 4000"
  34. Range("H" & DernierReste + 3).Value = SommeReste
  35.  
  36. End Sub

Merci d’avance pour votre aide !!
Lassé par la pub ? Créez un compte

Meilleure solution

Expert Programmation

Salut,

Rholala.... M'enfin, pourquoi ligne 5, sélectionnes-tu une zone pour ensuite appliquer le tri sur la sélection en cours. Abrège ton code, et applique le tri sur la zone directement. :spamafote: 

Grâce à l'aide en ligne, découvre la méthode Cells(). Elle est plus agréable à utiliser que Range() dans ton cas.

En fait, il ne faut pas que tu boucles sur autant de lignes que cela.
Pour déterminer la dernière ligne, inspire-toi de ce topic : http://www.presence-pc.com/forum/ppc/Programmation/tuto...

zeb a dit :
Salut,

Rholala.... M'enfin, pourquoi ligne 5, sélectionnes-tu une zone pour ensuite appliquer le tri sur la sélection en cours. Abrège ton code, et applique le tri sur la zone directement. :spamafote: 

Grâce à l'aide en ligne, découvre la méthode Cells(). Elle est plus agréable à utiliser que Range() dans ton cas.

En fait, il ne faut pas que tu boucles sur autant de lignes que cela.
Pour déterminer la dernière ligne, inspire-toi de ce topic : http://www.presence-pc.com/forum/ppc/Programmation/tuto...



salut zeb , voila ce que j'ai réussi à faire gra à ton topic. ça fonctionne.
  1. Sub TrierEtSommeSI()
  2.  
  3.  
  4.  
  5. Worksheets("Feuil1").Range("A1").Sort Key1:=Worksheets("Feuil1").Columns("H"), order1:=xlDescending, Header:=xlGuess
  6.  
  7.  
  8.  
  9. ' boucle
  10.  
  11. For i = 2 To 10000
  12.  
  13.  
  14.  
  15. If Range("H" & i).Value >= 10000 Then
  16.  
  17. SommeSup = SommeSup + Range("H" & i).Value
  18.  
  19. derniersup = i
  20.  
  21.  
  22.  
  23. ElseIf Range("H" & i).Value >= 4000 And Range("H" & i).Value < 10000 Then
  24.  
  25. SommeInf = SommeInf + Range("H" & i).Value
  26.  
  27. dernierinf = i
  28.  
  29. Else
  30.  
  31. SommeReste = SommeReste + Range("H" & i).Value
  32.  
  33. End If
  34.  
  35. Next
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43. Range("H" & derniersup + 1).EntireRow.Insert
  44.  
  45. Range("G" & derniersup + 1).Value = "Total des retards >= 10 000"
  46.  
  47. Range("G" & derniersup + 1).Font.Bold = True
  48.  
  49. Range("G" & derniersup + 1).HorizontalAlignment = xlRight
  50.  
  51. Range("H" & derniersup + 1).Value = SommeSup
  52.  
  53. Range("H" & derniersup + 1).Font.Bold = True
  54.  
  55.  
  56.  
  57. Range("H" & dernierinf + 2).EntireRow.Insert
  58.  
  59. Range("G" & dernierinf + 2).Value = "Total des retards entre 4 000 et 10 000"
  60.  
  61. Range("G" & dernierinf + 2).Font.Bold = True
  62.  
  63. Range("G" & dernierinf + 2).HorizontalAlignment = xlRight
  64.  
  65. Range("H" & dernierinf + 2).Value = SommeInf
  66.  
  67. Range("H" & dernierinf + 2).Font.Bold = True
  68.  
  69.  
  70.  
  71. Cells(Rows.Count, 7).End(xlUp).Offset(1).Select
  72.  
  73. Cells(Rows.Count, 7).End(xlUp).Offset(1).Value = "Total des retards < 4000"
  74.  
  75. Cells(Rows.Count, 7).End(xlUp).Font.Bold = True
  76.  
  77. Cells(Rows.Count, 7).End(xlUp).Offset(1).HorizontalAlignment = xlRight
  78.  
  79. Cells(Rows.Count, 8).End(xlUp).Offset(1).Value = SommeReste
  80.  
  81. Cells(Rows.Count, 8).End(xlUp).Font.Bold = True
  82.  
  83.  
  84.  
  85.  
  86.  
  87. End Sub
Expert Programmation

pffffffffffff ! Eh ben...

A la ligne 11, remplace le grand nombre par le numéro de la dernière ligne.
Ligne 5, tu précises la feuille. C'est bien. A toutes les autres lignes, tu ne le fait pas. C'est mal.
Ligne 71 et suivantes, tu utilises Cells(). C'est bien. Partout ailleurs, tu utilises Range(), c'est idiot.
Ligne 71, tu sélectionnes une ligne. Pour quoi faire ?
Ligne 71 et suivantes, tu fais beaucoup de calculs inutiles !
Lignes 75 et 81, t'es sûr que tu es sur la bonne ligne ?

---------------------

  1. // Premier jet
  2. Dim ws As Worksheets
  3. Dim cel As Range
  4. Dim SommeSup As Double
  5. Dim SommeReste As Double
  6. Dim derniersup As Long
  7. Dim dernierinf As Long
  8.  
  9. Set ws = Worksheets("Feuil1" )
  10.  
  11. ws.Range("A1" ).Sort Key1:=ws.Columns("H"), order1:=xlDescending, Header:=xlGuess
  12.  
  13. For i = 2 To ws.Cells(Rows.Count, 8).End(xlUp).Row
  14. If Cells(i, 8).Value >= 10000 Then
  15. SommeSup = SommeSup + Cells(i, 8).Value
  16. derniersup = i
  17. ElseIf Cells(i, 8).Value >= 4000 And Cells(i, 8).Value < 10000 Then
  18. SommeInf = SommeInf + Cells(i, 8).Value
  19. dernierinf = i
  20. Else
  21. SommeReste = SommeReste + Cells(i, 8).Value
  22. End If
  23. Next
  24.  
  25. set cel = Cells(derniersup + 1, 7)
  26. cel.EntireRow.Insert
  27. cel.Value = "Total des retards >= 10 000"
  28. cel.Font.Bold = True
  29. cel.HorizontalAlignment = xlRight
  30. Set cel = cel.Offset(1)
  31. cel.Value = SommeSup
  32. cel.Font.Bold = True
  33.  
  34. set cel = Cells(derniersup + 1, 7)
  35. cel.EntireRow.Insert
  36. cel.Value = "Total des retards entre 4 000 et 10 000"
  37. cel.Font.Bold = True
  38. cel.HorizontalAlignment = xlRight
  39. Set cel = cel.Offset(1)
  40. cel.Value = SommeInf
  41. cel.Font.Bold = True
  42.  
  43. Set cel = Cells(Rows.Count, 7).End(xlUp).Offset(1)
  44. cel.Value = "Total des retards < 4000"
  45. cel.Font.Bold = True
  46. cel.HorizontalAlignment = xlRight
  47. Set cel = cel.Offset(1)
  48. cel.Value = SommeReste
  49. cel.Font.Bold = True

Bon. Y'a un peu moins de calcul. Mais on peut pousser le vice plus loin : Les trois derniers blocs sont "presque" identiques. Et on se traîne des indices alors qu'on peut utiliser directement les objets.

  1. Sub NewLine(line As Range, title As String, value As Double)
  2. line.EntireRow.Insert
  3. With line.Columns("G")
  4. .Value = title
  5. .HorizontalAlignment = xlRight
  6. .Font.Bold = True
  7. End With
  8. With line.Columns("H")
  9. .Value = value
  10. .Font.Bold = True
  11. End With
  12. End Sub
  1. Sub TrierEtSommeSI()// Nouveau code
  2. Dim ws As Worksheets
  3. Dim cel As Range
  4. Dim SommeSup As Double
  5. Dim SommeInf As Double
  6. Dim SommeRst As Double
  7. Dim LineSup As Range
  8. Dim LineInf As Range
  9. Dim LineRst As Range
  10.  
  11. Set ws = Worksheets("Feuil1")
  12. ws.Range("A1" ).Sort Key1:=ws.Columns("H"), order1:=xlDescending, Header:=xlYes
  13.  
  14. Set LineRst = ws.Cells(ws.Rows.Count, 8).End(xlUp).EntireRow
  15. For Each cel In Range(ws.Rows(2), LineRst).Columns("H")
  16. Select Case cel.Value
  17. Case Is >= 10000
  18. SommeSup = SommeSup + cel.Value
  19. LineSup = cel.EntireRow
  20. Case Is >= 4000
  21. SommeInf = SommeInf + cel.Value
  22. LineInf = cel.EntireRow
  23. Case Else
  24. SommeRst = SommeRst + cel.Value
  25. End Select
  26. Next
  27.  
  28. NewLine LineSup, "Total des retards supérieurs à 10 000", SommeSup
  29. NewLine LineInf, "Total des retards entre 4 000 et 10 000", SommeInf
  30. NewLine LineRst, "Total des retards inférieurs à 10 000", SommeRst
  31. End Sub


Je conçois que ce soit plus difficile à écrire. Mais j'estime que c'est très facile à lire.
N'est-ce pas limpide ?

re,

j'ai essayé de faire marcher le"Nouveau code" mais j'ai un message d'erreur : "Incompatibilité de type" au niveau de la ligne 17. j'ai mis un "#" apres les "10000", mais ça ne marche toujours pas. Je suis sous excel 2003.

aussi j'aurai une deuxième question.

comment puis je faire pour que les sous totaux tiennent compte des suppressions de lignes.
je m'explique : une fois mon programme exécuté et que mon tableau tout fini et tout beau :D .
je serais amené à supprimer des lignes.
je me demandais comment faire pour que les sous totaux en tiennent compte?
Merci
Expert Programmation

Pour ton incompatibilité de type, je suppose que tu essaies d'additionner, ligne 18 en fait, des choux et des carottes. Vérifie si tu n'as pas du texte ou des choses comme ça dans tes lignes :
  1. For Each cel In Range(ws.Rows(2), LineRst).Columns("H" )
  2. If Not IsNumeric(cel.Value) Then
  3. MsgBox "Eh, mec, la cellule " & cel.Address(False, False) & " ne contient pas un nombre"
  4. Else
  5. Select Case cel.Value
  6. Case Is >= 10000
  7. SommeSup = SommeSup + cel.Value
  8. LineSup = cel.EntireRow
  9. Case Is >= 4000
  10. SommeInf = SommeInf + cel.Value
  11. LineInf = cel.EntireRow
  12. Case Else
  13. SommeRst = SommeRst + cel.Value
  14. End Select
  15. Endif
  16. Next


Au lieu de faire des additions, laisse Excel les faire lui même.
Tu connais la fonction =SOMME() d'Excel ? Ben tu peux mettre cette formule dans ta cellule. Ça tombe bien tu as tous les éléments.

(Aide-toi de l'enregistreur de macro pour découvrir comment mettre une formule dans une cellule. Publie ici ton code, je te montrerai comment l'arranger ;)  )

Non ya pas de texte, c'est que du chiffre. j'ai même remis le format de ces celules en nombre. Et pourtant ton message apparait bien. j'avoue là je ne comprends pas.
Mais Sinon, voilà ce que l'enregistreur de macro me donne pour ce qui est de mon 2e probleme
  1. Sub SousTot()
  2. ActiveCell.FormulaR1C1 = "=SUM(R[-44]C:R[-1]C)"
  3. Selection.AutoFill Destination:=Range("H46:K46"), Type:=xlFillDefault
  4. Range("H46:K46").Select
  5. End Sub


Merci de ton aide
Expert Programmation

Citation :
Non ya pas de texte, c'est que du chiffre.
Ben par expérience, je peux te dire que c'est bien du texte. Un O pour un zéro, un espace au début, à la fin au milieu... Eh, tu as l'adresse de la cellule, débrouille-toi !

Or donc tu as écris =SOMME() et l'enregistreur a enregistré =SUM(). C'est tout ce que je voulais te faire remarquer. Donc tu supprimes des additions, et tu ajoutes ta formule.

  1. Sub NewLine(ByRef line_1 As Range, ByRef line_2 As Range, title As String)
  2. Dim sum_address As String
  3.  
  4. ' // Juste histoire d'être sûr
  5. set line_1 = line_1.EntireRow
  6. set line_2 = line_2.EntireRow
  7.  
  8. Set sum_address = line_1.Worksheet.Range(line_1, line_2).Columns("H").Address
  9.  
  10. line_2.EntireRow.Insert
  11. With line_2.Columns("G")
  12. .Value = title
  13. .HorizontalAlignment = xlRight
  14. .Font.Bold = True
  15. End With
  16. With line_2.Columns("H")
  17. .Formula = "=SUM(" & sum_address & ")"
  18. .Font.Bold = True
  19. End With
  20. End Sub
  1. Sub TrierEtSommeSI()// Nouveau code
  2. Dim ws As Worksheets
  3. Dim cel As Range
  4. Dim SommeSup As Double
  5. Dim SommeInf As Double
  6. Dim SommeRst As Double
  7. Dim LineSup As Range
  8. Dim LineInf As Range
  9. Dim LineRst As Range
  10.  
  11. Set ws = Worksheets("Feuil1")
  12. ws.Range("A1" ).Sort Key1:=ws.Columns("H"), order1:=xlDescending, Header:=xlYes
  13.  
  14. Set LineRst = ws.Cells(ws.Rows.Count, 8).End(xlUp).EntireRow
  15. For Each cel In Range(ws.Rows(2), LineRst).Columns("H")
  16. If Not IsNumeric(cel.Value) Then
  17. MsgBox "Puisque je te dis que la cellule " & cel.Address(False, False) & " ne contient pas un nombre !"
  18. Else
  19. Select Case cel.Value
  20. Case Is >= 10000 : LineSup = cel.EntireRow
  21. Case Is >= 4000 : LineInf = cel.EntireRow
  22. End Select
  23. End If
  24. Next
  25.  
  26. NewLine ws.Rows(2), LineSup, "Total des retards supérieurs à 10 000"
  27. NewLine LineSup, LineInf, "Total des retards entre 4 000 et 10 000"
  28. NewLine LineInf, LineRst, "Total des retards inférieurs à 10 000"
  29. End Sub


Il y a peut-être deux/trois ajustements à faire ;) 

salut Zeb,
je vais te décevoir mais j'ai laché ton code il est hyper compliqué pour moi.
par contre pour ce qui est de mon 2é problème (suppression de ligne et modification de la formule). j'ai essayé d'adapter ce que tu m'avais filé.
et ça marche mais juste pour la dernière ligne. en fait il me fait la somme de la cellule avant la ligne nouvellement insérée.
qu'est ce que je dois mettre pour qu'il prennent en compte, dans le total, tous les nombres supérieurs à 10000? :( 

Merci pour ta réponse

  1. Sub TrierEtSommeSItest()
  2.  
  3. Worksheets("Feuil1").Range("A1").Sort Key1:=Worksheets("Feuil1").Columns("H"), order1:=xlDescending, Header:=xlGuess
  4.  
  5. For i = 2 To 10000
  6. If Range("H" & i).value >= 10000 Then
  7. SommeSup = SommeSup + Range("H" & i).value
  8. derniersup = i
  9. vadresse = Worksheets(1).Range("H" & i).Address
  10. ElseIf Range("H" & i).value >= 4000 And Range("H" & i).value < 10000 Then
  11. SommeInf = SommeInf + Range("H" & i).value
  12. dernierinf = i
  13. Else
  14. SommeReste = SommeReste + Range("H" & i).value
  15. End If
  16. Next
  17.  
  18. Range("H" & derniersup + 1).EntireRow.Insert
  19. Range("G" & derniersup + 1).value = "Total des retards >= 10 000"
  20. Range("G" & derniersup + 1).Font.Bold = True
  21. Range("G" & derniersup + 1).HorizontalAlignment = xlRight
  22. Range("H" & derniersup + 1).value = SommeSup
  23. Range("H" & derniersup + 1).Formula = "=SUM(" & vadresse & " )"
  24. Range("H" & derniersup + 1).Font.Bold = True
  25.  
  26. End sub

Pour tes lignes est-ce que après ta dernière lignes tu peux avoir d'autres ligne de remplies (en gros avoir une ligne vide) ? Si ce n'est pas le cas tu peux faire un If sur une cellule de ta ligne pur savoir si elle est vide et si c'est le cas sortir du traitement :

  1. For i = 1 To 10
  2.  
  3. If feuil1.cells(i, 1) <> "" Then
  4.  
  5. ...
  6.  
  7. Else
  8.  
  9. Exit Sub
  10.  
  11. End If
  12.  
  13. Next
Lassé par la pub ? Créez un compte