conserver lignes et colonnes non vides d'un tableau

elido

XLDnaute Nouveau
Bonjour

Voici mon problème. J'ai un fichier avec un tableau récapitulatif avec + de 50 colonnes et 100 lignes. Dans ce tableau certaines colonnes et lignes non adjacentes peuvent être vides ou pas.

Je voudrais épurer ce tableau sur un nouvel onglet de façon à ne garder que les lignes non vides. Je crois qu'il faudrait utiliser une fonction genre INDEX, EQUIV, ou quelque chose comme ça mais je ne les maitrise pas du tout et tous les exemples vus par ailleurs ne me parlent pas !!

Quelqu'un peut-il m'aider ?? Merci pour votre aide

Elido
 

Pièces jointes

  • Aide panier.xlsx
    17.4 KB · Affichages: 51

klin89

XLDnaute Accro
Re : conserver lignes et colonnes non vides d'un tableau

Re le forum,

Le code remanié, c'est mieux ainsi.
2 versions dans le fichier joint.
Résultat dans la feuille "paniers"

La première :
VB:
Option Explicit

Sub PaniersV1()
Dim myAreas As Areas, w(), n As Long, y, x As Long, w2 As Long
Dim i As Long, j As Long, k As Long
    Application.ScreenUpdating = False
    With Sheets("récap")
        On Error Resume Next
        Set myAreas = .Columns("A").SpecialCells(2).Areas
        On Error GoTo 0
    End With
    If Not myAreas Is Nothing Then
        With CreateObject("Scripting.Dictionary")
            .CompareMode = 1
            For i = 1 To myAreas.Count
                If myAreas(i).Rows.Count > 1 Then
                    For j = 3 To myAreas(i).CurrentRegion.Columns.Count
                        If Application.CountA(myAreas(i).Columns(j)) > 1 Then
                            If Not .exists(myAreas(i)(1, j).Value) Then
                                ReDim w(1 To 3, 1 To Application.CountA(myAreas(i).Columns(j)))
                                w(1, 1) = "Commandes"
                                w(2, 1) = "Panier du client " & myAreas(i)(1, j).Value
                                w(3, 1) = "Quantité"
                                For k = 2 To myAreas(i).Rows.Count
                                    If myAreas(i)(k, j).Value <> "" Then
                                        n = n + 1
                                        w(1, n + 1) = myAreas(i)(1, 1).Value
                                        w(2, n + 1) = myAreas(i)(k, 1).Value
                                        w(3, n + 1) = myAreas(i)(k, j).Value
                                    End If
                                Next
                                .Item(myAreas(i)(1, j).Value) = w
                                n = 0
                            Else
                                w = .Item(myAreas(i)(1, j).Value)
                                w2 = UBound(w, 2)
                                ReDim Preserve w(1 To 3, 1 To UBound(w, 2) + Application.CountA(myAreas(i).Columns(j)) - 1)
                                For k = 2 To myAreas(i).Rows.Count
                                    If myAreas(i)(k, j).Value <> "" Then
                                        n = n + 1
                                        w(1, w2 + n) = myAreas(i)(1, 1).Value
                                        w(2, w2 + n) = myAreas(i)(k, 1).Value
                                        w(3, w2 + n) = myAreas(i)(k, j).Value
                                    End If
                                Next
                                .Item(myAreas(i)(1, j).Value) = w
                                n = 0
                                w2 = 0
                            End If
                        End If
                    Next
                End If
            Next
            x = .Count: y = .items
        End With
        'restitution et mise en forme
        'Recopie en bas
        If x > 0 Then
            With Sheets("paniers")
                .Cells.Clear
                With .Columns(1).Resize(, 3)
                    .Font.Name = "calibri"
                    .Font.Size = 10
                    .HorizontalAlignment = xlCenter
                    .VerticalAlignment = xlCenter
                End With
                For i = 0 To UBound(y)
                    With .Cells(n + 1, 1)
                        .Resize(UBound(y(i), 2), UBound(y(i), 1)).Value = Application.Transpose(y(i))
                        With .CurrentRegion
                            With .Rows(1)
                                .Font.Size = 11
                                .Interior.ColorIndex = 42
                                .BorderAround Weight:=xlThin
                            End With
                            .Borders(xlInsideVertical).Weight = xlThin
                            .BorderAround Weight:=xlThin
                        End With
                    End With
                    n = n + UBound(y(i), 2) + 1
                Next
                .Columns.AutoFit
                .Activate
            End With
        Else
            MsgBox "Pas de paniers en commande"
        End If
    End If
    Application.ScreenUpdating = True
End Sub
La seconde version avec restitution des tableaux sur la droite
VB:
.......
'restitution et mise en forme
        'recopie à droite
        If x > 0 Then
            With Sheets("paniers")
                .Cells.Clear
                For i = 0 To UBound(y)
                    With .Cells(1, n + 1)
                        .Resize(UBound(y(i), 2), UBound(y(i), 1)).Value = Application.Transpose(y(i))
                        With .CurrentRegion
                            .Font.Name = "calibri"
                            .Font.Size = 10
                            .HorizontalAlignment = xlCenter
                            .VerticalAlignment = xlCenter
                            .Columns.AutoFit
                            .Borders(xlInsideVertical).Weight = xlThin
                            .BorderAround Weight:=xlThin
                            With .Rows(1)
                                .Font.Size = 11
                                .Interior.ColorIndex = 38
                                .BorderAround Weight:=xlThin
                            End With
                        End With
                    End With
                    n = n + UBound(y(i)) + 1
                Next
                .Columns.AutoFit
                .Activate
            End With
        Else
            MsgBox "Pas de paniers en commande"
        End If
.......
klin89
 

Pièces jointes

  • Paniers1.xls
    86 KB · Affichages: 32
Dernière édition:

elido

XLDnaute Nouveau
Re : conserver lignes et colonnes non vides d'un tableau

Bonjour Mapomme
Merci pour ta réponse, tu as très bien compris ma demande et c'est vraiment à ça que je voulais arriver. Pour l'économie de papier, si les clients sans commandes n'étaient pas présents sur le "récap panier" ça aurait été super car j'arrive à + de 50 noms ! Mais là je pense en demander trop !!!
Les explications sont très utiles pour comprendre le cheminement opéré. Merci pour le coté pédagogue ! Un vrai plaisir d'avoir pu bénéficier de tes compétences.

Une autre question si tu as des idées : quand les personnes passent commande elle vont directement sur leur onglet. Parfois certains se trompent et vont passer leur commande sur un onglet qui n'est pas pour eux mais ne s'en rendent pas compte. A ton avis y a t-il une possibilité pour éviter ce genre d'embrouille ?

Je ne t'oublie pas Klin89, merci également de ta proposition mais elle ne pourra pas me servir cette fois car je ne peux pas utiliser les macros pour ce travail. Je la garde au chaud pour une autre fois peut-être.

Elido
 

klin89

XLDnaute Accro
Re : conserver lignes et colonnes non vides d'un tableau

Bonsoir elido, mapomme, le forum :)

Je souhaitais revenir sur cet exercice.

Pour faire simple, j'ai commencé par créer une copie de la feuille source et effectuer un bon nettoyage.
Avec le fichier du post #12, résultat dans la feuille "paniers"
VB:
Option Explicit

