简体   繁体   中英

How to convert many columns to one column in excel but keep the 1st cell of each column and repeat it in new rows?

I have and excel document that looks like this:

输入,{男|约翰|迈克|乔治} {女|安|琼|简}

and i want it to be like:

输出,{男|约翰} {男|迈克} {男|乔治} {女|安} {女|琼} {女|简}

*comma (,) means that data are in different cells horizontally.

is there any vb macro or an expression to do it?

If all of the Rows have the same number of columns, then you can use INDEX , INT , COUNTA and MOD to break this down.

Column A:

=INDEX(Sheet1!$A$1:$D$2,1+INT((ROW()-1)/(COUNTA(Sheet1!$1:$1)-1)),1)

Column B:

=INDEX(Sheet1!$A$1:$D$2,1+INT((ROW()-1)/(COUNTA(Sheet1!$1:$1)-1)),2+MOD(ROW()-1,COUNTA(Sheet1!$1:$1)-1))

Where Sheet1!$A$1:$D$2 is the 'Input' range, and Sheet1!$1:$1 is any row in that range with a full row of data.

INDEX lets you get a specific row/column of a range. Our Range is Sheet1!$A$1:$D$2 , and the Row is the same for both formulae:

1+INT((ROW()-1)/(COUNTA(Sheet1!$1:$1)-1)),

This will be 1 for n rows, 2 for the next n , etc, where n is the number of cells in a row minus the starter column (ie how many names per gender)

( INT removes the decimal part of a number, so INT(3/4) is INT(0.75) , which is 0 . COUNTA just counts the non-blank cells)

The difference between the two is the Column. In column A, we just want the first column, so Column is 1 . In column B, we want the x th item after the first column, where x A) counts up by 1 each row and B) resets to 1 when we go from Male to Female (or beyond)

Now, the MOD function lets us do that fairly simply: MOD(0, 3) is 0, MOD(1, 3) is 1, MOD(2, 3) is 2, and MOD(3, 3) is back to 0 . We just need to start out row count at 0 (subtract 1 from Row, and add it back outside the MOD ) and remove the first column from the items-per-row (subtract 1 from the COUNTA , add 1 outside the MOD )

A straightforward solution would be to use Split

Sub TransferIt()

Const SEP = ","

Dim rg As Range
Dim vdat As Variant
Dim lDat As Variant
Dim i As Long, j As Long
Dim col As Collection

    ' Assumption data is in column A, adjust accordingly
    Set rg = Range("A1:A4")
    vdat = WorksheetFunction.Transpose(rg)

    Set col = New Collection

    For i = LBound(vdat) To UBound(vdat)
        lDat = Split(vdat(i), SEP)
        For j = LBound(lDat) + 1 To UBound(lDat)
            ' first field always contains female or male
            col.Add lDat(LBound(lDat)) & SEP & lDat(j)
        Next j
    Next i

    vdat = collectionToArray(col)

    ' Write data into column B
    Range("B1").Resize(UBound(vdat) + 1) = WorksheetFunction.Transpose(vdat)

End Sub

' Source: http://www.iwebthereforeiam.com/iwebthereforeiam/2004/06/excel-vba-code-to-convert-coll.html
Function collectionToArray(c As Collection) As Variant()
    Dim a() As Variant: ReDim a(0 To c.Count - 1)
    Dim i As Integer
    For i = 1 To c.Count
        a(i - 1) = c.Item(i)
    Next
    collectionToArray = a
End Function

Before:

在此处输入图片说明

After:

在此处输入图片说明

Code:

Sub settupp()
Set s1 = Sheets("Sheet1")
Set s2 = Sheets("Sheet2")
s1.Activate
n = Cells(Rows.Count, 1).End(xlUp).Row
k = 1
For i = 1 To n
namee = Cells(i, 1).Value
For j = 2 To 4
numberr = Cells(i, j).Value
s2.Cells(k, 1) = namee
s2.Cells(k, 2) = numberr
k = k + 1
Next
Next
End Sub

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM