VBA:Somme d'un Rng de cells jusqu'à next vide

Fermé
titigrosminet - 21 janv. 2010 à 15:53
moiced59 Messages postés 1145 Date d'inscription samedi 15 novembre 2008 Statut Membre Dernière intervention 18 août 2014 - 23 janv. 2010 à 08:41
Bonjour tout le monde,

Je vient de débuter avec VBA (1semaine environ) et je tombe sur un petit pb :


J'ai la tête prise sur une problématique depuis deux jours, que je n'arrive pas à résoudre, à force de chercher je pars dans tout les sens et je n'arrive du coup plus à me concentrer.

Voici mon pb :

Sur ma feuille j'ai des valeurs (tiré d'un import, ttes les valeurs sont dja mise en forme).

A chaque fois qu'une ligne de ma colonne (on va dire "F") est vide il me faudrait une somme de toutes les lignes précédentes sur "F", mettons F1 est non vide, F2 est non vide, F3 est vide, F4 est non vide ,F5 est non vide, F6 est vide.

Le vrai pb vient du fait qu'en réalité il ne me faut pas une somme de toutes les lignes qui précédent mais uniquement celles qui n'ont pas déjà fait l'objet d'une somme. Donc, si F3 est vide (faire un test ?) sommer toutes les valeurs précédentes (cad F1+F2). Si F6 est vide sommer toutes les valeurs précédentes jusqu'à F4 (puisque F3 fait déjà la somme des éléments précédents). ET ce jusqu'à F"x".

J'ai pensé un "Range i" pour chaque F non vide et sommer, parcontre ne voit pas trop comment l'écrire.

Aussi pensé allouer une couleur à chaque fois qu'une somme est calculé et de demandé d'arreter le calcul jusquà la couleur, mais ma maîtrise du vba est limité.

J'en suis à peu près à savoir déterminer la dernière ligne, la rendre active et essayer de remonter jusqu'à la prochaine ligne vide (avec un while not is empty). Par contre ça ne me permets pas de selectionner les non vides en question.

Bref je suis perdu ....

voici à quoi ressemble mon code pour le moment :
__________________________________________________________________________________________[...]
For Each MaCellule In Range("W2:W" & NbLignes)
MaFeuille.Range("Y2:Y" & NbLignes).Value = MaCellule.Value

Set NouvFeuil = Sheets.Add(, After:=Worksheets(Worksheets.Count))

On Error Resume Next
NouvFeuil.Name = MaCellule.Value

LDEC.AdvancedFilter Action:=xlFilterCopy, _
CriteriaRange:=Sheets("Extraction"X"").Range("Y1:Y2"), _
CopyToRange:=NouvFeuil.Range("A1"), _
Unique:=False

Next

MaFeuil.Select
MaFeuille.Columns("W:Y").Delete

Application.DisplayAlerts = False
'supprime tous les popups (ex : demande de confirmation de suppression de pages)

Sheets("Feuil2").Delete
Sheets("Feuil3").Delete
Sheets("Feuil4").Delete


Application.DisplayAlerts = True
'réactive tous les popups (ex : demande de confirmation de suppression de pages

'-----------------------------------------
'Deuxième partie du code
'Extrait la liste des catégories et la copie sur la colonne "W"

[...]

'Début de la boucle

For Each MaCellule In Range("W2:W" & NbLignes)
MaFeuille.Range("Y2:Y" & NbLignes).Value = MaCellule.Value


LDEC.AdvancedFilter Action:=xlFilterCopy, _
CriteriaRange:=Sheets("Extraction"X"").Range("Y1:Y2"), _
CopyToRange:=Sheets(MaCellule.Value).Range("A1000"), _
Unique:=False
'supprime les lignes vides
Sheets(MaCellule.Value).Range("A5:A1000").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
'mets en forme les colonnes de chaque feuille
Sheets(MaCellule.Value).Range("A:O").EntireColumn.AutoFit
Sheets(MaCellule.Value).Columns("C").Delete
Sheets(MaCellule.Value).Columns("E").Delete


Dim LastRow As Long
Dim Rng As Range
i = 0
With ActiveSheet
Set Rng = .Range(Cells(LastRow - i, 12), .Cells(.Rows.Count, 12).End(xlUp))

JE SUIS PERDU ICI


Loop






Next
'mets en forme les colonnes de 1ère feuille extraite de "X"
MaFeuil.Select
MaFeuille.Columns("W:Y").Delete
MaFeuille.Range("A:O").EntireColumn.AutoFit

End Sub

OU ICI UN AUTRE ESSAIE MAIS BON JE L AI MIS DE COTE
'essaie de somme
'Dim Rng As Range
'i = 0
'With ActiveSheet
'Set Rng = .Range(Cells(lastrow - i, 12), .Cells(.Rows.Count, "A").End(xlUp))
'EndWith
'Do While Not (IsEmpty(ActiveSheet.Cells(ii, 6)))
'SumRng = Application.WorksheetFunction.Sum(Rng)

17 réponses

Gord21 Messages postés 918 Date d'inscription samedi 21 novembre 2009 Statut Membre Dernière intervention 20 mars 2013 289
21 janv. 2010 à 23:22
Bonsoir,

Je n'ai pas regardé ton code en détail, il y a des actions qui ne correspondent pas au problème évoqué dans ton sujet.
Si je garde ton exemple de la colonne F, le code devrait ressembler à quelque chose comme ça :

Sub Somme_liste()

Dim ligne_debut As Long
Dim ligne_fin As Long

ligne_debut = 1
ligne_fin = Range("F" & ligne_debut).End(xlDown).Row

While ligne_debut < Rows.Count
If ligne_fin < Rows.Count Then
Range("F" & ligne_fin + 1).Value = WorksheetFunction.Sum(Range("F" & ligne_debut & ":F" & ligne_fin))
ligne_debut = ligne_fin + 2
ligne_fin = Range("F" & ligne_debut).End(xlDown).Row
Else
ligne_debut = ligne_fin
End If
Wend

End Sub


Par contre, dans ce cas, la somme est fixe : si tu changes les valeurs, la somme n'est pas recalculée. Si tu veux qu'elle se recalcule, il faut utiliser la propriété Formula en lieu et place de Value.
1
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 310
22 janv. 2010 à 12:55
Bonjour,

Excusez l'incruste...

Ci dessous proposition tenant de plusieurs cellules vides d'affilée
Dim derlig As Long, lig As Long, lig_0 As Long
'nettoie la zone de restitution
Range("G1:G10000").ClearContents
'initialisations
derlig = Range("F65536").End(xlUp).Row
lig = 1
Application.ScreenUpdating = False

While lig <= derlig
    lig_0 = lig
    lig = Columns(6).Find("", Cells(lig_0, 6), xlValues).Row
    If Application.Sum(Range(Cells(lig_0, 6), Cells(lig, 6))) <> 0 Then 'gestion avec plusieurs lignes vides
        Cells(lig - 1, 7) = Application.Sum(Range(Cells(lig_0, 6), Cells(lig, 6))) 'restitution en colonne G (G--->7)
    Else
        lig = lig + 1
    End If
Wend


ci joint démo
https://www.cjoint.com/?bwm0qTmY7E

pour avoir une liste dynamique, comme le suggère Gord21 (bonjour), tu pourrais déclencher la macro par une macro événementielle: si ca t'intéresse et que tu connais pas, tu fais signe...
1
titigrominet
21 janv. 2010 à 22:46
up !
0
titgrosminet
21 janv. 2010 à 23:39
Merci Gord 21 de m'avoir répondu,

En effet le code copié sert à faire pas mail d'instructions.

En fait j'ai copié tout ça c'était plus dans le but de montrer que le code (ici Somme_liste) allait se trouver dans une boucle qui copie colle des données sur pas mal de feuilles Ainsi sur feuille page la somme sera réalisée.

J'étais en réalité perdu entre le "Dim last row" et le loop. qui seront remplacé par le code ci dessus.

La je n'ai pas accès à Windows, je tenterai demain matin. Mais déjà à le lire ça à l'air super !!!

Encore merci !
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
titigrosminet
22 janv. 2010 à 11:30
Rebonjour,

J'ai essayé d'adapter un peu le code à ma feuille, je déclare deux lignes de fin :

- une pour vérifier que c'est bien la ligne que je recherche ligne_finF
- une pour mettre la somme qui nous intéresse ligne_finM qui correspond à la même cellule que ligne_finF mais décalé de 8 cellules. J'ai donc essayé de déclaré ligne_finM comme étant un offset de ligne_finF. sauf que le débogeur n'aime pas trop çà :)



le code :


Dim ligne_debut As Long
Dim ligne_finF As Long
Dim ligne_finM As Long

ligne_debut = 3
ligne_finF = Range("F" & ligne_debut).End(xlDown).Row
ligne_finM = ligne_finF.Offset(O, 8)


