MACRO POUR MOYENNER DE MANIERE SIMPLE UNE BASE DE DONNEES

Résolu
SERIEUXETCOOL Messages postés 336 Date d'inscription dimanche 3 avril 2011 Statut Membre Dernière intervention 12 juin 2012 - 1 août 2011 à 20:00
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 - 28 sept. 2011 à 09:59
(Dsl si je ne post pas au bon endroit, merci de déplacer)

Bonjour,

Je dispose d'un code sous VBA qui permet de me faire tourner une petite marco sous Excel. Ce code permet de supprimer certaines lignes présentes dans une base de données déjà existante.

Maintenant je cherche poursuivre le développement de cette macro en réalisant 2 fonctions supplémentaires.

-La première fonction est de faire une moyenne sur un ensemble particulier de lignes. Ces lignes vont varier de position suivant la base de données. Et elle ne seront pas au même nombre à chaque fois.

-La dernière fonction étant de remplacer les lignes qui auront servi à calculer les moyennes pas la valeur moyennée justement. Donc on fait une suppression de lignes et un remplacement de valeurs.

Je ne sais pas si je suis clair, de toute façon d'autres explications vont suivre si-après, plus le code pour voir mieux un petit exemple.

Voici le code existant qui permet de créer une petite base de données à titre d'exemple et de supprimer certaines lignes :
(elle fonctionne très bien)

Sub Macro1()
  Cells.Clear ' Vide la feuille

  Dim plage As Range, plage_a_supp As Range
  Dim nb As Long, n As Long, i As Long, j As Long, msg As String
  Dim t, ii As Byte

  t = Split("1 11 21 31") 'Permet de créer une petite table pour exemple
  For ii = 0 To 3
     Cells(t(ii), 1).Resize(10) = ii
     Cells(t(ii), 2).Resize(10) = [=TRANSPOSE({1,2,3,4,5,6,7,8,9,10})]
  Next ii
  n = ActiveSheet.UsedRange.Rows.Count 'Compte le nombre de lignes dynamiques
  nb = 4 'pour ôter 4 lignes en bas et 4 en haut
   If nb = 0 Then Exit Sub
   msg = ""
   For i = 2 To n + 1
     If Range("A" & i).Value = Range("A" & i - 1).Value Then
       If plage Is Nothing Then
         Set plage = Union(Range("A" & i - 1), Range("A" & i))
       Else
         Set plage = Union(plage, Range("A" & i))
       End If
     Else
       If plage.Rows.Count >= nb * 2 Then
         For j = 1 To nb
           If plage_a_supp Is Nothing Then
             Set plage_a_supp = Union(plage(1, 1), plage(plage.Rows.Count, 1))
           Else
             Set plage_a_supp = Union(plage_a_supp, plage(j, 1), plage(plage.Rows.Count + 1 - j, 1))
           End If
         Next
         Set plage = Range("A" & i)
         If Range("A" & i).Value = "" Then Exit For
       Else
         msg = msg & " - " & plage(1, 1).Value
         Set plage = Nothing
         If Range("A" & i).Value = "" Then Exit For
       End If
     End If
   Next
   If Not plage_a_supp Is Nothing Then
     plage_a_supp.Rows.EntireRow.Delete
   End If
   If msg <> "" Then
     MsgBox "les groupes suivants, d'un nombre non suffisant, " & _
     "n'ont pas été traités " & vbCrLf & Mid(msg, 3)
   End If
End Sub


Ce qu'il reste à faire...De manière générale j'ai une feuille excel avec les données suivantes :

Colonne1/Colonne2/Colonne3...
0 xxx xxx
0 xxx xxx
0 xxx xxx
1 xxx xxx
1 xxx xxx
1 xxx xxx
2 xxx xxx
2 xxx xxx
2 xxx xxx
3 xxx xxx
3 xxx xxx
3 xxx xxx

-Les données partent de 0 et vont jusqu'à X. X étant un nombre connu mais variable. C'est une série de nombre entier, ordonnée du plus petit au plus grand.
Chaque entier naturel est répété un certain nombre de fois. Dans mon exemple on compte de 0 à 3 en répétant chaque chiffre 3 fois. (c'est un exemple)

-Mon but est de calculer la moyenne sur certaines colonnes de la manière suivante. Je commence avec la première série de 0. Je fais la moyenne sur toute les lignes qui ont pour indice 0, j'insère une ligne, je note la moyenne et je supprimer toutes les valeurs qui m'on servi à calculer la moyenne. Je fais donc la moyenne pour la colonne A, B,C...

-Ensuite je passe à l'entier naturel suivant, les 1. Et ainsi de suite.

-A la fin je souhaite obtenir un fichier ne représentant que les moyennes

Colonne1/Colonne 2/Colonne3....
0 XXX XXXX
1 XXX XXXX
2 XXX XXXX
3 XXX XXXX

Pour ce faire, il faut bien sur réutiliser le même code précédent. Une première partie du code supprime un certains nombre de lignes et la deuxième partie du code doit pouvoir me calculer la moyenne sur chaque série d'entier naturel et l'afficher pour remplacer la série d'entier.

Je pense être clair mais si vous avez besoin de plus d'infos je suis la.

Merci pour votre aide.

PS : J'ai commencé en utilisant la fonction suivante qui fonctionne. Mais je ne parviens pas à l'intégrer dans une boucle.

Formule = Application.Average(Range("A" & i, ":A" & j))

90 réponses

ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 212
7 août 2011 à 15:56
Bon ...
Je ne te vois pas et n'ai pas de MP !

Mais voilà comment tu vas faire et tous tes problèmes disparaîtront en principe :
1) tu vas là où tu as écrit ta macro (ça, tu sais apparemment faire)
2) tu y effaces tout
3) tu y colles tout ce qui suit, par copier-coller (ne cherche pas pour l'instant à traficotter quoi que ce soit d'autre :
Sub ma_big_macro()
  Dim feuille_donnees As String
  Dim colonne_groupes As String, a_partir_ligne As Integer, ecreter_de_combien As Long
  Dim colonnes_moyennes, colonnes_diff
  
  ' ==============================c'est ici que tu définis la feuille des données ==========================================
  feuille_donnees = "Feuil1" ' <<<<<========= le nom exact de la feuille contenant les groupes à traiter
  ''c'est ici, que tu définis les autres paramètres =========================================
  colonne_groupes = "A" '<<<<<<<======== ici : la colonne des groupes
  a_partir_ligne = 1 '<<<<<<============ ici : la ligne où commencent les groupes
  ecreter_de_combien = 4 '<<<<======= ici : de combien écréter en haut et en bas de chaque groupe
  colonnes_moyennes = Array("B", "D", "E", "F") '<<<<=== ici : énumération des colonnes où faire la moyenne ("") si aucune
  colonnes_diff = Array("C") ' <<<<<===== ici : énumération des colonnes où faire tes "différences" ("") si aucune
  col_groupes = Array(colonne_groupes) ' ---->> ça, c'est pour le code. Ne t'en préoccupe pas.
  '==========================================================================================================================
  
  
  ' ________________________________________ les gardes-fou, maintenant ________________________________________________
  
  If ActiveSheet.Name <> feuille_donnees Then
    MsgBox "cette opération ne doit être lancée que si la feuille " & feuille_donnees & " est la feuille active"
    Exit Sub
  End If
  If verif(col_groupes, colonne_groupes, a_partir_ligne, "colonne des groupes") = False Then Exit Sub
  If verif(colonnes_moyennes, colonne_groupes, a_partir_ligne, "colonne à moyenne") = False Then Exit Sub
  If verif(colonnes_diff, colonne_groupes, a_partir_ligne, "colonne à différence") = False Then Exit Sub
  '______________________________________________________________________________________________________________________
  
  
  ' ------------------------------ si l'exécution atteint ce point, c'est que tout est cohérent -------------------------
  ' ------------------------------ on y va donc -------------------------------------------------------------------------
  ' ---------------------------------------------"écrétant" d'abord------------------------------------------------------
  epurer colonne_groupes, a_partir_ligne, ecreter_de_combien
  ' ----------------------------------------puis en traitant le reste (écart(s) et moyenne(s) ---------------------------
  on_amenage colonne_groupes, a_partir_ligne, colonnes_moyennes, colonnes_diff
  
  
End Sub


Public Sub epurer(ByVal col As String, ByVal ligne As Integer, ByVal nb As Integer)
  Dim plage As Range, plage_a_supp As Range
  Dim n As Long, i As Long, j As Long, msg As String
   n = Range(col & Rows.Count).End(xlUp).Row
   If nb = 0 Then Exit Sub
   msg = ""
   For i = ligne + 1 To n + 1
     If Range(col & i).Value = Range(col & i - 1).Value Then
       If plage Is Nothing Then
         Set plage = Union(Range(col & i - 1), Range(col & i))
       Else
         Set plage = Union(plage, Range(col & i))
       End If
     ElseIf Not plage Is Nothing Then
         If plage.Rows.Count >= nb * 2 Then
           For j = 1 To nb
             If plage_a_supp Is Nothing Then
               Set plage_a_supp = Union(plage(1, 1), plage(plage.Rows.Count, 1))
             Else
               Set plage_a_supp = Union(plage_a_supp, plage(j, 1), plage(plage.Rows.Count + 1 - j, 1))
             End If
           Next
           Set plage = Range(col & i)
           If Range(col & i).Value = "" Then Exit For
          Else
            msg = msg & " - " & plage(1, 1).Value
            Set plage = Nothing
            If Range(col & i).Value = "" Then Exit For
          End If
      Else
        msg = msg & " - " & Cells(i - 1, 1).Value
     End If
   Next
   If Not plage_a_supp Is Nothing Then
     plage_a_supp.Rows.EntireRow.Delete
   End If
   If msg <> "" Then
     MsgBox "les groupes suivants, d'un nombre non suffisant, " & _
     "n'ont pas été traités " & vbCrLf & Mid(msg, 3)
   End If
End Sub
Public Sub on_amenage(ByVal col As String, ByVal ld As Integer, ByVal moy, ByVal dif)
 Dim deb As Long, n As Long, i As Long, combien As Long, k As Long, j As Long
 Dim plage As Range, plage_a_supp As Range
 Dim elmt
 deb = Range(col & ":" & col).Column
 n = Range(col & Rows.Count).End(xlUp).Row
 For i = ld + 1 To n + 1
   If Range(col & i).Value = Range(col & i - 1).Value Then
     If plage Is Nothing Then
       Set plage = Union(Range(col & i - 1), Range(col & i))
     Else
       Set plage = Union(plage, Range(col & i))
     End If
   Else
     If Not plage Is Nothing Then
       combien = plage.Rows.Count
       If combien > 1 Then
         If UBound(moy) > 0 Then
           For Each elmt In moy
             k = Range(elmt & ":" & elmt).Column - deb + 1
             plage.Cells(1, k) = WorksheetFunction.Average(plage.Columns(k))
           Next
         End If
         If UBound(dif) > 0 Then
           For Each elmt In dif
             k = Range(elmt & ":" & elmt).Column - deb + 1
             plage.Cells(1, k).Value = plage(plage.Rows.Count, k).Value - plage(1, k).Value
           Next
         End If
         For j = 2 To combien
             If plage_a_supp Is Nothing Then
               Set plage_a_supp = plage(j, 1)
             Else
               Set plage_a_supp = Union(plage_a_supp, plage(j, 1))
             End If
          Next
       End If
       Set plage = Nothing
     End If
   End If
 Next
 If Not plage_a_supp Is Nothing Then
   plage_a_supp.Rows.EntireRow.Delete
 End If
End Sub
Public Function verif(cols, colonne_groupes, a_partir_ligne, descr As String) As Boolean
  verif = True
  If UBound(cols) = 0 Then Exit Function
  derlig = Range(colonne_groupes & Rows.Count).End(xlUp).Row
  For Each elmt In cols
    Dim plage As Range
    Set plage = Nothing
    On Error Resume Next
    Set plage = Range(elmt & a_partir_ligne & ":" & elmt & derlig).SpecialCells(xlCellTypeBlanks)
    If Not plage Is Nothing Then
      MsgBox "la " & descr & " " & elmt & " contient une cellule vide - Corrigez puis relancez, s'il vous plait !"
      verif = False
      On Error GoTo 0
    End If
  Next
End Function


Voilà qui est fait ?
Bien :
tu modifies maintenant tes paramètres (en fonction de ce que tu as, toi) :
Cela se passe entre les lignes de commentaires encadrées par des ============================ (plus clair, on ne peut pas !)

J'ai de surcroît placé plein de garde-fous (tous ceux qu'il m'était possible de placer) !
Si tu ne t'en sors pas avec tout çà, je ne sais plus quoi faire pour t'aider, ami.
Voilà !




____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
3
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 212
22 sept. 2011 à 22:40
coucou (plus tôt que prévu) :
1) une erreur de ta part ici (pas nécessaire de "moyenner" la colonne A) :
colonnes_moyennes = Array("C", "D", "E", "F", "G", "H") '<<<<=== ici : énumération des colonnes où faire la moyenne ("") si aucunen :
donc ===>>
colonnes_moyennes = Array("C", "D", "E", "F", "G", "H") '<<<<=== ici : énumération des colonnes où faire la moyenne ("") si aucune

2) une inattention de ma part ('tous mes tests étaient plus complexes et j'avais testé avec plusieurs colonnes où faire la différence, sans jamais tester avec une seule colonne !)

Corriger donc cette partie :
If UBound(dif) > 0 Then
           For Each elmt In dif
             k = Range(elmt & ":" & elmt).Column - deb + 1
             plage.Cells(1, k).Value = plage(plage.Rows.Count, k).Value - plage(1, k).Value
           Next
         End If

en la remplaçant par celle-ci :
 If dif(0) <> "" Then
           For Each elmt In dif
             k = Range(elmt & ":" & elmt).Column - deb + 1
             plage.Cells(1, k).Value = plage(plage.Rows.Count, k).Value - plage(1, k).Value
           Next
         End If


Bonne nuit !


____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
3
SERIEUXETCOOL Messages postés 336 Date d'inscription dimanche 3 avril 2011 Statut Membre Dernière intervention 12 juin 2012 1
23 sept. 2011 à 19:42
Ah merci Ucfoutu !!!

Tu m'as fait deux bonnes surprises :

-La première, je viens de voir le code maintenant et en fait tu l'avais posté depuis hier soir déjà. La class.

-La deuxième, la modification apportée par tes soins est en effet efficace.

Sa fonctionne donc beaucoup mieux de cette façon. Il me semblait bien que sa devait sans doute venir d'une petite inattention de programmation. Et au fait, merci aussi pour m'avoir corrigée mon erreur de mettre deux fois la colonne groupe à moyenner. Sa me semble évident maintenant en fait^^

Je poste donc le code corrigé qui fonctionne très bien :

Sub SUPPRESSION_MOYENNE_DIFFERENCE()

Cells.Clear ' Vide la feuille

  Dim plage As Range, plage_a_supp As Range
  Dim nb As Long, n As Long, i As Long, j As Long, msg As String
  Dim t, ii As Byte

  t = Split("1 11 21 31") 'Permet de créer une petite table pour exemple
  
  For ii = 0 To 3
     Cells(t(ii), 1).Resize(10) = ii
     Cells(t(ii), 2).Resize(10) = [=TRANSPOSE({1,2,3,4,5,6,7,8,9,10})]
  Next ii
  
    Cells(41, 1).Value = 3
    Cells(42, 1).Value = 3
    Cells(43, 1).Value = 3
    Cells(44, 1).Value = 3
    Cells(45, 1).Value = 3
    Cells(41, 2).Value = 11
    Cells(42, 2).Value = 12
    Cells(43, 2).Value = 13
    Cells(44, 2).Value = 14
    Cells(45, 2).Value = 15
    
    Columns("A:B").Select
    Selection.Copy
    Columns("C:C").Select
    ActiveSheet.Paste
    Columns("A:D").Select
    Application.CutCopyMode = False
    Selection.Copy
    Columns("E:E").Select
    ActiveSheet.Paste
    Application.CutCopyMode = False
    
  
  
  Dim feuille_donnees As String
  Dim colonne_groupes As String, a_partir_ligne As Integer, ecreter_de_combien As Long
  Dim colonnes_moyennes, colonnes_diff
  
  ' ==============================c'est ici que tu définis la feuille des données ==========================================
  feuille_donnees = "Feuil1" ' <<<<<========= le nom exact de la feuille contenant les groupes à traiter
  ''c'est ici, que tu définis les autres paramètres =========================================
  colonne_groupes = "A" '<<<<<<<======== ici : la colonne des groupes
  a_partir_ligne = 1 '<<<<<<============ ici : la ligne où commencent les groupes
  ecreter_de_combien = 2 '<<<<======= ici : de combien écréter en haut et en bas de chaque groupe
  colonnes_moyennes = Array("C", "D", "E", "F", "G", "H") '<<<<=== ici : énumération des colonnes où faire la moyenne ("") si aucune
  colonnes_diff = Array("B") ' <<<<<===== ici : énumération des colonnes où faire tes "différences" ("") si aucune
  col_groupes = Array(colonne_groupes) ' ---->> ça, c'est pour le code. Ne t'en préoccupe pas.
  '==========================================================================================================================
  
  
  ' ________________________________________ les gardes-fou, maintenant ________________________________________________
  
  If ActiveSheet.Name <> feuille_donnees Then
    MsgBox "cette opération ne doit être lancée que si la feuille " & feuille_donnees & " est la feuille active"
    Exit Sub
  End If
  If verif(col_groupes, colonne_groupes, a_partir_ligne, "colonne des groupes") = False Then Exit Sub
  If verif(colonnes_moyennes, colonne_groupes, a_partir_ligne, "colonne à moyenne") = False Then Exit Sub
  If verif(colonnes_diff, colonne_groupes, a_partir_ligne, "colonne à différence") = False Then Exit Sub
  '______________________________________________________________________________________________________________________
  
  
  ' ------------------------------ si l'exécution atteint ce point, c'est que tout est cohérent -------------------------
  ' ------------------------------ on y va donc -------------------------------------------------------------------------
  ' ---------------------------------------------"écrétant" d'abord------------------------------------------------------
  epurer colonne_groupes, a_partir_ligne, ecreter_de_combien
  ' ----------------------------------------puis en traitant le reste (écart(s) et moyenne(s) ---------------------------
  on_amenage colonne_groupes, a_partir_ligne, colonnes_moyennes, colonnes_diff
  
  
End Sub
Public Sub epurer(ByVal col As String, ByVal ligne As Integer, ByVal nb As Integer)
  Dim plage As Range, plage_a_supp As Range
  Dim n As Long, i As Long, j As Long, msg As String
   n = Range(col & Rows.Count).End(xlUp).Row
   If nb = 0 Then Exit Sub
   msg = ""
   For i = ligne + 1 To n + 1
     If Range(col & i).Value = Range(col & i - 1).Value Then
       If plage Is Nothing Then
         Set plage = Union(Range(col & i - 1), Range(col & i))
       Else
         Set plage = Union(plage, Range(col & i))
       End If
     ElseIf Not plage Is Nothing Then
         If plage.Rows.Count >= nb * 2 Then
           For j = 1 To nb
             If plage_a_supp Is Nothing Then
               Set plage_a_supp = Union(plage(1, 1), plage(plage.Rows.Count, 1))
             Else
               Set plage_a_supp = Union(plage_a_supp, plage(j, 1), plage(plage.Rows.Count + 1 - j, 1))
             End If
           Next
           Set plage = Range(col & i)
           If Range(col & i).Value = "" Then Exit For
          Else
            msg = msg & " - " & plage(1, 1).Value
            Set plage = Nothing
            If Range(col & i).Value = "" Then Exit For
          End If
      Else
        msg = msg & " - " & Cells(i - 1, 1).Value
     End If
   Next
   If Not plage_a_supp Is Nothing Then
     plage_a_supp.Rows.EntireRow.Delete
   End If
   If msg <> "" Then
     MsgBox "les groupes suivants, d'un nombre non suffisant, " & _
     "n'ont pas été traités " & vbCrLf & Mid(msg, 3)
   End If
