IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Range dynamique pour fonctions


Sujet :

Macros et VBA Excel

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2011
    Messages : 6
    Points : 5
    Points
    5
    Par défaut Range dynamique pour fonctions
    Bonjour,

    Je cherche à faire quelque chose de particulier. Je commence tout juste en VBA. J'ai fait le tour des forums et je n'ai rien trouvé qui puissent m'aider.

    Je possède une base de données qui me permet de rappeler un certaine nombre d'entre elles et de les classer. Le hic, c'est que le nombre est variable selon les critères et donc que mes plages de sorties varient.

    Voici un exemple de ce que je peux avoir. (en surligné ce que j'aimerais avoi, idéalement les moyennes serait alignées dans une colonne)

    A B CDEFGH
    5 1 abc Moyenne 5 Moyenne Écart-type Nb()
    5 20 abcdefg Moyenne 45 Moyenne Écart-type Nb()
    5 31 ab Moyenne 90 Moyenne Écart-type Nb()

    45 2 a Moyenne
    45 7 ab Moyenne
    45 35 a Moyenne
    45 41 abcd Moyenne
    45 42 abc Moyenne

    90 5 ab Moyenne
    90 12 abcdefgh Moyenne


    Je cherche à calculer la moyenne de chaque ligne à la dernière colone +1, la moyenne de la moyenne de chaque ligne, l'écart type de la moyenne de chaque ligne pour chaque bloc de données ainsi que le nb de la colonne B de chaque bloc.

    Je pense qu'une manière d'y arriver est de définir le range de la colonne 3 jusqu'à la dernière colonne utilisée de la feuille jusqu'à la ligne vide et faire une boucle pour chaque bloc de données. Mettre ça en VBA après, c'est autre chose...

    J'espère que c'est suffisamment clair. Merci beaucoup!!

  2. #2
    Membre chevronné Avatar de ZebreLoup
    Homme Profil pro
    Ingénieur Financier
    Inscrit en
    Mars 2010
    Messages
    994
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur Financier
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 994
    Points : 2 131
    Points
    2 131
    Par défaut
    Désolé mais pour ma part je n'ai rien compris à ce que tu voulais faire. J'espère que d'autres seront plus perspicaces que moi. Sinon, tu peux reformuler ou donner un exemple ?
    « Compter en octal, c’est comme compter en décimal, si on n’utilise pas ses pouces » - Tom Lehrer
    « Il est assez difficile de trouver une erreur dans son code quand on la cherche. C’est encore bien plus dur quand on est convaincu que le code est juste. » - Steve McConnell

  3. #3
    Expert éminent sénior
    Homme Profil pro
    aucune
    Inscrit en
    Septembre 2011
    Messages
    8 203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Septembre 2011
    Messages : 8 203
    Points : 14 354
    Points
    14 354
    Par défaut
    Bonjour,

    Franchement, je ne comprends pas l'organisation de tes données. Est-ce la base de données ou le résultat souhaité ?
    Cordialement.

    Daniel

    La plus perdue de toutes les journées est celle où l'on n'a pas ri. Chamfort

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2011
    Messages : 6
    Points : 5
    Points
    5
    Par défaut Une image vaut mille mots
    Voici une explication plus claire.

    Je cherche à pouvoir appliquer différentes fonctions (voir images) sur une série de données qui peuvent avoir un nombre de lignes et de colonnes variable mais qui sont toujours circonscrites en (3) blocs (voir images).

    Je cherche à avoir sur ces plages de données

    • La moyenne de chaque ligne alignée à la dernière colonne + 1
    • La moyenne des moyennes de chaque ligne pour chaque bloc
    • Le SEM (ecarttype()/racine(nb())) des moyennes de chaque ligne pour chaque bloc
    • Le nb() des moyennes de chaque ligne pour chaque bloc


    Sur les images en

    noir: ce que j'ai en ce moment
    vert: ce que j'aimerais obtenir




    Une solution à laquelle j'avais pensée c'est de trouver le nombre de colonnes max et les lignes vides et de définir mon range à partir de ce max et de la ligne vide puis faire une boucle pour chaque bloc. Étant débutant en VBA je ne sais pas comment pouvoir appliquer ça en pratique.

    Merci

  5. #5
    Expert éminent sénior
    Homme Profil pro
    aucune
    Inscrit en
    Septembre 2011
    Messages
    8 203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Septembre 2011
    Messages : 8 203
    Points : 14 354
    Points
    14 354
    Par défaut
    Pour tes formules "moyenne", est-ce ce que tu veux valable pour la colonne N (14) ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Range([A1], Cells(Rows.Count, 1).End(xlUp)).Offset(, 13).FormulaR1C1 = "=AVERAGE(RC3:RC[-1])"
    Cordialement.

    Daniel

    La plus perdue de toutes les journées est celle où l'on n'a pas ri. Chamfort

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2011
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Bonjour Daniel,

    Merci de la réponse.

    J'ai fait un petit ajout pour que les moyennes s'ajoutent toujours à la dernière colonne.

    Deux questions demeurent:

    • Comment ajouter les autres fonctions calculées sur les moyennes des blocs?
    • Comment faire pour que la formule ne s'applique pas aux lignes vides?


    Pour le moment j'ai ceci qui fonctionne bien outre les points mentionnés ci-hauts.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     
    Dim Last As Long
        Last = Cells.Find("*", SearchOrder:=xlByColumns, _
        LookIn:=xlValues, SearchDirection:=xlPrevious).Column
     
    Range([A2], Cells(Rows.Count, 1).End(xlUp)).Offset(, Last).FormulaR1C1 = "=AVERAGE(RC3:RC[-1])"

    Merci

  7. #7
    Expert éminent sénior
    Homme Profil pro
    aucune
    Inscrit en
    Septembre 2011
    Messages
    8 203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Septembre 2011
    Messages : 8 203
    Points : 14 354
    Points
    14 354
    Par défaut
    Comment ajouter les autres fonctions calculées sur les moyennes des blocs?
    Tu peux me donner un exemple sur les feuilles que tu as publiées ?

    Comment faire pour que la formule ne s'applique pas aux lignes vides?
    Essaie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Sub test()
        Dim LastCol As Long
        LastCol = Cells.Find("*", SearchOrder:=xlByColumns, _
        LookIn:=xlValues, SearchDirection:=xlPrevious).Column
        lastlig = Cells.Find("*", SearchOrder:=xlByRows, _
        LookIn:=xlValues, SearchDirection:=xlPrevious).Row
        For Each c In Range([A2], Cells(lastlig, 1)).Offset(, LastCol)
            If Application.CountA(Range(Cells(c.Row, 1), Cells(c.Row, LastCol))) > 0 Then
                c.Formula = "=AVERAGE(" & Range(Cells(c.Row, 1), Cells(c.Row, LastCol)).Address(0, 0) & ")"
            End If
        Next c
    End Sub
    Cordialement.

    Daniel

    La plus perdue de toutes les journées est celle où l'on n'a pas ri. Chamfort

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2011
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Le code évitant les lignes vides fonctionne très bien. Merci!

    Pour les statistiques (moyenne, SEM et nb()) sur les blocs de donnée, sur l'image
    • supérieure ça fait référence aux formules de Q2 à S4
    • inférieure ça fait référence aux formules de J2 à L4.
    • En P2:4 et I2:4 respectivement on retrouve le numéro du bloc dans le colonne A duquel sont issus les fonctions.


    Merci encore

  9. #9
    Expert éminent sénior
    Homme Profil pro
    aucune
    Inscrit en
    Septembre 2011
    Messages
    8 203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Septembre 2011
    Messages : 8 203
    Points : 14 354
    Points
    14 354
    Par défaut
    Bonjour,

    Pour la moyenne et la colonne P. Essaie d'adapter pour le reste (c'est quoi "SEM" ?) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    Sub test1()
        'Réf. 111119.xlsm
        Dim Ligne As Long, Res As String, Ligne1 As Long
        Ligne = 1
        Ligne1 = 1
        Dim c As Range
        For Each c In Range([N2], Cells(Rows.Count, 14).End(xlUp))
            If c.Offset(1).Value = "" And c.Value <> "" Then
                Ligne = Ligne + 1
                Cells(Ligne, "S").Formula = "=AVERAGE(" & Res & ":" & c.Address & ")"
            ElseIf c.Value <> "" And c.Offset(-1) = 0 Then
                Res = c.Address
                Ligne1 = Ligne1 + 1
                Cells(Ligne1, "P").Formula = "=" & c.Address(0, 0)
            End If
        Next c
    End Sub
    Cordialement.

    Daniel

    La plus perdue de toutes les journées est celle où l'on n'a pas ri. Chamfort

  10. #10
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2011
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Le debugger s'active à la ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ElseIf c.Value <> "" And c.Offset(-1) = 0 Then
    SEM c'est Standard error of mean ou erreur standard de la moyenne. En fonction excel on parle de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    =ecartype(X)/racine(nb(X)))
    .

    Ci-joint le classeur sur lequel le code a été testé.

    Merci
    Fichiers attachés Fichiers attachés

  11. #11
    Expert éminent sénior
    Homme Profil pro
    aucune
    Inscrit en
    Septembre 2011
    Messages
    8 203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Septembre 2011
    Messages : 8 203
    Points : 14 354
    Points
    14 354
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    Sub Moyenne()
        'Réf. 111119.xlsm
        'données en colonne G
        'moyenne en colonne H
        'NB en colonne J
        'Ecart type en colonne K
        Dim Ligne As Long, Res As String, Ligne1 As Long
        Ligne = 1
        Ligne1 = 1
        Dim c As Range
        For Each c In Range([G2], Cells(Rows.Count, 7).End(xlUp))
            If c.Offset(1).Value = "" And c.Value <> "" Then
                Ligne = Ligne + 1
                Cells(Ligne, "H").Formula = "=AVERAGE(" & Res & ":" & c.Address & ")"
                Cells(Ligne, "J").Formula = "=COUNT(" & Res & ":" & c.Address & ")"
                Cells(Ligne, "K").Formula = "=STDEV(" & Res & ":" & c.Address & ")" & _
                    "/SQRT(" & Cells(Ligne, "J").Address(0, 0) & ")"
            ElseIf c.Value <> "" And c.Offset(-1) = "" Then
                Res = c.Address
                Ligne1 = Ligne1 + 1
                Cells(Ligne1, "I").Formula = "=" & c.Address(0, 0)
            End If
        Next c
    End Sub
    Cordialement.

    Daniel

    La plus perdue de toutes les journées est celle où l'on n'a pas ri. Chamfort

  12. #12
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2011
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Wow Daniel, je dois avouer que je trouve ça presque magique!

    J'ai encore une fois changé légèrement le code pour que ce soit toujours relatif à la dernière colonne puisque celle-ci change en fonction du nombre de données.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    Sub Macro1()
        'Trouver la dernière colonne Last
        Dim Last As Long
        Last = Cells.Find("*", SearchOrder:=xlByColumns, _
        LookIn:=xlValues, SearchDirection:=xlPrevious).Column
        'Moyenne, SEM et N
        'moyenne des lignes en colonne Last
        Dim Ligne As Long, Res As String, Ligne1 As Long
        Ligne = 1
        Ligne1 = 1
        Dim c As Range
        For Each c In Range([G2], Cells(Rows.Count, Last).End(xlUp))
            If c.Offset(1).Value = "" And c.Value <> "" Then
                Ligne = Ligne + 1
                'moyenne en colonne Last+2
                Cells(Ligne, Last + 2).Formula = "=AVERAGE(" & Res & ":" & c.Address & ")"
                 'Ecart type en colonne Last + 3
                Cells(Ligne, Last + 3).Formula = "=STDEV(" & Res & ":" & c.Address & ")" & _
                    "/SQRT(" & Cells(Ligne, Last + 4).Address(0, 0) & ")"
                 'NB en colonne Last + 4
                Cells(Ligne, Last + 4).Formula = "=COUNT(" & Res & ":" & c.Address & ")"
            ElseIf c.Value <> "" And c.Offset(-1) = "" Then
                Res = c.Address
                Ligne1 = Ligne1 + 1
               'Numero du groupe en colonne Last + 1
                Cells(Ligne1, Last + 1).Formula = "=" & c.Address(0, 0)
            End If
        Next c
    End Sub
    Il y a deux lignes que je n'ai pas su ajuster.

    • Je ne réussi pas à mettre [G2] par rapport à Last. Je cherche à viser la cellule dans la colonne Last à la ligne 2. Dans l'exemple c'était G mais ce peut être variable (parce que le nombre maximale de données par ligne varit). J'ai tenté Last[2] mais ma synthaxe a fait sauté le debogger .

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    For Each c In Range([G2], Cells(Rows.Count, Last).End(xlUp))
    • Cela fait référence à la 1ere moyenne de chacune des lignes. Dans l'exemple du classeur précédent il s'agit de la colonne G alors que c'est la colonne A qui devrait toujours (ne change pas) être visée. Par contre, les lignes sont bien selectionnées.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Cells(Ligne1, Last + 1).Formula = "=" & c.Address(0, 0)
    Je dois encore te remercier de ton aide inestimable Daniel. Cela fait des semaines que je cherche à faire ce macro et je n'y serais jamais arrivé sans ton aide.

  13. #13
    Expert éminent sénior
    Homme Profil pro
    aucune
    Inscrit en
    Septembre 2011
    Messages
    8 203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Septembre 2011
    Messages : 8 203
    Points : 14 354
    Points
    14 354
    Par défaut
    Bonjour,

    Essaie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    Sub Moyenne()
        'Réf. 111119.xlsm
        'données en colonne G
        'moyenne en colonne H
        'NB en colonne J
        'Ecart type en colonne K
        Dim Ligne As Long, Res As String, Ligne1 As Long, DerCol As Long
        DerCol = Cells.Find("*", , , , xlByColumns, xlPrevious).Column
        Ligne = 1
        Ligne1 = 1
        Dim c As Range
        For Each c In Range(Cells(2, DerCol), Cells(Rows.Count, DerCol).End(xlUp))
            If c.Offset(1).Value = "" And c.Value <> "" Then
                Ligne = Ligne + 1
                Cells(Ligne, "H").Formula = "=AVERAGE(" & Res & ":" & c.Address & ")"
                Cells(Ligne, "J").Formula = "=COUNT(" & Res & ":" & c.Address & ")"
                Cells(Ligne, "K").Formula = "=STDEV(" & Res & ":" & c.Address & ")" & _
                    "/SQRT(" & Cells(Ligne, "J").Address(0, 0) & ")"
            ElseIf c.Value <> "" And c.Offset(-1) = "" Then
                Res = c.Address
                Ligne1 = Ligne1 + 1
                Cells(Ligne1, "I").Formula = "=" & c.Address(0, 0)
            End If
        Next c
    End Sub
    Cordialement.

    Daniel

    La plus perdue de toutes les journées est celle où l'on n'a pas ri. Chamfort

Discussions similaires

  1. Modifier onclick dynamiquement pour passer une fonction avec paramètres
    Par denisosteo dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 02/01/2014, 12h38
  2. Copie range dynamique en fonction de la date
    Par Invité dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 23/03/2012, 13h41
  3. DataSource dynamique pour fonction importation
    Par Georges_Lauret dans le forum XMLRAD
    Réponses: 1
    Dernier message: 13/06/2007, 15h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo