Moyenne de n cellule en décaler

Bonjour/Bonsoir.

Je réalise un projet sur une bdd excel avec l'utilisation des fameuses macros.

Je découvre le langage VBA, donc vous voila prévenue de mon niveau

Ma bdd contient des relevés de débits (du mois étudié) d'une station et mon objectif finale est de réaliser un récapitulatif (tableau + graphique) .

Mais pour arriver à ce final, il y a plusieurs étapes évidemment.

Mise en contexte:

  • j'ai réalisé des macros en amont pour arriver au stade suivant (sur une nouvelle feuille):
  • j'ai une colonne nommée "Valeur" qui est variable, c'est à dire que selon le mois étudié et le nombre de mesure par heure (mis en place par la station), le nombre de lignes peut donc être de 10 000 ou 5 000.
  • j'ai une autre colonne nommée "Jour", dans laquelle il y a la date des relevés, du type "20/03/2018" (cette colonne est aussi variable)
  • une autre colonne "Heure" avec donc l'heure de la réalisation du relevé.
(exemple pour la ligne 2 de mon fichier:

colonne"Valeur"= 15.2

colonne"Jour"=01/03/2019

colonne "Heure"=00:15

Mon problème est le suivant:

-j'aimerais créer une nouvelle colonne qui sera variable aussi (car elle prendrait en compte les trois précédentes qui le sont).

Dans cette colonne, je voudrais mettre en place une fonction (ou autre) qui me permette de calculer la moyenne de débits par heure.

Je m'explique, si par exemple le nombre de mesure par heure est 4 (relevé effectué tous les quarts d'heure) et que le nombre de jour dans le mois est 30, ALORS je voudrais voudrais dans cette nouvelle colonne, 30(jours) multiplié par 24(heures) =, 720 lignes/cellules. Et pour chaque heure avec la moyenne.

VOILA VOILA .

Pour m'aider, j'ai juger utile de mettre en place un système d’input box pour demander le nombre de mesures par heure et de jour.

  • j'ai donc, dans une cellule, le nombre de mesures réalisé par heure.
  • j'ai également le nombre de jour dans le mois en question, mis dans une autre cellule.

En faisant des recherches sur le net, j'ai vu que la fonction décaler était pas mal pour ce genre de problème, mais malheureusement je n'ai pas réussi à obtenir le résultat voulu.

En espérant avoir une réponse positif de votre part.

Merci d'avance.

Bonjour saphya


Si j'ai presque tout compris de ton problème dans les grandes lignes, je n'ai en revanche pas bien compris l'objectif final et en particulier

Je m'explique, si par exemple le nombre de mesure par heure est 4 (relevé effectué tous les quarts d'heure) et que le nombre de jour dans le mois est 30, ALORS je voudrais voudrais dans cette nouvelle colonne, 30(jours) multiplié par 24(heures) =, 720 lignes/cellules. Et pour chaque heure avec la moyenne.

Serait il envisageable de voir ce que tu as déjà réalisé pour que nous nous fassions une idée de ce que tu cherches à faire. Même si "le projet" n'est pas abouti, au moins une description des cas concrets envisagés lors de l'étude de ce projet et surtout quel résultat final tu veux obtenir tant dans le fond que la forme.


En aparté...

J'ai un peu de mal à comprendre pourquoi un sujet "si simple" en apparence en tout cas, nécessite l'utilisation de "autant de" VBA comme tu as l'air de le dire.

Je ne comprends pas bien non plus, la nécessité des "input-box"...

Ou alors, quelque chose doit m'échapper dans ta présentation du sujet.

Hello!

Déjà je te remercie énormément d'avoir pris le temps de lire ma requête

Alors enfaite l'objectif final de mon projet serait de faire un tableau et un graph récapitulatifs des relevés du mois étudié, MAIS ici dans ma requête le but n'est pas de réaliser le tableau et le graph.

Mon problème est l'étape en amont