End Sub
Public Sub on_amenage(ByVal col As String, ByVal ld As Integer, ByVal moy, ByVal dif)
 Dim deb As Long, n As Long, i As Long, combien As Long, k As Long, j As Long
 Dim plage As Range, plage_a_supp As Range
 Dim elmt
 deb = Range(col & ":" & col).Column
 n = Range(col & Rows.Count).End(xlUp).Row
 For i = ld + 1 To n + 1
   If Range(col & i).Value = Range(col & i - 1).Value Then
     If plage Is Nothing Then
       Set plage = Union(Range(col & i - 1), Range(col & i))
     Else
       Set plage = Union(plage, Range(col & i))
     End If
   Else
     If Not plage Is Nothing Then
       combien = plage.Rows.Count
       If combien > 1 Then
         If UBound(moy) > 0 Then
           For Each elmt In moy
             k = Range(elmt & ":" & elmt).Column - deb + 1
             plage.Cells(1, k) = WorksheetFunction.Average(plage.Columns(k))
           Next
         End If
        If dif(0) <> "" Then
           For Each elmt In dif
             k = Range(elmt & ":" & elmt).Column - deb + 1
             plage.Cells(1, k).Value = plage(plage.Rows.Count, k).Value - plage(1, k).Value
           Next
        End If
         For j = 2 To combien
             If plage_a_supp Is Nothing Then
               Set plage_a_supp = plage(j, 1)
             Else
               Set plage_a_supp = Union(plage_a_supp, plage(j, 1))
             End If
          Next
       End If
       Set plage = Nothing
     End If
   End If
 Next
 If Not plage_a_supp Is Nothing Then
   plage_a_supp.Rows.EntireRow.Delete
 End If
End Sub
Public Function verif(cols, colonne_groupes, a_partir_ligne, descr As String) As Boolean
  verif = True
  If UBound(cols) = 0 Then Exit Function
  derlig = Range(colonne_groupes & Rows.Count).End(xlUp).Row
  For Each elmt In cols
    Dim plage As Range
    Set plage = Nothing
    On Error Resume Next
    Set plage = Range(elmt & a_partir_ligne & ":" & elmt & derlig).SpecialCells(xlCellTypeBlanks)
    If Not plage Is Nothing Then
      MsgBox "la " & descr & " " & elmt & " contient une cellule vide - Corrigez puis relancez, s'il vous plait !"
      verif = False
      On Error GoTo 0
    End If
  Next
End Function



Une dernière chose Ucfoutu, quand j'avais réalisé mes tests je m'étais aperçu d'une chose un peu désagréable mais qui ne me dérangeais pas forcément beaucoup sur le coup. Il s'agit du fait que lorsque l'on supprime autant de lignes que n'en comporte le groupe, alors le groupe disparait complètement puisque l'on demande au programme de supprimer toute les lignes de ce groupe. Dans mon exemple les 3 premiers groupes comportent chacun 10 lignes, et si je demande de supprimer les 5 premières ET dernières lignes, alors ces 3 premiers groupes disparaissent et je n'affiche que le dernier groupe. Or je veux absolument conserver TOUS les groupes à l'écran.

Sa me gène un peu de faire disparaitre un groupe sans en avertir l'utilisateur. Par contre si on demande de supprimer plus de lignes que n'en compte le groupe alors on a bien le message d'alerte qui surgit et qui avertit que les groupes concernés ne seront pas touchés par aucune modification.

Je ne pense pas que sa soit une grande modification, mais pourrais tu faire en sorte que lorsque l'on demande de supprimer autant de lignes que n'en compte un groupe alors on a le même message d'alerte qui nous avertis que ce groupe ne sera pas modifié. Le même message d'alerte et les mêmes conséquences que lorsque l'on veut supprimer plus de lignes que n'en compte un groupe.

Sa serait sympa pour perfectionner le programme. Il y a peu de chances que ce cas se produise, mais j'aime autant me laisser ce degré de liberté en plus si sa n'engendre pas de grosses modifications du programme.


En tout état de cause, merci pour avoir rectifié la fonction "différence" qui m'embarrassait depuis un moment^^


Bien cordialement,

André
3
SERIEUXETCOOL Messages postés 336 Date d'inscription dimanche 3 avril 2011 Statut Membre Dernière intervention 12 juin 2012 1
27 sept. 2011 à 23:04
Bonsoir Ucfoutu, le Forum...

Alors comme convenu me voici de retour pour exprimer mon rapport sur la dernière version du code proposée par Ucfoutu.

Conclusion : SA MARCHE !

Voila j'ai passé un bon moment à éprouver ton code et à chercher la petite bête...mais rien n'y fait le code résiste. Ce qui est une excellente nouvelle en somme.

Donc au bout d'un moment j'ai admis que c'était validé. Je vais mettre sa application avec mon cas de figure (sa va me prendre un peu de temps pour tout remplacer) et ensuite je pourrais comparer l'exécution de ce nouveau code à l'ancien code que tu m'avais proposé et qui fonctionnait très bien lui aussi (sauf pour les différences). Alors la seulement je serais apte à certifier que ton code est top. Mais j'en suis déjà convaincu, car vu les tests que je lui ai fait subir sa suffira largement^^

Néanmoins passer d'un exemple d'application simple (cas des poissons) à mon application personnelle (gestions de multiples colonnes, milliers de lignes à traiter, nature des données différentes,...) sa peut créer des surprises. On ne sais jamais^^

