J'ai un vidage de données dans Excel qui consiste en des données client 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. ça ressemble à ça:
Je suis coincé avec une ligne pour le client 1 pour la valeur A en 2009 et une ligne séparée 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, aucune ligne n'a donc été générée à cet effet. 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 dans une année (et donc aucune ligne pour ce client cette année-là). Dans cette situation, l'absence d'une ligne pour ce client cette année est satisfaisante.
Je veux mettre cela dans une feuille de travail où il y a une ligne pour les deux valeurs pour chaque année et client. C'est-à-dire que je veux que les données ressemblent à ceci:
Quel est le moyen le plus efficace de créer ce résultat?
Ceci est VBA, ou une macro que vous pouvez exécuter sur votre feuille. Vous devez frapper alt+F11 pour afficher l'invite de Visual Basic pour Application, accédez à votre classeur et à right click - insert - module
et collez ce code ici. Vous pouvez ensuite exécuter le module à partir de VBA en appuyant sur F5. Cette macro s'appelle "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 aux deux le client et l'année et supprimez la ligne maintenant vide. La feuille de calcul doit être triée de la manière que vous avez présentée, clients et années ascendantes, , cette macro particulière n’examinera pas au-delà des lignes consécutives .
Edit - il est tout à fait possible que mon with statement
soit complètement inutile, mais ne blesse personne ..
Quelqu'un a utilisé cette réponse dans un autre question et quand je suis rentré, 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
Interrogé à nouveau Comment combiner les valeurs de plusieurs lignes dans une seule ligne? Avoir un module, mais il faut expliquer les variables et encore une fois, c'est assez médiocre.
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
Toutefois, selon le problème, il peut être préférable de step -1
sur 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
Une autre option:
Special
name __-> Blanks
-> OK
name__=
appuyez sur ↑, puis CTRL+ENTERSpecial
name __-> Blanks
-> OK
name__=IF(
appuyez sur ← tapez =
appuyez sur ← presse ↓ tapez ,
appuyez sur ↓ tapez ,0)
puis CTRL+ENTERCopy
and Paste Special as Values
EDIT:
Explication: J'essaie d'utiliser l'option GoTo Blanks . Une fois que vous avez sélectionné des 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 ressemblent à des blancs cohérents , à savoir: Value A
Les blancs de colonne ont le même CustomerID
comme ci-dessus la ligne non vide. De la même manière, les blancs de colonne Value B
ont le même nom CustomerID
au-dessous de la ligne non vide.
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 loin que nécessaire. Il génère une seule ligne de données à chaque fois que 2 lignes sont présentes, sans affecter les lignes individuelles. Collez les valeurs spéciales (pour supprimer les formules) des colonnes E-F-G-H ailleurs et triez-les par client pour supprimer toutes les lignes supplémentaires.
Pour ce faire, le moyen le plus efficace consiste à vider toutes les données dans un tableau croisé dynamique, à déposer "Client" dans les étiquettes de ligne, puis à effectuer un suivi avec les autres colonnes. Vous pouvez déposer "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
Voici les étapes à suivre pour créer une table séparée avec les données condensées.
Customer
et Year
name__. Cela fournira le cadre pour la table condensée.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.
Remplissez la formule dans la colonne. Remplissez ensuite pour remplir également la colonne Value B
. Voila!
Quelques notes:
1000000
s dans la formule en un nombre supérieur à votre nombre de lignes.