Extraction et classement de données

rhadamanthe

XLDnaute Junior
Bonjour,

J'ai des valeurs qui tombent tous les jours que je dois reporter dans un tableau bilan.

Il faut classer les valeurs par date, type et composé...d'où la difficulté!!!

Une âme charitable pour me donner un coup de main ? :eek:

Merci d'avance,

rhad
 

Pièces jointes

  • extraction.xls
    46 KB · Affichages: 57
  • extraction.xls
    46 KB · Affichages: 61
  • extraction.xls
    46 KB · Affichages: 62

JHA

XLDnaute Barbatruc
Re : Extraction et classement de données

Bonjour à tous,

Une solution par formule matricielle qui sera très lourde si tu as beaucoup de données, une solution VBA serait plus souple mais je suis incapable de la faire.

JHA
 

Pièces jointes

  • extraction.xls
    270 KB · Affichages: 57
  • extraction.xls
    270 KB · Affichages: 66
  • extraction.xls
    270 KB · Affichages: 63

Robert

XLDnaute Barbatruc
Repose en paix
Re : Extraction et classement de données

Bonsoir le fil, bonsoir le forum,

Une solution VBA, qui vient compléter la proposition de JHA, avec le code ci-dessous :
Code:
Option Explicit 'oblige à déclarer toutes les variables

Sub Macro1()
Dim r As Object 'déclare la variable r (onglet Result)
Dim ad As Range 'déclare la variable ad (Anciennes Données)
Dim o As Object 'déclare la variable o (Onglet)
Dim dl As Integer 'déclare la variable dl (Dernière Ligne)
Dim pl As Range 'déclare la variable pl (PLage)
Dim cel As Range 'déclare la variable cel (CELlule)
Dim li As Integer 'déclare la variable li (LIgne)
Dim col As Byte 'déclare la variable col (COLonne)

Set r = Sheets("result") 'définit l'onglet r
Application.ScreenUpdating = False 'masque les changements à l'écran

'*************************************************
'efface les anciennes données de l'onglet "result"
'*************************************************
Set ad = r.Range("A1").CurrentRegion 'définit la plage ad
If ad.Rows.Count > 2 Then 'condition : si le nombre de ligne de la plage ad est supérieur à 2
    Set ad = ad.Offset(2, 0).Resize(ad.Rows.Count - 2, ad.Columns.Count) 'redéfinit la plage ad (sans les deux premières lignes)
    ad.Clear 'efface la plage ad
End If 'fin de la condition

'********************************************************
'extraction des donnés des onglets vers l'onglet "result"
'********************************************************
For Each o In Sheets 'boucle 1 : sur tous les onglets du classeur
    If Not o.Name = r.Name Then 'condition 1 : si le nom de l'onglet n'est pas "result"
        dl = o.Cells(Application.Rows.Count, 1).End(xlUp).Row 'définit la dernière ligne éditée dl de la colonne 1 (=A)
        Set pl = o.Range("A2:A" & dl) 'définit la plage pl
        For Each cel In pl 'boucle 2 : sur toutes les cellules cel de la plage pl
            Select Case Application.WorksheetFunction.CountA(r.Columns(1)) 'agit en fonction du nombre de valeurs dans la colonne A de l'onglet r
                Case 0 'cas : aucune valeur
                    li = 3 'définit la ligne li
                Case Else 'tous les autres cas
                    'condition 2: si la valeur de la cellule n'existe pas dans la colonne 1 de l'onglet r
                    If r.Columns(1).Find(cel.Value, , xlFormulas, xlWhole) Is Nothing Then
                        'définit la ligne li (première cellule vide de la colonne A de l'onglet r)
                        li = r.Cells(Application.Rows.Count, 1).End(xlUp).Offset(1, 0).Row
                    Else 'sinon (si la cellule existe)
                        'définit la ligne li (ligne de la cellule trouvée)
                        li = r.Columns(1).Find(cel.Value, , xlFormulas, xlWhole).Row
                    End If 'fin de la condition 2
            End Select 'fin de l'action en fonction du nombre de valeurs dans la colonne A de l'onglet r
            col = r.Rows(2).Find(cel.Offset(0, 2).Value, , xlValues, xlWhole).Column 'définit la colonne col
            r.Cells(li, 1).Value = cel.Value 'place dans la cellule de la ligne li et de la colonne 1 la valeur de la cellule cel
            r.Cells(li, col) = cel.Offset(0, 3).Value 'place dans la cellule de la ligne li et de la colonne col la valeur en colonne D de la cellule cel
        Next cel 'prochaine cellule de la boucle 2
    End If 'fin de la condition 1
Next o 'prochain onglet de la boucle 1
'tri par ordre croissant sur la colonne A
r.Range("A3:K" & r.Cells(Application.Rows.Count, 1).End(xlUp).Row).Sort Key1:=r.Range("A3"), Order1:=xlAscending, Header:=xlNo, _
        OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, DataOption1:=xlSortNormal
Application.ScreenUpdating = True 'affiche les changements à l'écran
End Sub
Le fichier :
 

Pièces jointes

  • Radh_v01.xls
    41.5 KB · Affichages: 49

rhadamanthe

XLDnaute Junior
Re : Extraction et classement de données

Merci pour vos réponses !!!! :)

La technique matricielle de JHA est très intéressante, je ne pensais pas que c'était possible et ça me servira probablement dans d'autres cas plus léger :eek:...pour le cas présent, mes données sont nombreuses et s'étalent sur beaucoup de jours...ça risque donc d'être un peu lourd!

Concernant la méthode VBA de Robert, c'est top :D, ça limite le nombre de date en plus! Un petit bug néanmoins : il ne classe pas par méthode puis composés mais par composé : Il a donc un mauvais classement du composé ABC issu de la méthode 4224035 dans la méthode 4223321 qui apparaît avant! Est il possible de corriger ce souci ? :confused:

Au plaisir de vous lire,

rhad
 

Robert

XLDnaute Barbatruc
Repose en paix
Re : Extraction et classement de données

Bonjour le fil, bonjour le forum,

Ooopa Rhad je navet (si, si, dans ce cas on peut...) pas vu que le composé ABC était deux fois... J'ai modifié vite fait en rajoutant la ligne :

Code:
If r.Cells(1, col) <> cel.Offset(0, 1).Value Then col = 11 'si le type est différent, col =11 (colonne K)
Mais si ce n'est pas un cas unique (même composé pour plusieurs types), il faudra revoir le code plus sérieusement.
Le code modifié :
Code:
Option Explicit 'oblige à déclarer toutes les variables


Sub Macro1()
Dim r As Object 'déclare la variable r (onglet Result)
Dim ad As Range 'déclare la variable ad (Anciennes Données)
Dim o As Object 'déclare la variable o (Onglet)
Dim dl As Integer 'déclare la variable dl (Dernière Ligne)
Dim pl As Range 'déclare la variable pl (PLage)
Dim cel As Range 'déclare la variable cel (CELlule)
Dim li As Integer 'déclare la variable li (LIgne)
Dim col As Byte 'déclare la variable col (COLonne)

Set r = Sheets("result") 'définit l'onglet r
Application.ScreenUpdating = False 'masque les changements à l'écran
'*************************************************
'efface les anciennes données de l'onglet "result"
'*************************************************

Set ad = r.Range("A1").CurrentRegion 'définit la plage ad
If ad.Rows.Count > 2 Then 'condition : si le nombre de ligne de la plage ad est supérieur à 2
    Set ad = ad.Offset(2, 0).Resize(ad.Rows.Count - 2, ad.Columns.Count) 'redéfinit la plage ad (sans les deux premières lignes)
    ad.Clear 'efface la plage ad
End If 'fin de la condition

'********************************************************
'extraction des donnés des onglets vers l'onglet "result"
'********************************************************
For Each o In Sheets 'boucle 1 : sur tous les onglets du classeur
    If Not o.Name = r.Name Then 'condition 1 : si le nom de l'onglet n'est pas "result"
        dl = o.Cells(Application.Rows.Count, 1).End(xlUp).Row 'définit la dernière ligne éditée de la colonne 1 (=A)
        Set pl = o.Range("A2:A" & dl) 'définit la plage pl
        For Each cel In pl 'boucle 2 : sur toutes les cellules cel de la plage pl
            Select Case Application.WorksheetFunction.CountA(r.Columns(1)) 'agit en fonction du nombre de valeurs dans la colonne A de l'onglet r
                Case 0 'cas : aucune valeur
                    li = 3 'définit la ligne li
                Case Else 'tous les autres cas
                    'condition 2: si la valeur de la cellule n'existe pas dans la colonne 1 de l'onglet r
                    If r.Columns(1).Find(cel.Value, , xlFormulas, xlWhole) Is Nothing Then
                        'définit la ligne li (première cellule vide de la colonne A de l'onglet r)
                        li = r.Cells(Application.Rows.Count, 1).End(xlUp).Offset(1, 0).Row
                    Else 'sinon (si la cellule existe)
                        'définit la ligne li (ligne de la cellule trouvée)
                        li = r.Columns(1).Find(cel.Value, , xlFormulas, xlWhole).Row
                    End If 'fin de la condition 2
            End Select 'fin de l'action en fonction du nombre de valeurs dans la colonne A de l'onglet r
            col = r.Rows(2).Find(cel.Offset(0, 2).Value, , xlValues, xlWhole).Column 'définit la colonne col
            If r.Cells(1, col) <> cel.Offset(0, 1).Value Then col = 11 'si le type est différent, col =11 (colonne K)
            r.Cells(li, 1).Value = cel.Value 'place dans la cellule de la ligne li et de la colonne 1 la valeur de la cellule cel
            r.Cells(li, col) = cel.Offset(0, 3).Value 'place dans la cellule de la ligne li et de la colonne col la valeur en colonne D de la cellule cel
        Next cel 'prochaine cellule de la boucle 2
    End If 'fin de la condition 1
Next o 'prochain onglet de la boucle 1
'tri par ordre croissant sur la colonne A
r.Range("A3:K" & r.Cells(Application.Rows.Count, 1).End(xlUp).Row).Sort Key1:=r.Range("A3"), Order1:=xlAscending, Header:=xlNo, _
        OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, DataOption1:=xlSortNormal
Application.ScreenUpdating = True 'affiche les changements à l'écran
End Sub
Le fichier :
 

Pièces jointes

  • Radh_v02.xls
    42.5 KB · Affichages: 49

rhadamanthe

XLDnaute Junior
Re : Extraction et classement de données

Merci Robert pour la réponse rapide!!! :)

Néanmoins, je suis embêté car dans la situation présente, il y a redondance au niveau des noms des composés avec des types différents. Aussi, je crains que la solution proposée ne soit acceptable que pour l'exemple. :(

Est il possible d'avoir la modification plus sérieuse ? :confused:
 

Robert

XLDnaute Barbatruc
Repose en paix
Re : Extraction et classement de données

Bonsoir le fil, bonsoir le forum,

La Version 3 corrigée. Le code :
Code:
Option Explicit 'oblige à déclarer toutes les variables


Sub Macro1()
Dim r As Object 'déclare la variable r (onglet Result)
Dim ad As Range 'déclare la variable ad (Anciennes Données)
Dim o As Object 'déclare la variable o (Onglet)
Dim dl As Integer 'déclare la variable dl (Dernière Ligne)
Dim pl As Range 'déclare la variable pl (PLage)
Dim cel As Range 'déclare la variable cel (CELlule)
Dim li As Integer 'déclare la variable li (LIgne)
Dim rc As Range 'déclare la recherche rc (ReCherche)
Dim pa As String 'déclare la variable pa (Première Adresse)
Dim col As Byte 'déclare la variable col (COLonne)

Set r = Sheets("result") 'définit l'onglet r
Application.ScreenUpdating = False 'masque les changements à l'écran

'*************************************************
'efface les anciennes données de l'onglet "result"
'*************************************************
Set ad = r.Range("A1").CurrentRegion 'définit la plage ad
If ad.Rows.Count > 2 Then 'condition : si le nombre de ligne de la plage ad est supérieur à 2
    Set ad = ad.Offset(2, 0).Resize(ad.Rows.Count - 2, ad.Columns.Count) 'redéfinit la plage ad (sans les deux premières lignes)
    ad.Clear 'efface la plage ad
End If 'fin de la condition

