问题
I've tried searching Stackoverflow and Google for an answer to this but haven't found it yet. I think part of my problem is I'm not sure what the keyword(s) for what I'm trying to do would be.
My data looks something like this:
ID Var1 Var2 Name
01 0001 0002 Bill
01 0001 0002 Jim
01 0001 0002 Sally
02 0003 0004 Sam
02 0003 0004 Kyle
You'll see that I have multiple rows with the same ID and same Var1 and Var2 but each row has a unique name. I want to "flatten" the rows so there is only a single row for each ID and each row has as many "Name" columns as are necessary to fit all of the data.
Like this:
ID Var1 Var2 Name1 Name2 Name3
01 0001 0002 Bill Jim Sally
02 0003 0004 Sam Kyle
Does anyone know how to do this or what it's called?
Thanks!
Update based on comments: My data source is .csv file and I'm trying to manipulate it with Excel. Excel macros or VBA solutions would be best. Unfortunately my SQL is very elementary so learning to apply an SQL solution would be time-prohibitive.
回答1:
Something like this is very quick using variant arrays and a dictionary object
The code dumps the output from A1:Dx to F1
Update: fixed name numerals

Sub ReCut()
Dim X
Dim Y
Dim C
Dim lngRow As Long
Dim lngCol As Collection
Dim lngCnt1 As Long
Dim lngCnt As Long
Dim objDic As Object
Set objDic = CreateObject("scripting.dictionary")
X = Range([a1], Cells(Rows.Count, "C").End(xlUp)).Value2
Y = X
ReDim Y(1 To UBound(Y), 1 To 100)
For lngCnt1 = 1 To (UBound(Y, 2) - 3)
Y(1, lngCnt1) = "Name" & lngCnt1
Next
For lngRow = 1 To UBound(X, 1)
If objDic.exists(X(lngRow, 1) & X(lngRow, 2) & X(lngRow, 3)) Then
'find first blank entry in relevant array row
C = Split(Join(Application.Index(Y, lngCnt), "| "), "|")
Y(lngCnt, Application.Match(" ", C, 0)) = X(lngRow, 4)
Else
lngCnt = lngCnt + 1
Y(lngCnt, 1) = X(lngRow, 1)
Y(lngCnt, 2) = X(lngRow, 2)
Y(lngCnt, 3) = X(lngRow, 3)
Y(lngCnt, 4) = X(lngRow, 4)
objDic.Add X(lngRow, 1) & X(lngRow, 2) & X(lngRow, 3), lngCnt
End If
Next
[f1].Resize(UBound(Y, 1), UBound(Y, 2)) = Y
End Sub
回答2:
If you are going for a SQL request, you might take a look at triggers. First, you need to loop through your data.
CREATE TRIGGER tg AFTER INSERT ON `myTable`
FOR EACH ROW
BEGIN
insert into myTable(MyNewName) values (Name);
END
;
Also you need to work with Alter Table in order to add a new column
ALTER TABLE myTable
ADD MyNewName VARCHAR
http://www.w3schools.com/sql/sql_alter.asp
And to make a comparison if Var1 already exists you do an IF-condition
IF previousrecord = nextrecord
BEGIN
ALTER TABLE myTable
ADD MyNewName VARCHAR
END
http://msdn.microsoft.com/fr-fr/library/ms182717.aspx
Now combine all of them with a trigger:
CREATE TRIGGER tg AFTER INSERT ON `myTable`
FOR EACH ROW
BEGIN
IF previousrecord = currentrecord // where at beginning previousrecord=firstrecord
BEGIN
ALTER TABLE myTable
ADD MyNewName VARCHAR // MyNewName you can create a variable that increases
// smth like $added=0 then increase it
insert into myTable(MyNewName) values (Name);
END
END
;
It is a supposition when you read the data from your input that it is sorted by ID. It's maybe not the final solution, but it is supposed to help you out.
回答3:
Formula-only requires quite a lot of explanation but is merely a sequence of operations that individually are quite familiar to many:
- Select your four columns (say A:D).
- Data > Outline – Subtotal with At each change in:
ID, Use function:Count, Add subtotal to: check all, checkReplace current subtotalsandSummary below dataand OK. - Filter A:E and for ColumnA choose
Text Filters, ContainsC, OK. - Enter, in B5
=B4and copy across to D5 - In F5:
=IF(COLUMN()<6+$E5,OFFSET($E5,COLUMN()-6-$E5,),"")
- Copy F5 across to say Z5 (further to the right if necessary).
- Copy B5:D5 and F5:Z5 down to last grouped row.
- Unfilter (select all).
- Copy whole sheet and paste over the top with Paste Special, Values.
Remove Allin Subtotal.- Filter ColumnA to select
Grand Countand(Blanks)only. - Delete rows numbered in blue.
- Delete ColumnA.
- Drag D1 to E1 and append
1. - Drag E1 across to the right as far as required.
- Delete ColumnD.
来源:https://stackoverflow.com/questions/17748781/flatten-multiple-rows-containing-different-data-but-with-a-common-reference-in