While ligne_debut < Rows.Count
If ligne_finF < Rows.Count Then
Range("M" & ligne_finM + 1).Value = WorksheetFunction.Sum(Range("M" & ligne_debut & ":M" & ligne_finM))
ligne_debut = ligne_finF + 2
ligne_finF = Range("F" & ligne_debut).End(xlDown).Row
ligne_finM = ligne_finF.Offset(O, 8)
Else
ligne_debut = ligne_finF
End If
Wend

ps : à quoi sert le ":" juste avant M dans le" &":M""



:)
0
titigrosminet
22 janv. 2010 à 12:05
J'ai déclaré une nouvelle variable Range pour essayé de contourner le pb, le déboggeur ne dit plus rien, par contre aucune trace des sommes.

:


Dim ligne_debut As Long
Dim ligne_finF As Long
Dim ligne_finM As Long
Dim ligne_finF1 As Range

ligne_debut = 3
ligne_finF = Sheets(MaCellule.Value).Range("F" & ligne_debut).End(xlDown).Row
ligne_finF1 = Sheets(MaCellule.Value).Range("F" & ligne_debut).End(xlDown).Row
ligne_finM = ligne_finF1.Offset(O, 10)


While ligne_debut < Rows.Count
If ligne_finF < Rows.Count Then
Sheets(MaCellule.Value).Range("M" & ligne_finM + 1).Value = WorksheetFunction.Sum(Range("M" & ligne_debut & ":M" & ligne_finM))
ligne_debut = ligne_finF + 2
ligne_finF = Sheets(MaCellule.Value).Range("F" & ligne_debut).End(xlDown).Row
ligne_finF1 = Sheets(MaCellule.Value).Range("F" & ligne_debut).End(xlDown).Row
ligne_finM = ligne_finF1.Offset(O, 10)
Else
ligne_debut = ligne_finF
End If
Wend

Sheets(MaCellule.Value).Range("A:O").EntireColumn.AutoFit
Next
0
titigrosminet
22 janv. 2010 à 13:41
Bonjour Gord21,

Merci pour l'aide,

j'ai dl le fichier .xls, effectivement la requête réalisée est semblable à celle dont j'ai besoin.

je vais essayer de plancher sur les deux codes pour essayer de les adapter à mon classeur.

Je viens de me rendre compte d'une chose, cellule vide en "F" n'est pas tjrs la dernière ligne à prendre en compte pour le calcul de ma somme, parfois il reste une cellule vide, puis un autre montant à intégrer dans ma somme.

Je pense que je vais devoir contourner en créant une règle, genre a chaque fois que telle condition est remplie, sauter une vraie ligne, pour ensuite faire tourner le code de la somme derrière.

Ainsi le test se fera à partir d'une ligne vide et non plus à partir d'une cellule vide dans "F".

Merci à vous pour votre aide !!

ps : dois-je mettre le sujet en résolu ?
0
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 310
22 janv. 2010 à 13:45
Excuse moi de t'avoir dérangé, mais c'est promis ca ne se reproduira plus
0
titigrosminet
22 janv. 2010 à 14:52
""Excuse moi de t'avoir dérangé, mais c'est promis ca ne se reproduira plus "" ?

Je ne suis pas sûr de comprendre.

Au fait dans mon message précédent je disait bonjour Gord21, je voulais dire bonjour michel_m. (et donc merci pour le fichier joint).

Et personne ne me dérange, au contraire l'aide apportée est plus que précieuse, par contre de mon coté je suis conscient que ce n'est pas top de trop solliciter de l'aide lorsque l'on à pas suffisament cherché de réponses.

Vous avez répondu à la question que j'ai posée, cad de savoir faire une somme arrivé à une cellule vide, je n'abuserai pas au point de vous demander d'écrire tout mon code :)


C'est la raison pour laquelle je pensais (et pense tjrs, je remercie Descartes au passage :) mettre le sujet en résolu.

Vous en pensez quoi ?
0
Gord21 Messages postés 918 Date d'inscription samedi 21 novembre 2009 Statut Membre Dernière intervention 20 mars 2013 289
22 janv. 2010 à 21:13
Bonsoir titigrosminet,

Juste pour répondre à ton post 4, en fait, si tu veux faire la somme des valeurs de F1 à F4, il faudrait écrire :
WorksheetFunction.Sum(Range("F1:F4")) ce qui devient si tu veux mettre des variables :
WorksheetFunction.Sum(Range("F" & indice_premiere_ligne & ":F" & indice_derniere_ligne)).