'********************************************************
'extraction des donnés des onglets vers l'onglet "result"
'********************************************************
For Each o In Sheets 'boucle 1 : sur tous les onglets du classeur
    If Not o.Name = r.Name Then 'condition 1 : si le nom de l'onglet n'est pas "result"
        dl = o.Cells(Application.Rows.Count, 1).End(xlUp).Row 'définit la dernière ligne éditée de la colonne 1 (=A)
        Set pl = o.Range("A2:A" & dl) 'définit la plage pl
        For Each cel In pl 'boucle 2 : sur toutes les cellules cel de la plage pl
            Select Case Application.WorksheetFunction.CountA(r.Columns(1)) 'agit en fonction du nombre de valeurs dans la colonne A de l'onglet r
                Case 0 'cas : aucune valeur
                    li = 3 'définit la ligne li
                Case Else 'tous les autres cas
                    'condition 2: si la valeur de la cellule n'existe pas dans la colonne 1 de l'onglet r
                    If r.Columns(1).Find(cel.Value, , xlFormulas, xlWhole) Is Nothing Then
                        'définit la ligne li (première cellule vide de la colonne A de l'onglet r)
                        li = r.Cells(Application.Rows.Count, 1).End(xlUp).Offset(1, 0).Row
                    Else 'sinon (si la cellule existe)
                        'définit la ligne li (ligne de la cellule trouvée)
                        li = r.Columns(1).Find(cel.Value, , xlFormulas, xlWhole).Row
                    End If 'fin de la condition 2
            End Select 'fin de l'action en fonction du nombre de valeurs dans la colonne A de l'onglet r
            Set rc = r.Rows(1).Find(cel.Offset(0, 1).Value, , xlValues, xlWhole) 'définit la recherche rc (recherche le type dans la lige 1)
            If Not rc Is Nothing Then 'si il existe au moins une occurrence trouvée
                pa = rc.Address 'définit l'adresse de la premnière occurrence trouvée
                Do 'exécute
                    'si la cellule en dessous de l'occurrence trouvée correspond à la cellule en colonne C de cel
                    'définit la colonne col, sort de la boucle
                    If rc.Offset(1, 0) = cel.Offset(0, 2).Value Then col = rc.Column: Exit Do
                    Set rc = r.Rows(1).FindNext(rc) 'redéfinit la recherche rc (occurrence suivante)
                Loop While Not rc Is Nothing And rc.Address <> pa 'boucle tantn qu'il existe des occurrences ailleurs qu'en pa
            End If
            r.Cells(li, 1).Value = cel.Value 'place dans la cellule de la ligne li et de la colonne 1 la valeur de la cellule cel
            r.Cells(li, col) = cel.Offset(0, 3).Value 'place dans la cellule de la ligne li et de la colonne col la valeur en colonne D de la cellule cel
        Next cel 'prochaine cellule de la boucle 2
    End If 'fin de la condition 1
Next o 'prochain onglet de la boucle 1
'tri par ordre croissant sur la colonne A
r.Range("A3:K" & r.Cells(Application.Rows.Count, 1).End(xlUp).Row).Sort Key1:=r.Range("A3"), Order1:=xlAscending, Header:=xlNo, _
        OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, DataOption1:=xlSortNormal
Application.ScreenUpdating = True 'affiche les changements à l'écran
End Sub
Le fichier :
 

Pièces jointes

  • Radh_v03.xls
    44.5 KB · Affichages: 40

rhadamanthe

XLDnaute Junior
Re : Extraction et classement de données

Merci Robert.

J'ai noté un petit bug car dans mon cas, il y a beaucoup de données...néanmoins je retrouve le bug dans un exemple un peu plus complexe que je joins et qui parlera mieux que les mots!

En gros, en ajoutant plus de valeur de composé, le classement se loupe.

Autre point : il se trouve que j'ai plus de 255 lignes...je dois donc disposer de 2 feuilles de result (+result2) pour récupérer l'ensemble des données et d'une feuille result3 (feuille neutre, pas de macro mais ne doit pas être concernée par la recherche de valeur) pour faire un bilan calculatoire (je sais c'est compliqué, ce code me sauve la vie, chaque jour, je mettais 2 heures à rentrer l'extraction).

Je ne sais pas si c'est possible. :confused:
 

Pièces jointes

  • Radh_v03re.xls
    44.5 KB · Affichages: 44

Robert

XLDnaute Barbatruc
Repose en paix
Re : Extraction et classement de données

Bonsoir le fil, bonsoir le forum,

Dans le dernier exemple que tu fournis tu as des couples Type/Composé répétés plusieur fois :
4223325/GHI colonne D, F, H, J, L, et N.
4223325/JKL colonne E, G, I, K, et M.
Je vois mal, dans ces conditions comment le code pourrait fonctionner...
Pour cela comme pour le deuxième point il faut repenser le code. Je t'avoue que c'est la chose que je déteste le plus, me décarcasser pour trouver une solution puis à la fin on change les règles du jeu...
De toutes manières, si tu as des couple répétés je n'ai pas de solution, sinon de faire la somme des valeurs...
 