Pour l'heure on va pouvoir clore définitivement cette longue discussion qui nous à tout de même permis d'aboutir à un super petit bout de code !! (C'est mon avis perso).

Sans ton aide, Ucfoutu, je n'y serais pas parvenu. Et je ne peux que te remercier encore une fois de plus ! Sincèrement MERCI. Je peux toujours poursuivre le développement de ma Macro qui est de plus en plus robuste et efficace.

Pour tous les nouveau qui tomberaient sur ce post, j'ai la flême de faire un rapide résumer sur l'application de code. Le mieux, c'est que vous repartiez du début de la discussion pour comprendre. Sinon c'est chaud^^

Je post ici la version absolument définitive du code qui fonctionne parfaitement :

Option Explicit

Sub DIFFERENCE_SUPPRESSION_MOYENNE()

    Dim colonne_groupes As String, feuille_donnees As String
    Dim a_partir_ligne As Long, Minimum_devant_rester As Long, ecreter_de_combien As Long
    Dim depart As Double
    Dim col_groupes As Variant, colonnes_moyennes As Variant, colonnes_diff As Variant

  ' ==============================c'est ici que tu définis les paramètres ==============================================
  feuille_donnees = "MACRO" ' <<<<<========= le nom exact de la feuille contenant les groupes à traiter
  colonne_groupes = "A" '<<<<<<<======== ici : la colonne des groupes
  a_partir_ligne = 2 '<<<<<<============ ici : la ligne où commencent les groupes
  ecreter_de_combien = 2 '<<<<======= ici : de combien écréter en haut et en bas de chaque groupe
  Minimum_devant_rester = 1 '<<<<======= ici : écrêtement si ce minimum après écrêtement sinon non
  depart = 16.05 ' <<<<<===== la valeur de ton choix, sous forme avec . comme séparateur décimal si utilisé
  colonnes_moyennes = Array("C", "D", "E") '<<<<=== ici : énumération des colonnes où faire la moyenne ("") si aucune
  colonnes_diff = Array("B") ' <<<<<===== ici : la SEULE  colonne où faire ta "différences" ("") si aucune
  col_groupes = Array(colonne_groupes) ' ---->> ça, c'est pour le code. Ne t'en préoccupe pas.
  '=====================================================================================================================


  ' ________________________________________ les gardes-fou, maintenant ________________________________________________

  If ActiveSheet.Name <> feuille_donnees Then
    MsgBox "cette opération ne doit être lancée que si la feuille " & feuille_donnees & " est la feuille active"
    Exit Sub
  End If
  If verif(col_groupes, colonne_groupes, a_partir_ligne, "colonne des groupes") = False Then Exit Sub
  If verif(colonnes_moyennes, colonne_groupes, a_partir_ligne, "colonne à moyenne") = False Then Exit Sub
  If verif(colonnes_diff, colonne_groupes, a_partir_ligne, "colonne à différence") = False Then Exit Sub
  '_____________________________________________________________________________________________________________________


  ' ------------------------------ si l'exécution atteint ce point, c'est que tout est cohérent ------------------------
  ' ------------------------------------------------ on y va donc ------------------------------------------------------
  ' --------------------------------------------- en écrêtant d'abord --------------------------------------------------
   epurer colonne_groupes, a_partir_ligne, ecreter_de_combien, Minimum_devant_rester, colonnes_diff, depart
  ' ---------------------------------puis en traitant le reste (écart(s) et moyenne(s)) --------------------------------
  MsgBox "On vient d'épurer"
  on_amenage colonne_groupes, a_partir_ligne, colonnes_moyennes, colonnes_diff
  '---------------------------------------------------------------------------------------------------------------------

End Sub

Public Sub epurer(ByVal col As String, ByVal ligne As Integer, ByVal nb As Integer, ByVal mini As Integer, ByVal dif, ByVal deb As Single)
  
  Dim plage As Range, plage_a_supp As Range
  Dim n As Long, i As Long, j As Long
  Dim ahah As Double
  Dim msg As String
   
   n = Range(col & Rows.Count).End(xlUp).Row
   msg = ""
   For i = ligne + 1 To n + 1
     If Range(col & i).Value = Range(col & i - 1).Value Then
       If plage Is Nothing Then
         Set plage = Union(Range(col & i - 1), Range(col & i))
       Else
         Set plage = Union(plage, Range(col & i))
       End If
     ElseIf Not plage Is Nothing Then
          Dim R As Range
          If dif(0) <> "" Then
            For Each R In plage.Rows
               ahah = Cells(plage.Row + plage.Rows.Count - 1, dif(0)).Value
              Cells(R.Row, dif(0)).Value = ahah - deb
            Next
          End If
          If dif(0) <> "" Then deb = ahah
         If plage.Rows.Count > (nb * 2) + mini - 1 Then
           For j = 1 To nb
             If plage_a_supp Is Nothing Then
               Set plage_a_supp = Union(plage(1, 1), plage(plage.Rows.Count, 1))
             Else
               Set plage_a_supp = Union(plage_a_supp, plage(j, 1), plage(plage.Rows.Count + 1 - j, 1))
             End If
           Next
           Set plage = Range(col & i)
           If Range(col & i).Value = "" Then Exit For
          Else
            msg = msg & " - " & plage(1, 1).Value
            Set plage = Nothing
            If Range(col & i).Value = "" Then Exit For
          End If
      Else
        msg = msg & " - " & Cells(i - 1, 1).Value
     End If
   Next
   If Not plage_a_supp Is Nothing Then
     plage_a_supp.Rows.EntireRow.Delete
   End If
   If msg <> "" Then
     MsgBox "les groupes suivants, d'un nombre non suffisant, " & _
     "n'ont pas été traités " & vbCrLf & Mid(msg, 3)
   End If

End Sub

Public Sub on_amenage(ByVal col As String, ByVal ld As Integer, ByVal moy, ByVal dif)
 
 Dim deb As Long, n As Long, i As Long, combien As Long, k As Long, j As Long
 Dim plage As Range, plage_a_supp As Range
 Dim elmt As Variant
 
 deb = Range(col & ":" & col).Column
 n = Range(col & Rows.Count).End(xlUp).Row
 For i = ld + 1 To n + 1
   If Range(col & i).Value = Range(col & i - 1).Value Then
     If plage Is Nothing Then
       Set plage = Union(Range(col & i - 1), Range(col & i))
     Else
       Set plage = Union(plage, Range(col & i))
     End If
   Else
     If Not plage Is Nothing Then
       combien = plage.Rows.Count
       If combien > 1 Then
         If moy(0) <> "" Then
           For Each elmt In moy
             k = Range(elmt & ":" & elmt).Column - deb + 1
             
             plage.Cells(1, k) = WorksheetFunction.Average(plage.Columns(k))
           Next
         End If
         For j = 2 To combien
             If plage_a_supp Is Nothing Then
               Set plage_a_supp = plage(j, 1)
             Else
               Set plage_a_supp = Union(plage_a_supp, plage(j, 1))
             End If
          Next
       End If
       Set plage = Nothing
     End If
   End If
 Next
 If Not plage_a_supp Is Nothing Then
   plage_a_supp.Rows.EntireRow.Delete
 End If

End Sub

Public Function verif(cols, colonne_groupes, a_partir_ligne, descr As String) As Boolean
  
  Dim derLig As Long
  Dim plage As Range
  Dim elmt As Variant
  
  verif = True
  If cols(0) = "" Then Exit Function
  derLig = Range(colonne_groupes & Rows.Count).End(xlUp).Row
  For Each elmt In cols
    Set plage = Nothing
    On Error Resume Next
    Set plage = Range(elmt & a_partir_ligne & ":" & elmt & derLig).SpecialCells(xlCellTypeBlanks)
    If Not plage Is Nothing Then
      MsgBox "la " & descr & " " & elmt & " contient une cellule vide - Corrigez puis relancez, s'il vous plait !"
      verif = False
      On Error GoTo 0
    End If
  Next
  
End Function



Un grand merci encore une fois Ucfoutu. Je vais tâcher de te laisser tranquille un peu quand même^^. Mais j'ai apprécié ton aide, ainsi que ta rigueur et ta capacité de raisonnement. Nice !


Bien cordialement,

André

Ps : SUPER la fonction que tu as intégré à la dernière minute (celle qui permet de définir le nombre de lignes minimum restant par groupe après écrêtement). J'adore cette fonction^^
3

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

Posez votre question
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 212
1 août 2011 à 20:09
trois questions :
1) cette moyenne doit-elle être calculée sur les valeurs :
- avant suppression (auquel cas on peut inclure du code dans l'existant)
ou
- après suppression et alors il vaudra mieux ne pas inclure dans le code (bien qu'on ourrait le faire, mais sans gain de temps, bien au contraire), mais in fine, en rebouclant.
2) Pourquoi dans un autre fichier ? écrire dans une autre feuille du classeur en cours serait plus économique.
3)Je comprends bien en ce qui concerne la moyenne de la colonne A, mais quelles valeurs conserver pour les 2 autres colonnes, dans ce cas ? (celles de quelle ligne ?).