J'utilise vba car les relevés sont faits tous les mois, du coup j'ai 12 fichiers différents pour une année, et donc il est plus pratique de créer une macro pour faire ces étapes répétitives (surtout qu'on m'a demandé de travailler avec, je suis stagiaire).

Je te joint le fichier, je pense que c'est plus pratique

(dans cette feuille j'ai mis dans deux cellules: le nombre de jour du mois en question et le nombre de mesure réalisé par heure, ces elements font que le nombre de relevés/cellules est variable)

Si tu as besoin davantage d'info, fait moi signe !

Merci d'avance

Ps: j'ai pensé à faire un tableau croisé dynamique ( avec donc les relevés moyens, avec en ordonnée les jours du mois, et en abscisse les heures) si tu as une piste pour réaliser une macro je suis preneuse, sinon ce n'est point grave

Bonjour,

un TCD te le calcul tout seul.

Ta macro pourra donc se limiter à regrouper les données, actualiser le TCD, exploiter éventuellement le TCD.

Tableau Croisé Dynamique (TCD) : http://www.mdf-xlpages.com/modules/smartsection/item.php?itemid=109

et

http://www.mdf-xlpages.com/modules/publisher/item.php?itemid=130

eric

Bonjour, (eriiic)

Autre solution VBA pour le calcul des moyennes

Si tu as besoin de "commenter" le code dis-le mais je pense qu'il se comprend de lui-même !

Sub CalculerMoyenne()
Dim tabMesure()
Dim somMesure
Dim nbrMesure
Dim cptMesure

Dim ligDeb, colDeb
Dim ligFin, colFin
Dim colNbr

    nbrMesure = Cells(1, 2)
    somMesure = 0

    ligDeb = 2
    colDeb = 3
    ligFin = Cells(Rows.Count, colDeb).End(xlUp).Row
    colFin = 6
    colNbr = colFin - colDeb + 1

    tabMesure = Range(Cells(ligDeb, colDeb), Cells(ligFin, colFin + 1))
    For cptMesure = 1 To UBound(tabMesure, 1)
        somMesure = somMesure + tabMesure(cptMesure, UBound(tabMesure, 2) - 1)
        If cptMesure Mod nbrMesure = 0 Then
            tabMesure(cptMesure, colNbr + 1) = somMesure / nbrMesure
            somMesure = 0
        End If
    Next
    Cells(2, 8).Resize(UBound(tabMesure, 1), UBound(tabMesure, 2)) = tabMesure
End Sub

@eriiic

Je ne savais pas que tu étais "fan" de mdf-XLPages

Bonjour,

fan est un bien grand mot

Disons que quand je trouve un tuto bien clair je le met de coté.

C'est plus complet que d'expliquer en 2-3 phrases.

eric

Bonjour

@eriiic

C'est une bonne méthode, il est vrai que les tutos de Didier son assez bien conçus - Certains sur des sujets rares d'ailleurs !

Bonjour

@saphya

Merci d'avoir aimé nos messages mais l'un au moins des deux est il la résolution du problème ?

Bonjour, (eriiic)

Autre solution VBA pour le calcul des moyennes

Si tu as besoin de "commenter" le code dis-le mais je pense qu'il se comprend de lui-même !

Sub CalculerMoyenne()
Dim tabMesure()
Dim somMesure
Dim nbrMesure
Dim cptMesure

Dim ligDeb, colDeb
Dim ligFin, colFin
Dim colNbr

    nbrMesure = Cells(1, 2)
    somMesure = 0

    ligDeb = 2
    colDeb = 3
    ligFin = Cells(Rows.Count, colDeb).End(xlUp).Row
    colFin = 6
    colNbr = colFin - colDeb + 1

    tabMesure = Range(Cells(ligDeb, colDeb), Cells(ligFin, colFin + 1))
    For cptMesure = 1 To UBound(tabMesure, 1)
        somMesure = somMesure + tabMesure(cptMesure, UBound(tabMesure, 2) - 1)
        If cptMesure Mod nbrMesure = 0 Then
            tabMesure(cptMesure, colNbr + 1) = somMesure / nbrMesure
            somMesure = 0
        End If
    Next
    Cells(2, 8).Resize(UBound(tabMesure, 1), UBound(tabMesure, 2)) = tabMesure
End Sub

@eriiic

Je ne savais pas que tu étais "fan" de mdf-XLPages

Salut ,

Merciii énormément d'avoir pris le temps de réaliser une macro pour ce problème !

Mais pourrais tu m'expliquais davantage les étapes stp

Est ce que le nombre de jour inscrit dans la cellule B2 t'a été utile ? (ou bien pas la peine de le demander à l'utilisateur ?)