Sub Creation_des_paniers()
Dim myAreas As Areas, w(), n As Long, y, x As Long, w2 As Long
Dim i As Long, j As Long, k As Long
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    'On crée une copie de la feuille source
    'sur laquelle on va travailler : version sans formule
    On Error Resume Next
    Application.DisplayAlerts = False
    Sheets("Copie").Delete
    Application.DisplayAlerts = True
    On Error GoTo 0
    Sheets("récap commandes").Copy after:=Sheets(Sheets.Count)
    Sheets(Sheets.Count).Name = "Copie"
    Sheets("Copie").Move before:=Sheets("récap commandes")

    'Nettoyage de la copie pour y voir plus clair et réorganisation des données
    With Sheets("copie")
        With .UsedRange
            .Value = .Value
            .Font.ColorIndex = 1
            .Interior.ColorIndex = -4142
            .Replace What:="0", Replacement:="", LookAt:=xlWhole, _
                     SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
                     ReplaceFormat:=False
        End With
        On Error Resume Next
        .Columns("A").SpecialCells(2, 1).EntireRow.Delete
        .Columns("A").SpecialCells(4).EntireRow.Delete
        On Error GoTo 0
        .Columns(1).Insert
        With .Range("b1", .Range("b" & Rows.Count).End(xlUp)).Offset(, -1)
            .Formula = "=if(or(b1= ""Total"",b1= ""RETOUR LISTE NOMS""),1,"""")"
            .Value = .Value
            On Error Resume Next
            .SpecialCells(2, 1).Offset(1).EntireRow.Insert shift:=xlShiftUp
            On Error GoTo 0
        End With
        .Columns(1).Delete
        On Error Resume Next
        Set myAreas = .Columns("A").SpecialCells(2).Areas
        On Error GoTo 0
    End With
    
    'Traitement des données
    If Not myAreas Is Nothing Then
        With CreateObject("Scripting.Dictionary")
            .CompareMode = 1
            For i = 1 To myAreas.Count
                If myAreas(i).Rows.Count > 3 Then
                    For j = 5 To myAreas(i).CurrentRegion.Columns.Count
                        If Application.CountA(myAreas(i).Columns(j)) > 3 Then
                            If Not .exists(myAreas(i)(1, j).Value) Then
                                ReDim w(1 To 4, 1 To Application.CountA(myAreas(i).Columns(j)) - 2)
                                w(1, 1) = " Produits "
                                w(2, 1) = "Panier de " & myAreas(i)(1, j).Value
                                w(3, 1) = "Quantité"
                                w(4, 1) = "Montant"
                                For k = 3 To myAreas(i).Rows.Count - 1
                                    If myAreas(i)(k, j).Value <> "" Then
                                        n = n + 1
                                        w(1, n + 1) = myAreas(i)(1, 1).Value
                                        w(2, n + 1) = myAreas(i)(k, 1).Value
                                        w(3, n + 1) = myAreas(i)(k, j).Value
                                        w(4, n + 1) = myAreas(i)(k, j).Value * myAreas(i)(k, 3).Value
                                    End If
                                    If n + 1 = Application.CountA(myAreas(i).Columns(j)) - 2 Then Exit For
                                Next
                                .Item(myAreas(i)(1, j).Value) = w
                                n = 0
                            Else
                                w = .Item(myAreas(i)(1, j).Value)
                                w2 = UBound(w, 2)
                                ReDim Preserve w(1 To 4, 1 To UBound(w, 2) + Application.CountA(myAreas(i).Columns(j)) - 3)
                                For k = 3 To myAreas(i).Rows.Count - 1
                                    If myAreas(i)(k, j).Value <> "" Then
                                        n = n + 1
                                        w(1, w2 + n) = myAreas(i)(1, 1).Value
                                        w(2, w2 + n) = myAreas(i)(k, 1).Value
                                        w(3, w2 + n) = myAreas(i)(k, j).Value
                                        w(4, w2 + n) = myAreas(i)(k, j).Value * myAreas(i)(k, 3).Value
                                    End If
                                    If n = Application.CountA(myAreas(i).Columns(j)) - 3 Then Exit For
                                Next
                                .Item(myAreas(i)(1, j).Value) = w
                                n = 0
                                w2 = 0
                            End If
                        End If
                    Next
                End If
            Next
            x = .Count: y = .items
        End With
        'restitution et mise en forme
        'recopie à droite dans la feuille "paniers"
        If x > 0 Then
            With Sheets("paniers")
                .Cells.Clear
                For i = 0 To UBound(y)
                    With .Cells(1, n + 1)
                        .Resize(UBound(y(i), 2), UBound(y(i), 1)).Value = Application.Transpose(y(i))
                        With .CurrentRegion
                            With .Offset(.Rows.Count).Resize(1)
                                .Value = _
                                Array("Total", "Panier", "-", "=sum(r2c:r[-1]c)")
                                With .CurrentRegion
                                    .Font.Name = "calibri"
                                    .Font.Size = 10
                                    .HorizontalAlignment = xlCenter
                                    .VerticalAlignment = xlCenter
                                    .Borders(xlInsideVertical).Weight = xlThin
                                    .BorderAround Weight:=xlThin
                                    With .Rows(1)
                                        .Interior.ColorIndex = 38
                                        .BorderAround Weight:=xlThin
                                    End With
                                    With .Rows(.Rows.Count)
                                        .Interior.ColorIndex = 43
                                        .BorderAround Weight:=xlThin
                                    End With
                                    With .Columns(.Columns.Count)
                                        .NumberFormat = "# ##0.00 €"
                                        .HorizontalAlignment = xlRight
                                    End With
                                    .Columns.AutoFit
                                End With
                            End With
                        End With
                    End With
                    n = n + UBound(y(i)) + 1
                Next
                .Columns.AutoFit
                .Activate
            End With
        Else
            MsgBox "Pas de paniers en commande"
        End If
    End If
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
End Sub
klin89
 

Pièces jointes

  • Paniers2.xls
    656.5 KB · Affichages: 35

Discussions similaires

Membres actuellement en ligne

Statistiques des forums

Discussions
312 294
Messages
2 086 895
Membres
103 404
dernier inscrit
sultan87