____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
0
SERIEUXETCOOL Messages postés 336 Date d'inscription dimanche 3 avril 2011 Statut Membre Dernière intervention 12 juin 2012 1
1 août 2011 à 20:40
Re-Bonsoir Ucfoutu,

Alors première réponse :

Je pense que tu dois parler de la suppression des lignes qui interviennent dans le code déjà existant et non de la suppression des lignes qui restent et qui servent à faire la moyenne.

Dans l'ordre sa donne sa : J'ai une base de données, je commence par supprimer certaines lignes qui ne me servent pas du tout. Un fois ces lignes supprimées, j'obtiens une nouvelle base de données légèrement plus courte en termes de lignes. Sur cette dernière je procède à la moyenne de chaque série d'entier sans prendre en compte les lignes précédemment supprimées. Une fois ces moyennes faites, je supprime alors toutes les lignes restantes qui auront servies à calculer les moyennes puis je ne laisse seulement qu'une seule ligne associée à chaque groupe d'entier. Au final, ma base de données ne comporte que des lignes moyennées et une seule pour chaque entier. Rien de plus.

Réponse deux :

Je ne souhaite créer ni deuxième fichier, ni deuxième feuille excel. Je souhaite travailler UNIQUEMENT sur la même feuille en cour. Sa deviendrais trop compliqué pour moi. Alors j'aimerais que les opération s'éxécutent sur une seule et même feuille. On supprime certaines ligne/On fait les moyennes résultantes/et on remplace tout par uniquement les valeurs moyennées. La base de données initiale est en quelque sorte travaillée pour ne garder que ce dont j'ai besoin. Le reste est détruit volontairement.

Réponse trois :

En fait la première colonne (A) contient les groupe d'entier. C'est l’indicateur qui me permet d'identifier les bon numéros de lignes et de les travailler. En vis à vis sur les colones B,C,D...Se trouvent les vraies données à traiter, qui seront traitées en même tps que la colonne A.
Je ne sais pas quelle colonne utiliser encore de manière définitive. Mais admettons que l'indicateur (groupe d'entier naturel) soit dans dans la colonnes A et les données associées sur la colonne B,D, et E,F. Comme sa j'aurais le modèle pour 2 colonnes séparées et 2 colonnes jointes. Je saurais me débrouiller pour adapter. Donc en fait le calcul qui sera fait sur la colonne A et sur les lignes de A sera fait simultanément sur les colonnes B,D,E,F et sur les même lignes.

Suis-je clair ?

Je file manger. Je reviens après pour plus d'infos si besoin.

Merci Ucfoutu
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 212
1 août 2011 à 21:10
Tes réponses 1 et 2 sont claires.
Ta réponse 3 ne l'est pas.
Donne un exemple sur quelques lignes du même groupe, en montrant ce que tu as dans les autres colonnes et le résultat final :
Exemple avec 2 groupes "résiduels" et 3 colonnes (ce n'est qu'un exemple)
colonne A Colonne B colonne C
1-------- 3-------- 5--------
1-------- 4-------- 8--------
2-------- 9-------- 6--------
2-------- 3-------- 1--------
Que veux-tu comme résultat final (remplace les ?)
1-------- ?- ------ ?--------
2-------- ?- ------ ?--------


____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
0
SERIEUXETCOOL Messages postés 336 Date d'inscription dimanche 3 avril 2011 Statut Membre Dernière intervention 12 juin 2012 1
1 août 2011 à 21:34
Voila la réponse à ton exemple pour ce cas ci.

Exemple avec 2 groupes "résiduels" et 3 colonnes (ce n'est qu'un exemple)

colonne A Colonne B colonne C
1-------- 3-------- 5--------
1-------- 4-------- 8--------
2-------- 9-------- 6--------
2-------- 3-------- 1--------

Le Résulat sera alors idiqué comme suis :

1-------- (3+4)/2-- (5+8)/2--
2-------- (9+3)/2-- (6+1)/2--


Et voila^^
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 212
1 août 2011 à 21:39
Plus rien n'est maintenant dans l'ombre ===>> je te propose un code demain matin.
Bonne nuit.


____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
0
SERIEUXETCOOL Messages postés 336 Date d'inscription dimanche 3 avril 2011 Statut Membre Dernière intervention 12 juin 2012 1
1 août 2011 à 21:44
Pas de soucis Ucfoutu.

Demain je bosserais mais c'est avec plaisir et impatience que je viendrais voir ce petit bout de code le soir.

Bonne soirée à tous.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 212
2 août 2011 à 11:01
Bon,

Je viens d'établir le principe, appliqué pour l'instant à la seule colonne B (pour la moyenne)
J'ai oublié une question :
Quelles sont les colonnes à "moyenner" ainsi ? (de sorte à ce que je fasse la sous-boucle nécessaire)

____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 212
2 août 2011 à 11:37
Si les colonnes en cause sont toutes à droite de la colonne A et juxtaposées, seul leur nombre m'intéresse.
Si non juxtaposées ===>> le numéro de ces colonnes me sera bien évidemment nécessaire (encore que je me demanderais alors quoi mettre de valable dans les autres colonnes !)
Une autre chose doit être claire : les colonnes concernées ne doivent contenir que des nombres, d'une part, et aucune colonne parmi elles, pour chacun des groupes, ne devra rien contenir (au moins une valeur par groupe).
Je suis maintenant totalement prêt et n'attends que ta réponse pour finir (en un "coup de cuillère à pot").


____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
0
SERIEUXETCOOL Messages postés 336 Date d'inscription dimanche 3 avril 2011 Statut Membre Dernière intervention 12 juin 2012 1
2 août 2011 à 20:10
Bonsoir Ucfoutu,

Alors il y a deux code possibles.

-Le premier code très simple est le code qui permet de résoudre la petite base de données du fichier que j'ai déposé dans les posts précédents. C'est ma base de données à titre d'exemple pour vérifier de manière simple que tout fonctionne. Donc tu as simplement à supprimer des lignes (ce que ton code initial fait déjà très bien) et faire la moyenne de chaque groupe d'entier naturel. La base de données comporte deux colonnes A et B. Cette base de données fort simple tu la connais déjà.

