Comment combiner des valeurs de plusieurs lignes en une seule ligne dans Excel?

10

J'ai un vidage de données dans Excel qui se compose de données clients annuelles pour deux valeurs différentes. Les données ont été fournies avec une ligne distincte pour la valeur pour chaque année et chaque client. C'est à dire que cela ressemble à ceci:

entrez la description de l'image ici

Je suis coincé avec une ligne pour le client 1 pour la valeur A en 2009 et une ligne distincte pour la valeur B pour le même client dans la même année.

Dans certains cas, il n'y a pas de valeur A ou de valeur B. Dans l'exemple ci-dessus, vous pouvez voir que le client 1 n'a pas de valeur B en 2011, donc aucune ligne n'a été générée pour cela. Et, bien qu'ils ne soient pas représentés dans l'exemple, certains clients n'auront aucune donnée pour l'une ou l'autre valeur au cours d'une année (et donc pas de ligne pour ce client cette année-là). Dans cette situation, l'absence d'une rangée pour ce client cette année-là est très bien.

Je veux mettre cela dans une feuille de calcul où il y a une ligne pour les deux valeurs pour chaque année et client. C'est à dire, je veux que les données ressemblent à ceci:

entrez la description de l'image ici

Quelle est la manière la plus efficace de créer ce résultat?

Greg R.
la source

Réponses:

6

Il s'agit de VBA ou d'une macro que vous pouvez exécuter sur votre feuille. Vous devez appuyer sur alt+ F11pour afficher l'invite Visual Basic pour Application, accédez à votre classeur right click - insert - moduleet collez-y ce code. Vous pouvez ensuite exécuter le module à partir de VBA en appuyant sur F5. Cette macro est nommée "test"

Sub test()
'define variables
Dim RowNum as long, LastRow As long
'turn off screen updating
Application.ScreenUpdating = False
'start below titles and make full selection of data
RowNum = 2
LastRow = Cells.SpecialCells(xlCellTypeLastCell).Row
Range("A2", Cells(LastRow, 4)).Select
'For loop for all rows in selection with cells
For Each Row In Selection
    With Cells
    'if customer name matches
    If Cells(RowNum, 1) = Cells(RowNum + 1, 1) Then
        'and if customer year matches
        If Cells(RowNum, 4) = Cells(RowNum + 1, 4) Then
            'move attribute 2 up next to attribute 1 and delete empty line
            Cells(RowNum + 1, 3).Copy Destination:=Cells(RowNum, 3)
            Rows(RowNum + 1).EntireRow.Delete
        End If
     End If
    End With
'increase rownum for next test
RowNum = RowNum + 1
Next Row
'turn on screen updating
Application.ScreenUpdating = True

End Sub

Cela passera par une feuille de calcul triée et combinera des lignes consécutives qui correspondent à la fois au client et à l'année et supprimera la ligne maintenant vide. La feuille de calcul doit être triée comme vous l'avez présentée, les clients et les années croissant, cette macro particulière ne regardera pas au-delà des lignes consécutives .

Edit - il est tout à fait possible que mon with statementsoit complètement inutile, mais cela ne fait de mal à personne ..

REVISITED 28/02/14

Quelqu'un a utilisé cette réponse dans une autre question et quand je suis revenu, je pensais que ce VBA était pauvre. Je l'ai refait -

Sub CombineRowsRevisited()

Dim c As Range
Dim i As Integer

For Each c In Range("A2", Cells(Cells.SpecialCells(xlCellTypeLastCell).Row, 1))
If c = c.Offset(1) And c.Offset(,4) = c.Offset(1,4) Then
            c.Offset(,3) = c.Offset(1,3)
            c.Offset(1).EntireRow.Delete
End If

Next

End Sub

Revisité le 05/04/16

Redemandé Comment combiner les valeurs de plusieurs lignes en une seule ligne? Avoir un module, mais besoin d'expliquer les variables et encore une fois, c'est assez pauvre.

Sub CombineRowsRevisitedAgain()
    Dim myCell As Range
    Dim lastRow As Long
    lastRow = Cells(Rows.Count, "A").End(xlUp).Row

    For Each myCell In Range(Cells("A2"), Cells(lastRow, 1))
        If (myCell = myCell.Offset(1)) And (myCell.Offset(0, 4) = myCell.Offset(1, 4)) Then
            myCell.Offset(0, 3) = myCell.Offset(1, 3)
            myCell.Offset(1).EntireRow.Delete
        End If
    Next
End Sub

Cependant, selon le problème, il peut être préférable de step -1saisir un numéro de ligne afin que rien ne soit ignoré.

Sub CombineRowsRevisitedStep()
    Dim currentRow As Long
    Dim lastRow As Long
    lastRow = Cells(Rows.Count, 1).End(xlUp).Row

    For currentRow = lastRow To 2 Step -1
        If Cells(currentRow, 1) = Cells(currentRow - 1, 1) And _
        Cells(currentRow, 4) = Cells(currentRow - 1, 4) Then
            Cells(currentRow - 1, 3) = Cells(currentRow, 3)
            Rows(currentRow).EntireRow.Delete
        End If
    Next

End Sub
Raystafarian
la source
2

Une autre option:

  1. Sélectionnez la colonne B, appuyez sur CTRL+G-> Special-> Blanks->OK
  2. Tapez =appuyez sur , puisCTRL+ENTER
  3. Sélectionnez la colonne C, appuyez sur CTRL+G-> Special-> Blanks->OK
  4. Tapez la =IF(presse Type =presse presse Type ,presse Type ,0)puisCTRL+ENTER
  5. Sélectionnez toutes les données et CopyetPaste Special as Values
  6. Supprimez les doublons.