Ton bug vient probablement de ligne_finM = ligne_finF.Offset(O, 8) qui ne veut rien dire. Si tu veux aller 8 lignes plus loin, tu dois écrire ligne_finM = ligne_finF+8 mais si tu veux aller 8 colonnes plus loin, alors ligne_finM = ligne_finF.
De plus, tu n'a pas de résultat car tu parles dans l'énoncé de faire la somme sur la colonne F alors que dans ton adaptation, tu n'as que des M.

PS : je pense que le Excuse moi de t'avoir dérangé, mais c'est promis ca ne se reproduira plus de michel_m que je salue vient bien de ton erreur d'en-tête.

Pour le statut Résolu, tu es le mieux placé pour dire si tu as encore des question ou non :-)
0
titgrosminet
22 janv. 2010 à 22:34
Bonsoir Gord21,

Merci pour ta réponse.

Je veut effectivement aller 8 colonnes plus loin. Par contre je ne suis pas sur d'avoir compris.

Pour aller 8 colonnes plus loin je dois juste écrire : ligne_finM = ligne_finF.

Ou dois-je ajouter derrière 8 ?

Je devais effectivement effectuer une somme sur des suites continues de cellules en M, cependant, pour déterminer la fin d'une suite j'utilise la colonne M. Effectivement mon premier exemple ne reflète pas cela.

Merci concernant de m'avoir éclairé sur le ":M". Maintenant je sais comment faire une somme sur un range variable.
0
Gord21 Messages postés 918 Date d'inscription samedi 21 novembre 2009 Statut Membre Dernière intervention 20 mars 2013 289
22 janv. 2010 à 22:50
Bonsoir,
Oui, pour aller 8 colonnes plus loin, ligne_finM = ligne_finF (c'est sur la même ligne) mais ça ne sert peut-être à rien de déclarer deux variables si elles ont constamment la même valeur.
Donc pour aller 8 colonne plus loin, tu aura :
Range("U" & ligne).Value = ... : U est à 8 colonnes de M
0
titgrosminet
22 janv. 2010 à 22:58
ok c nickel, j'ai compris ! :=)

Ce site est vraiment génial. Du coup je me suis inscrit, mon nvo pseudo est "Jabba the Hutt".


Bonne soirée !
0
moiced59 Messages postés 1145 Date d'inscription samedi 15 novembre 2008 Statut Membre Dernière intervention 18 août 2014 60
22 janv. 2010 à 23:08
slt
Pourquoi ne pas demarrer de la fin et faire une somme en remontant jusqu'a la 1ere cellule vide?
0
Jabba the Hutt Messages postés 32 Date d'inscription vendredi 22 janvier 2010 Statut Membre Dernière intervention 2 août 2010
22 janv. 2010 à 23:13
slt,

je pensais faire ça au début, mais le code écrit par Gord21, inclus une boucle. Dans le code on sort de la boucle lorsque l'on arrive à la dernière ligne en F qui détient une information.


Moi ça me convient. :)
0
moiced59 Messages postés 1145 Date d'inscription samedi 15 novembre 2008 Statut Membre Dernière intervention 18 août 2014 60
22 janv. 2010 à 23:21
bah imagine tu pe :

selectionne derniere ligne vide puis en remontant repere la prochaine vide et additionne tte les cell entre les 2
0
Gord21 Messages postés 918 Date d'inscription samedi 21 novembre 2009 Statut Membre Dernière intervention 20 mars 2013 289
22 janv. 2010 à 23:51
Bonsoir,
Oui, tu peux, ça revient au même. Au lieu de commencer à la première ligne du classeur, tu commences à la dernière et tu remplaces End(xlDown) par End(xlUp).

Je ne pense pas que tu y gagnes en temps de calcul.
0
Jabba the Hutt Messages postés 32 Date d'inscription vendredi 22 janvier 2010 Statut Membre Dernière intervention 2 août 2010
22 janv. 2010 à 23:24
mdr,

oui pour imaginer j'y arrivais, le pb étais plus d'écrire le code, mais en réalité le pb est maintenant résolu grace aux deux codes plus haut. Les deux répondent à la question initialement posée.

:=)
0
moiced59 Messages postés 1145 Date d'inscription samedi 15 novembre 2008 Statut Membre Dernière intervention 18 août 2014 60
23 janv. 2010 à 08:41
ok salut
0