Par contre, cette base de données (qui est présente directement dans le code vba) ne sert qu'a titre d'exemple. Le premier code sert de validation. Voila pourquoi je te disais que j'aimerais avoir la version 2 du code qui sois adapté pour ma vrai base de données qui comporte plusieurs milliers de lignes et dont les données sont situées de manière un peu moins agréable.

Ma vrai base de données se comporte comme suis :

- L'indicateur, autrement dit la série comportant les groupes d'entier allant de 0 à X (X étant un entier variable pour chaque base de données); chaque groupe d'entier étant répété un certains nombre de fois et de manière aléatoire se trouve en colonne B et le premier 0 de la série démarre à la ligne 5. Donc dans ma vrai base de données, le premier 0 est de coordonnées ( Ligne 5, colonne B) alors que dans ma base de données pour exemple le premier 0 se trouve très simplement en (Ligne 1, colonne A).
Ensuite mes données démarrent toutes elles aussi de la ligne 5 et sont réparties sur les colonnes C,D,E ET AUSSI O,P

Voila pour la répartitions des colonnes. Par contre il y a une petite subtilité sur la colonne C. Sur la colonne C, au lieu de faire la moyenne comme pour toute les autres colonnes, je souhaite simplement faire une différence de valeurs. C'est à dire que pour chaque groupe d'entier, au lieu de faire la moyenne, je fais simplement afficher la différence entre le contenu de la cellule la plus en bas ET le contenu de la première cellule associée à l'entier naturel. La logique de programmation est la même pour la colonne C ou les autres. Sauf que le calcul est différent. On ne fait pas la moyenne de chaque valeur pour chaque groupe d'entier mais simplement une différence entre la dernière cellule du groupe et la première. (Ne pas oublier que l'on supprime définitivement les lignes au tout début du programme, et une fois les lignes supprimées alors on commence à faire la moyenne ou la différence). On ne tiens donc PAS COMPTE des lignes précédemment supprimées.

-Caque cellule est OBLIGATOIREMENT remplis d'une valeur. Donc aucun risque d'avoir de cellules vide ou autres.

-Voici un lien ou j'ai mis en photo le début de ma vrai table. Tu auras un visuel et tu captera directement mieux.

http://www.cijoint.fr/cjlink.php?file=cj201108/cijACDq2Xj.jpg

Mes données sont en rouge. Elles démarrent toutes en ligne 5 et se trouvent en colonne B,C,D,E ET O,P. La colonne C est spéciale car on fait simplement une différence entre les 2 valeurs extrèmes.

Pense tu t'en sortir avec tout sa ?

Je suis pour des infos complémentaires.

Pour rappel, il est souhaitable de proposer un premier code qui fonctionne bien avec une base de données très simple (type celle qui est présente sur le code posté sur ce site) Et ensuite de l'étendre à un vrai type de base de données.

Ps : En un coup de cuillère à pot dis tu ??? Ben bonne chance pour sa^^. Je te laisse même 5 coups si tu veux ;)
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 212
2 août 2011 à 21:03
Pense tu t'en sortir avec tout sa ?

Oui et sans aucun doute, mais à la seule condition que ne subsiste aucune ambiguïté !
Relis mon message précédent en ce qui concerne certains aspects.
Puis, relis-toi lorsque tu dis :
Ensuite mes données démarrent toutes elles aussi de la ligne 5 et sont réparties sur les colonnes C,D,E ET AUSSI O,P

et alors ? Qu'y a-t-il dans les colonnes F à O ? et quand je "traite" (que ce soit par moyenne ou par "différence") : que dois-je y mettre ?
Tu as vu ma méthode d'exemple plus haut ?
A toi de m'en faire un plus complet et répondant exactement à tes besoins (toutes les collonnes, de A à P)

____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 212
2 août 2011 à 22:15
J'ai par exemple examiné l'image du groupe 0 de ton fichier.
Une question saute aux yeux :
Que fait-on des données situées dans les colonnes G, H, L et N ? Laquelle conserve-t-on (puisqu'il ne restera qu'une ligne, selon ton voeu) ?
Il va te falloir être ici TRES précis.


____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
0
SERIEUXETCOOL Messages postés 336 Date d'inscription dimanche 3 avril 2011 Statut Membre Dernière intervention 12 juin 2012 1
2 août 2011 à 22:45
Ah oui en effet je n'ai pas été très précis sur ce qui se passais entre les colonnes F à N.

Alors pour répondre à ta question, les colonnes F à O sont vides. Rien n'y est affecté. En fait elles vont se remplir par la suite un fois que la suppression des lignes, la moyenne, et la différence sera faite.

Donc les seules colonnes contenant des données au débute sont BCDE, O,P. Je te glisse un exemple concernant la disposition de ma vrai base de données, ainsi que le résultat voulu.

-----ColA/ColB/ColC/ColD/ColE/ColF/ColG/ColH/.../ColL/ColM/ColN/ColO/ColP
Lg1----------------------------------------------------------------------
Lg2-------MÉLANGE DE CELLULES VIDES PLUS DONNÉES A NE PAS TOUCHER--------
Lg3----------------------------------------------------------------------
Lg4----------------------------------------------------------------------
Lg5----&----0----0----0----0----&----&----&------&----&----&----0----0---
Lg6----&----0----1----7----3----&----&----&------&----&----&----2----1---
Lg7----&----0----4----3----3----&----&----&------&----&----&----9----2---
Lg8----&----1----2----2----7----&----&----&------&----&----&----2----9---
Lg9----&----1----7----8----4----&----&----&------&----&----&----3----6---
Lg10---&----2----1----3----9----&----&----&------&----&----&----8----2---
Lg11---&----2----0----0----0----&----&----&------&----&----&----4----2---
Lg12---&----2----1----7----3----&----&----&------&----&----&----2----1---
Lg13---&----2----4----3----3----&----&----&------&----&----&----9----2---
Lg14---&----2----2----2----7----&----&----&------&----&----&----2----9---
Lg15---&----3----7----8----4----&----&----&------&----&----&----3----6---
Lg16---&----3----1----3----9----&----&----&------&----&----&----8----2---
Lg17---&----3----1----3----9----&----&----&------&----&----&----8----2---
Lg18---&----3----0----0----0----&----&----&------&----&----&----4----2---
Lg19---&----3----1----7----3----&----&----&------&----&----&----2----1---
Lg20---&----3----10---3----3----&----&----&------&----&----&----9----2---

Le résultat que je souhaite obtenir :

-----ColA/ColB/ColC/ColD/ColE/ColF/ColG/ColH/.../ColL/ColM/ColN/ColO/ColP
Lg1----------------------------------------------------------------------
Lg2-------MÉLANGE DE CELLULES VIDES PLUS DONNÉES A NE PAS TOUCHER--------
Lg3----------------------------------------------------------------------
Lg4----------------------------------------------------------------------
Lg5----&----0----4---3,3---2----&----&----&------&----&----&---3,6---1---
Lg6----&----1----5----5---5,5---&----&----&------&----&----&---2,5--7,5--
Lg7----&----2----1----3---4,4---&----&----&------&----&----&----5---3,2--
Lg8----&----3----3----4---4,6---&----&----&------&----&----&---5,6--2,5--