ÉDITER:

Explication: J'essaie d'utiliser l' option GoTo Blanks . Une fois que vous avez sélectionné les blancs, vous pouvez entrer la même formule pour toutes les cellules vides sélectionnées. En ce qui concerne la question de OP, les données semblent avoir des blancs cohérents , c'est-à-dire que les Value Ablancs de colonne ont la même chose CustomerIDque la ligne non vide ci-dessus. De la même manière Value B, les blancs de colonne ont la même valeur CustomerIDque la ligne non vide ci-dessous.

zx8754
la source
Bonjour zx8754. Pourriez-vous s'il vous plaît ajouter quelques explications sur l'idée derrière votre solution?
nixda
@nixda Explication ajoutée, désolé de trouver les étapes assez claires.
zx8754
0

La façon la plus efficace de le faire est de vider toutes les données dans un tableau croisé dynamique et de déposer «Client» dans les étiquettes de lignes, puis de suivre les autres colonnes. Vous pouvez déposer l '«Année» dans l'en-tête de la colonne si vous souhaitez voir la répartition par année

Les tableaux croisés dynamiques se trouvent sous Insérer dans Excel 2010

xXPhenom22Xx
la source
Vous rencontrerez des problèmes avec des cellules qui n'ont aucune valeur dans la colonne B car Excel n'aura aucun moyen de savoir que la valeur dans B2 et B3 est en quelque sorte liée.
xXPhenom22Xx
J'ai certes peu d'expérience avec les tableaux croisés dynamiques, mais je ne pense pas que les tableaux croisés dynamiques résolvent le problème que j'ai. Je veux que les données pour toutes les valeurs d'un client sur une ligne par an afin que je puisse les manipuler (par exemple créer une colonne en ajoutant la valeur A + la valeur B), pas seulement changer la façon dont je les affiche via un tableau croisé dynamique. Je veux littéralement que les données soient structurées différemment dans la feuille de calcul.
Greg R.
Oui, ce serait difficile à moins que vous ayez toujours des colonnes alternées avec des données manquantes comme vous le faites dans l'exemple. Si ce n'est pas le cas, il n'y a aucun moyen pour Excel de faire logiquement ce que vous voulez aussi.
xXPhenom22Xx
Greg - vous pouvez résoudre le problème ainsi: une fois qu'il est dans le tableau croisé dynamique au format souhaité, copiez-le hors du tableau croisé dynamique vers un autre emplacement (même feuille ou autre) - et ensuite vous pouvez le manipuler comme vous le souhaitez , y compris l'ajout de colonnes, de formules, etc.
yosh m
0

Voici les étapes pour créer une table séparée avec les données condensées.

  1. Copiez l'intégralité de votre tableau et collez-le sur une nouvelle feuille.
  2. Sélectionnez votre nouveau tableau et Supprimer les doublons (Ruban de données -> Supprimer les doublons) sur les colonnes Customeret Year. Cela fournira le cadre du tableau condensé.
  3. Dans B2 (la première entrée pour Value A) entrez les informations suivantes:

    =IFERROR(INDEX(Sheet1!B$1:B$11,MIN(IF(Sheet1!$A$1:$A$11=$A2,IF(Sheet1!$D$1:$D$11=$D2,IF(Sheet1!B$1:B$11<>"",ROW(Sheet1!$A$1:$A$11),1000000),1000000),1000000))),"")

    Entrez la formule sous forme de formule matricielle en appuyant sur Ctrl+ Shift+ Enter.

  4. Remplissez la formule dans la colonne. Remplissez ensuite pour remplir également la Value Bcolonne. Voila!

Quelques notes:

  • Vous devrez bien sûr ajuster les adresses en fonction de vos données. Pour référence, Sheet1 est les données d'origine dans les colonnes A à D.
  • Je suppose que vos données (ou en-têtes) commencent à la ligne 1. C'est probablement vrai s'il s'agit d'un vidage de données. La formule devra être ajustée si ce n'est pas le cas.
  • Je suppose que votre table contient moins d'un million de lignes. Si vous en avez plus que cela, changez le 1000000s de la formule en quelque chose de plus grand que votre nombre de lignes.
  • Si votre table contient plusieurs milliers de lignes (100 000+), vous pouvez envisager d'utiliser une solution VBA à la place, car les formules de tableau peuvent s'enliser avec de grands tableaux.
Excellll
la source
0

Tout le monde utilise beaucoup de code VBA ou des fonctions compliquées pour cela. J'ai une méthode qui prend une seconde à mettre en œuvre mais qui est beaucoup plus compréhensible et très facile à ajuster en fonction de diverses autres possibilités.

Dans l'exemple que vous avez donné ci-dessus, collez ces (4) fonctions dans les cellules, E2, F2, G2 et H2, respectivement (les fonctions F&G font référence aux cellules ci-dessus):

=IF(D2=D3, A2,         IF(D2<>D1, A2,            ""))    
=IF(D2=D3, MAX(B2:B3), IF(D2<>D1, B2,            ""))    
=IF(D2=D3, MAX(B2:B3), IF(D2<>D1, IF(C2=0,"",C2),""))    
=IF(D2=D3, D2,         IF(D2<>D1, D2,            ""))

Faites glisser ces formules aussi bas que nécessaire. Il génère une seule ligne de données chaque fois que 2 lignes sont présentes, laissant les lignes simples inchangées. Collez les valeurs spéciales (pour supprimer les formules) des colonnes EFGH ailleurs et triez-les par client pour supprimer toutes les lignes supplémentaires.

Kindlin
la source