Bebere

XLDnaute Barbatruc
Re : Extraction et classement de données

bonjour Rhadamanthe,Robert
en réponse à 1ère demande une autre proposition

Code:
Public Sub Result()
    Dim a, Cel As Range, Ws As Worksheet, L As Long, DerL As Long, C As Integer, Mondico As Object
    Dim Indice As Long, MaLigne As Long, Clé As String, CléBase As String

    Application.ScreenUpdating = False

    Feuil3.Activate    'result
    Range("B3:K800").ClearContents
    For Each Ws In Worksheets
        If IsNumeric(Ws.Name) Then
            DerL = Ws.Range("A65536").End(xlUp).Row
            a = Ws.Range("A2:D" & DerL)
            For C = 2 To Range("B1").End(xlToRight).Column
                Set Mondico = CreateObject("scripting.dictionary")
                For i = 1 To UBound(a, 1)
                    If a(i, 2) & a(i, 3) = Cells(1, C) & Cells(2, C) Then
                        CléBase = Cells(1, C) & Cells(2, C)
                        Clé = CléBase
                        Indice = 1
                        Do While Mondico.exists(Clé)
                            Clé = CléBase & Indice
                            Indice = Indice + 1
                        Loop
                        Mondico(Clé) = i
                    End If
                Next i

                CléBase = Cells(1, C) & Cells(2, C)
                Clé = CléBase
                Indice = 1
                Do While Mondico.exists(Clé)
                    ligne = Mondico(Clé)
                    For Each Cel In Range("A3:A" & Range("A65536").End(xlUp).Row)

                        If CStr(Cel) = CStr(a(ligne, 1)) Then
                            L = Cel.Row
                            Exit For
                        End If
                    Next Cel
                    Cells(L, C) = a(ligne, 4)
                    Clé = CléBase & Indice
                    Indice = Indice + 1
                Loop
            Next C

        End If
    Next Ws

    Application.ScreenUpdating = True

End Sub
 

rhadamanthe

XLDnaute Junior
Re : Extraction et classement de données

Bonsoir le fil, bonsoir le forum,

Dans le dernier exemple que tu fournis tu as des couples Type/Composé répétés plusieur fois :
4223325/GHI colonne D, F, H, J, L, et N.
4223325/JKL colonne E, G, I, K, et M.
Je vois mal, dans ces conditions comment le code pourrait fonctionner...
Pour cela comme pour le deuxième point il faut repenser le code. Je t'avoue que c'est la chose que je déteste le plus, me décarcasser pour trouver une solution puis à la fin on change les règles du jeu...
De toutes manières, si tu as des couple répétés je n'ai pas de solution, sinon de faire la somme des valeurs...

Autant pour moi! J'ai écris l'exemple un peu vite. :eek: Il est vrai que ça semble peu faisable ainsi.

Avec des valeurs réelles, je constate un saut que je n'explique pas et qui fausse le resultat...j'essaie de comprendre ça pour poster un exemple adapté.
 

Robert

XLDnaute Barbatruc
Repose en paix
Re : Extraction et classement de données

Bonsoir le fil, bonsoir le forum,

Bebere, testé aussi sous excel 2003... Et ça plante là où je t'ai dit...
 

Pièces jointes

  • Radh_v03_Bebere.xls
    40.5 KB · Affichages: 39
  • Radh_v03_Bebere.xls
    40.5 KB · Affichages: 35
  • Radh_v03_Bebere.xls
    40.5 KB · Affichages: 42

rhadamanthe

XLDnaute Junior
Re : Extraction et classement de données

Robert,

Voici un exemple plus pertinent qui montre le 'bug'. Je crois qu'un saut de ligne ne s'effectue pas lorsqu'une ligne antérieure est ajoutée...(mais chuis un peu nul :( )

rhad

@Bebere : ca plante chez moi aussi
 

Pièces jointes

  • Radh_v03re2.xls
    46 KB · Affichages: 47
Dernière édition:

Discussions similaires

Statistiques des forums

Discussions
312 527
Messages
2 089 361
Membres
104 138
dernier inscrit
Ber