Aussi, pour la colonne L (ou il y a un les moyennes par heures),

  • à partir de cette colonne, aurait-il un moyen de créer une nouvelle colonne en skippant les cellules vides ? (j'aimerais avoir plusieurs colonnes pour avoir toutes les étapes)
  • également une autre colonne avec les dates regroupées par heure associé au relevé moyen?
(ainsi avoir deux colonnes qui me permettent de faire un tableau simple avec les relevés moyens par jour et heure)

J’espère avoir bien expliqué

En tt cas merci encore

Bonjour

Merciii énormément d'avoir pris le temps de réaliser une macro pour ce problème !

Mais pourrais tu m'expliquais davantage les étapes stp

=>

Si tu as besoin de "commenter" le code dis-le mais je pense qu'il se comprend de lui-même !

Donc je vais t'envoyer une version commentée !

Je répondrais aux autres questions après...

Bonjour à tous.

Il s'agit d'un multipost (au moins 3 forums) où j'avais ce matin fait sensiblement la même proposition qu'Eriiic

Comme dit aussi là-bas :

Un TCD se fait une fois pour toute et pas en VBA : on modifie la source et on l'actualise.

Il peut pointer sur une fichier externe qu'on écrase au fil du temps...

Bonjour

Réponse à la question "Est ce que le nombre de jour inscrit dans la cellule B2 t'a été utile ?" => Non inutile

Pour info le dernier quantième d'un mois se calcule ainsi

=Jour( Date( uneAnnee, unMois, 1) -1)

uneAnnee (est une annee au choix), unMois (est le mois suivant du mois dont on veut connaitre le nombre de jour)

le 1 représente le 1er quantième de ce mois, le -1 retranche 1 à la date trouvée

Donc nous avons le jour qui précède le 1er quantième du mois choisi

autrement dit le dernier quantième du mois, donc le nombre de quantième du mois


Voici le code commenté :

'   -------------------------------------------------------
'   Calculer une moyenne sur un Nombre variable de lignes
'   (c)2019, GLI73
'   -------------------------------------------------------
Sub CalculerMoyenne()
Dim tabMesure()         '   TABleau pour lire les MESUREs ligne / ligne
Dim somMesure           '   pour pouvoir faire la SOMme des MESUREs
Dim nbrMesure           '   pour pouvoir adapter la taille du tableau (voir code)
Dim cptMesure           '   ComPTeur des lignes des differentes MESUREs

Dim ligDeb, colDeb      '   pour noter  la LIGne et la COLonne de DEBut des donnees
Dim ligFin, colFin      '   ...         la LIGne et la COLonne de FIN des donnees
Dim colNbr              '   ...         le NomBRe de COLonnes

    nbrMesure = Cells(1, 2)     '   le nombre de mesure est supposé être en cellule 1,2 (B1)
    somMesure = 0               '   pour l'intant aucune sommme n'est realisee

    ligDeb = 2  '   ligne supposee de debut des donnees (a adapter au besoin)
    colDeb = 3  '   idem pour la colonne

    '   Rechercher la derniere ligne des donnees
    '       ROW         donne une ligne
    '       END(xlUp)   fait revenir a la derniere cellule non vide vers le haut (xlUp) - identique a [CTRL-HAUT]
    '       ROWS.COUNT  deplace (virtuellement) le pointeur de cellule sur la derrniere ligne d'un onglet
    '   =>  Nous avons donc remonté depuis la derniere ligne d'Excel vers le haut jusqu'à la premiere cellule non vide
    ligFin = Cells(Rows.Count, colDeb).End(xlUp).Row
    colFin = 6  '   Arbitrairement la derniere colonne est fixee a la 6ème (a adapter au besoin)
    colNbr = colFin - colDeb + 1    '   Trouver le nombre de colonnes utiles

    '   Initialiser le tableau des mesures avec led donnees utiles de ligDeb,colDeb à ligFin,colFin
    '   !!! Ajout d'une colonne supplementaire (colFin +1) pour pouvoir enregistrer directement dans le tableau
    '       la moyenne au fur et a mesure du calcul
    tabMesure = Range(Cells(ligDeb, colDeb), Cells(ligFin, colFin + 1))

    '   Maintenant le traitement commence

    '   Parcours du tabelau des donnees
    '   Pour toutes les lignes du tableau (ubound(... , 1) designe la dimension ligne du tableau)
    For cptMesure = 1 To UBound(tabMesure, 1)
        '   Sur chaque ligne SOMMER la colonne de mesure en additionnant la valeur de precedente
        somMesure = somMesure + tabMesure(cptMesure, UBound(tabMesure, 2) - 1)

        '   Pour savoir SI nous avons le 'bon nombre de mesures' pour faire la moyenne
        '       l'astuce utilisee est la suivante :
        '       la fonction MOD permet de connaitre le RESTE d'une division Euclidienne donc le reste de la division entiere
        '       =>  en divisant le compteur de mesure par le nombre de mesure a prendre nous savons aussitôt
        '           si nous avons le nombre de mesure
        If cptMesure Mod nbrMesure = 0 Then
            '   Alors nous pouvons calculer la moyenne
            '       en utilisant la colonne supplementaire ajoutee plus haut
            tabMesure(cptMesure, colNbr + 1) = somMesure / nbrMesure
            '   Une fois la moyenne calculee et stockee dans le tableau re-initialisation de la SOMme des MESUREs
            '   pour le prochain groupe de mesure
            somMesure = 0
        End If  '   Fin Si 'bon nombre de mesures'
    Next    ' Fin du Parcours du tableau... passer à la ligne suivante

    '   Copier le tableau contenant les moyennes
    '       Resize      permet de redimensionner (virtuellement) une cellule
    '                   les parametres sont la hauteur (nombre de lignes) et la lrageur (nombre de colonnes)
    '       La fonction Ubound permet de connaitre les dimesions d'un tableau
    '           Ubound(... ,1) donne le nombre de lignes
    '           Ubound(..., 2) donne le nombre de colonnnes
    '       Dans l'exemple le tableau est donc copié dans la celliule (redimensionnee) de ligne 2, colonne 8 (H2)
    Cells(2, 8).Resize(UBound(tabMesure, 1), UBound(tabMesure, 2)) = tabMesure
End Sub

  • à partir de cette colonne, aurait-il un moyen de créer une nouvelle colonne en skippant les cellules vides ? (j'aimerais avoir plusieurs colonnes pour avoir toutes les étapes)
  • également une autre colonne avec les dates regroupées par heure associé au relevé moyen?
(ainsi avoir deux colonnes qui me permettent de faire un tableau simple avec les relevés moyens par jour et heure)
vous pouvez répéter la question ou faire un dessin sous Excel du résultat souhaité ?

Bonjour

@78chris

Même si je suis de ton avis... Je pense que beaucoup de gens (parmi les novices en particulier) n'aime pas les TCD car ils n'ont pas la logique d'esprit pour les concevoir !

Et il semble que saphya soit de ceux-là !

Perso j'avoue que j'évite les TCD je les trouve mal pratique à concevoir et pire encore mal utilisés au final par l'utilisateur final justement ! Mais cela n'engage que moi

Bonjour,

oui, cela n'engage que toi

De toute façon la demandeuse elle s'en fout.

Elle passe mettre un j'aime et se casse sans même mettre un retour...

Ca et le multipostage ça fait beaucoup pour une seule personne, qui de débrouillera sans moi la prochaine fois.

eric

RE

Il est 1000 fois plus facile d'apprendre à créer et exploiter des TCD que d'apprendre à coder correctement.

La logique en est très simple.

En tant que formateur, autant sur l'un que sur l'autre, je sais de quoi je parle...

En plus les TCD offrent une souplesse que ne permet pas un code prévu pour répondre à un cahier des charges précis.

Ici on obtient le résultat en quelques clics.

Je n'ai rien contre le VBA mais pas quand on fait aussi bien sans.

En plus Avec PowerPivot et PowerQuery les TCD offrent de plus en plus de possibilités...

Si tu as des cas qui te paraissent difficile à concevoir, on peut en parler pour voir où le bas blesse...

Bonjour

@eriiic

Je ne fais pas de commentaire sur l'appréciation, cependant que j'approuve tout à fait la chose autant que je désapprouve le procédé !

Effectivement il serait "sympa" pour les autres co-forumeurs de ...

Bonjour

@78chris

Merci beaucoup pour tes remarques !

Pouvons terminer en MP au sujet de

Si tu as des cas qui te paraissent difficile à concevoir, on peut en parler pour voir où le bas blesse...

Bonjour,

un TCD te le calcul tout seul.

Ta macro pourra donc se limiter à regrouper les données, actualiser le TCD, exploiter éventuellement le TCD.

Tableau Croisé Dynamique (TCD) : http://www.mdf-xlpages.com/modules/smartsection/item.php?itemid=109

et

http://www.mdf-xlpages.com/modules/publisher/item.php?itemid=130

eric

Bonjour

Je vais essayer d'en apprendre plus sur les TCD, merci bcp pour les liens

Enfaite ce que je veux c'est réaliser une macro qui m'aide à faire un tableau récapitulatif, car la macro va devoir être utilisé pour plusieurs fichiers. Du coup voila je ne sais pas si cela à sert à quelque chose de faire un TCD au final ...

Merci encore d'avoir pris le temps de me répondre

Bye

Bonjour

Réponse à la question "Est ce que le nombre de jour inscrit dans la cellule B2 t'a été utile ?" => Non inutile

Pour info le dernier quantième d'un mois se calcule ainsi

=Jour( Date( uneAnnee, unMois, 1) -1)

uneAnnee (est une annee au choix), unMois (est le mois suivant du mois dont on veut connaitre le nombre de jour)

le 1 représente le 1er quantième de ce mois, le -1 retranche 1 à la date trouvée

Donc nous avons le jour qui précède le 1er quantième du mois choisi

autrement dit le dernier quantième du mois, donc le nombre de quantième du mois


Voici le code commenté :

'   -------------------------------------------------------
'   Calculer une moyenne sur un Nombre variable de lignes
'   (c)2019, GLI73
'   -------------------------------------------------------
Sub CalculerMoyenne()
Dim tabMesure()         '   TABleau pour lire les MESUREs ligne / ligne
Dim somMesure           '   pour pouvoir faire la SOMme des MESUREs
Dim nbrMesure           '   pour pouvoir adapter la taille du tableau (voir code)
Dim cptMesure           '   ComPTeur des lignes des differentes MESUREs

Dim ligDeb, colDeb      '   pour noter  la LIGne et la COLonne de DEBut des donnees
Dim ligFin, colFin      '   ...         la LIGne et la COLonne de FIN des donnees
Dim colNbr              '   ...         le NomBRe de COLonnes

    nbrMesure = Cells(1, 2)     '   le nombre de mesure est supposé être en cellule 1,2 (B1)
    somMesure = 0               '   pour l'intant aucune sommme n'est realisee

    ligDeb = 2  '   ligne supposee de debut des donnees (a adapter au besoin)
    colDeb = 3  '   idem pour la colonne

    '   Rechercher la derniere ligne des donnees
    '       ROW         donne une ligne
    '       END(xlUp)   fait revenir a la derniere cellule non vide vers le haut (xlUp) - identique a [CTRL-HAUT]
    '       ROWS.COUNT  deplace (virtuellement) le pointeur de cellule sur la derrniere ligne d'un onglet
    '   =>  Nous avons donc remonté depuis la derniere ligne d'Excel vers le haut jusqu'à la premiere cellule non vide
    ligFin = Cells(Rows.Count, colDeb).End(xlUp).Row
    colFin = 6  '   Arbitrairement la derniere colonne est fixee a la 6ème (a adapter au besoin)
    colNbr = colFin - colDeb + 1    '   Trouver le nombre de colonnes utiles

    '   Initialiser le tableau des mesures avec led donnees utiles de ligDeb,colDeb à ligFin,colFin
    '   !!! Ajout d'une colonne supplementaire (colFin +1) pour pouvoir enregistrer directement dans le tableau
    '       la moyenne au fur et a mesure du calcul
    tabMesure = Range(Cells(ligDeb, colDeb), Cells(ligFin, colFin + 1))

    '   Maintenant le traitement commence

    '   Parcours du tabelau des donnees
    '   Pour toutes les lignes du tableau (ubound(... , 1) designe la dimension ligne du tableau)
    For cptMesure = 1 To UBound(tabMesure, 1)
        '   Sur chaque ligne SOMMER la colonne de mesure en additionnant la valeur de precedente
        somMesure = somMesure + tabMesure(cptMesure, UBound(tabMesure, 2) - 1)

        '   Pour savoir SI nous avons le 'bon nombre de mesures' pour faire la moyenne
        '       l'astuce utilisee est la suivante :
        '       la fonction MOD permet de connaitre le RESTE d'une division Euclidienne donc le reste de la division entiere
        '       =>  en divisant le compteur de mesure par le nombre de mesure a prendre nous savons aussitôt
        '           si nous avons le nombre de mesure
        If cptMesure Mod nbrMesure = 0 Then
            '   Alors nous pouvons calculer la moyenne
            '       en utilisant la colonne supplementaire ajoutee plus haut
            tabMesure(cptMesure, colNbr + 1) = somMesure / nbrMesure
            '   Une fois la moyenne calculee et stockee dans le tableau re-initialisation de la SOMme des MESUREs
            '   pour le prochain groupe de mesure
            somMesure = 0
        End If  '   Fin Si 'bon nombre de mesures'
    Next    ' Fin du Parcours du tableau... passer à la ligne suivante

    '   Copier le tableau contenant les moyennes
    '       Resize      permet de redimensionner (virtuellement) une cellule
    '                   les parametres sont la hauteur (nombre de lignes) et la lrageur (nombre de colonnes)
    '       La fonction Ubound permet de connaitre les dimesions d'un tableau
    '           Ubound(... ,1) donne le nombre de lignes
    '           Ubound(..., 2) donne le nombre de colonnnes
    '       Dans l'exemple le tableau est donc copié dans la celliule (redimensionnee) de ligne 2, colonne 8 (H2)
    Cells(2, 8).Resize(UBound(tabMesure, 1), UBound(tabMesure, 2)) = tabMesure
End Sub

  • à partir de cette colonne, aurait-il un moyen de créer une nouvelle colonne en skippant les cellules vides ? (j'aimerais avoir plusieurs colonnes pour avoir toutes les étapes)
  • également une autre colonne avec les dates regroupées par heure associé au relevé moyen?
(ainsi avoir deux colonnes qui me permettent de faire un tableau simple avec les relevés moyens par jour et heure)
vous pouvez répéter la question ou faire un dessin sous Excel du résultat souhaité ?

Merciiiiiii beaucoup pour tes explications TRÈS précises , je suis davantage éclairée

Pour ma requete à la fin, je vais essayer de trouver une solution par moi même et si je n'y arrive pas je te ferais signe.

Merci encore pour ton temps

Bonjour

Merci pour

Merciiiiiii beaucoup pour tes explications TRÈS précises , je suis davantage éclairée

Je suis également ravi que tu envisages de faire le pas du TCD !

N'hésite pas à revenir si tu "sèches", en attendant bon courage !

Rechercher des sujets similaires à "moyenne decaler"