Voila en gros ce que je cherche à obtenir. (Dsl si certains calculs sont faux, je ne pense pas, mais je n'ai pas revérifié. Je suis crevé j'avoue). Ici le symbole "&" veut dire que la cellule ne contient rien. Elle est vierge comme à l'ouverture d'un nouveau classeur Excel.

Évidement, il faut garder en tête que la suppression de certaines lignes à déjà été faite. Après suppression des lignes, on obtient la base de données ci-dessus. Mais les lignes ont déjà été supprimées et elles ne nous intéressent pas du tout. Simple détail.

Et voila. Tu remarqueras que je ne touche pas aux cellules présentes dans les colonnes F,G,H,I,J,K,L,M,N. Les cellules sont vides, et elles le restent à la fin. J'espère que sa ne te posera pas de problème pour la suite.

Bonne soirée, et encore merci à toi Ucfoutu d'accepter de bien vouloir te pencher sur mon cas. J'apprécie ;)

PS : J'ai mis des nombre entier dans ma table, mais c'est pour un soucis de simplification bien entendu.
0
SERIEUXETCOOL Messages postés 336 Date d'inscription dimanche 3 avril 2011 Statut Membre Dernière intervention 12 juin 2012 1
2 août 2011 à 22:55
Donc je le redis, les colonnes de [F à N] Sont totalement vide de base. Elles se remplissent UNIQUEMENT après avoir calculé la moyenne des groupes et fait la différence des groupes pour la colonne C. Donc sa n'intervient pas dans ce code la. Il faut considérer ces cellules comme vierge, et les laisser vierges.

Je remet une image non faussée. Bien vu^^

Voici le lien :

http://www.cijoint.fr/cjlink.php?file=cj201108/cijjuhYb0i.jpg
[ http://www.cijoint.fr/cjlink.php?file=cj201108/cijjuhYb0i.jpg]
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 212
3 août 2011 à 07:45
Ton lien/fichier est inaccessible et je ne peux le voir.

J'avais déjà fait (en un coup de cuillère à pot) et testé le code (avec différenciation entre moyenne et différence). Tout cela marche bien.
Il ne me reste plus qu'à partir de la colonne B et pas A. Ce qui ne devrait pas représenter un obstacle et que je ferai donc ce soir (il me faut accomapgner aujourd'hui mon petit-fils à la pêche).


____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 212
3 août 2011 à 11:15
Bon...
Mon petit-fils s'est réveillé un peu tard ===>>>
Voilà ta procédure (à lancer une fois terminée l'autre) :
Private Sub on_amenage()
 Dim lesquels As Integer
 lesquels = 14
 n = Range("B" & Rows.Count).End(xlUp).Row
 Dim plage As Range, plage_a_supp As Range, combien As Integer
   For i = 6 To n + 1
     If Range(" B" & i).Value = Range("B" & i - 1).Value Then
       If plage Is Nothing Then
         Set plage = Union(Range("B" & i - 1), Range("B" & i))
     Else
         Set plage = Union(plage, Range("B" & i))
       End If
     Else
       If Not plage Is Nothing Then
         combien = plage.Rows.Count
         If combien > 1 Then
            For k = 2 To lesquels + 1
              Select Case k
                Case 3, 14, 15
                  plage.Cells(1, k) = WorksheetFunction.Average(plage.Columns(k))
                Case 2
                  plage.Cells(1, k).Value = plage(plage.Rows.Count, k).Value - plage(1, k).Value
              End Select
            Next
            For j = 2 To combien
               If plage_a_supp Is Nothing Then
                 Set plage_a_supp = plage(j, 1)
               Else
                 Set plage_a_supp = Union(plage_a_supp, plage(j, 1))
               End If
            Next
         End If
         Set plage = Nothing
       End If
     End If
   Next
    
   If Not plage_a_supp Is Nothing Then
     plage_a_supp.Rows.EntireRow.Delete
   End If
End Sub

Je te laisse transformer seul la première pour qu'elle démarre à la ligne 5 et en colonne B ou tu veux que je te la réécrive ?
Tu dis.



____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
0
SERIEUXETCOOL Messages postés 336 Date d'inscription dimanche 3 avril 2011 Statut Membre Dernière intervention 12 juin 2012 1
3 août 2011 à 21:58
Bonsoir Ucfoutu,

J'ai pu tester ton deuxième code pour la moyenne et pour la différence.

Et ben sa marche de manière superbe ! Sa fait vraiment plaisir de voir que le programme fait ce qu'on voulait lui dire de faire^^

Du coup j'ai commencé à monter la macro général et je me suis rendu compte d'une petite chose. Grosse erreur de ma part !!!

En fait c'est encore plus simple que ce que je t'ai demandé de faire^^. Ma base de données initiale commence bien en ligne 1 !!! Et elle est étalée sur la colonne A, B, C, D,E,F,G

C'est seulement après avoir appliqué le code 1 (suppression des lignes) puis le code 2 (moyenne et différence) que je commence à insérer les colonnes vides, et à créer le décalage en ligne 5.

Vraiment dsl, la j'ai merdé. Je passe tellement de temps sur ce code, que je finis par m'y perdre moi même. J'ai bien vérifié, ma logique est la suivante :

-j'importe mes données sous excels. Elles démarrent en A1 -> GX
-Je supprime les lignes avec ton code 1 qui fonctionne parfaitement
-J'applique le code 2 qui fait les moyennes et les différences
-Ensuite seulement j'insère des colonnes vide et des lignes

Je récapépète donc :

Ma basse de données initiale commence de la ligne 1 jusqu'à un nombre indéterminé. Les données remplissent les colonnes A, B, C, D, E, F, G.
Et les données restent en ligne 1 et colonne 1. C'est seulement après que je fais la mise en forme avec les lignes et colonnes.

Vraiment dsl Ucfoutu. En gros ton code 1 reste inchangé et c'est ton code 2 qui doit être modifié légèrement de manière à le faire travailler en A1 jusqu'à GX.

Excuse moi de l'erreur. Mais avec mon job d'été je ne peut plus être à 100% dans mon code général.

Ps : J'ai cherché à modifié ton code 2. J'ai vu qu'il falait changer le "i=6" en "i=2" puis tous les "B" en "A" mais sa marche plus ensuite. Donc j'aimerais que tu me le réécrive si possible.
Et au fait j'ai vu que les similitudes entre ton code 1 et ton code 2 sont flagrantes. Par curiosité, n'est pas possible de grouper le code 1 et 2 en une seule boucle ? Surtout que maintenant on travail toujours sur la colonne A1.
J'aimerais savoir la raison qui fait que l'on doit lancer le code 1 puis le code 2 et pas 1 ET 2 simultanément.
0
Rejoignez-nous