如何在excel中将许多列转换为一列,但保留每列的第一个单元格并在新行中重复它?

如何在excel中将许多列转换为一列,但保留每列的第一个单元格并在新行中重复它?,excel,excel-formula,excel-2016,vba,Excel,Excel Formula,Excel 2016,Vba,我有一个excel文档,看起来像这样: 我希望它是这样的: *逗号(,)表示数据水平位于不同的单元格中 有没有vb宏或表达式可以执行此操作?一个简单的解决方案是使用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

我有一个excel文档,看起来像这样:

我希望它是这样的:

*逗号(,)表示数据水平位于不同的单元格中


有没有vb宏或表达式可以执行此操作?

一个简单的解决方案是使用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

一个简单的解决方案是使用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

如果所有行的列数相同,则可以使用
INDEX
INT
COUNTA
MOD
进行分解

A栏:

=INDEX(Sheet1!$A$1:$D$2,1+INT((ROW()-1)/(COUNTA(Sheet1!$1:$1)-1)),1)
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))
其中
Sheet1$A$1:$D$2是“输入”范围,
Sheet1$1:$1
是该范围内包含整行数据的任何行

索引
用于获取范围的特定行/列。我们的范围是
Sheet1$A$1:$D$2
,两个公式的行相同:

1+INT((ROW()-1)/(COUNTA(Sheet1!$1:$1)-1)),
n行为1,下n行为2,以此类推,其中n是一行中的单元格数减去起始列(即每个性别有多少个姓名)

INT
删除数字的小数部分,因此
INT(3/4)
INT(0.75)
,即
0
COUNTA
只计算非空白单元格)

两者的区别在于列。在A列中,我们只需要第一个列,因此列是
1
。在B列中,我们需要第一列之后的第x项,其中x A)每行递增1,B)当我们从男性到女性(或更高)时重置为1


现在,
MOD
函数让我们非常简单地做到这一点:
MOD(0,3)
是0,
MOD(1,3)
是1,
MOD(2,3)
是2,
MOD(3,3)
回到0。我们只需要从0开始行计数(从行中减去1,并将其添加回
MOD
)并从每行的项目中删除第一列(从
COUNTA
中减去1,在
MOD
之外添加1)

如果所有行的列数相同,那么您可以使用
索引
INT
COUNTA
MOD
来分解这一点

A栏:

=INDEX(Sheet1!$A$1:$D$2,1+INT((ROW()-1)/(COUNTA(Sheet1!$1:$1)-1)),1)
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))
其中
Sheet1$A$1:$D$2是“输入”范围,
Sheet1$1:$1
是该范围内包含整行数据的任何行

索引
用于获取范围的特定行/列。我们的范围是
Sheet1$A$1:$D$2
,两个公式的行相同:

1+INT((ROW()-1)/(COUNTA(Sheet1!$1:$1)-1)),
n行为1,下n行为2,以此类推,其中n是一行中的单元格数减去起始列(即每个性别有多少个姓名)

INT
删除数字的小数部分,因此
INT(3/4)
INT(0.75)
,即
0
COUNTA
只计算非空白单元格)

两者的区别在于列。在A列中,我们只需要第一个列,因此列是
1
。在B列中,我们需要第一列之后的第x项,其中x A)每行递增1,B)当我们从男性到女性(或更高)时重置为1

现在,
MOD
函数让我们非常简单地做到这一点:
MOD(0,3)
是0,
MOD(1,3)
是1,
MOD(2,3)
是2,
MOD(3,3)
回到0。我们只需要从0开始行计数(从行中减去1,并将其添加回
MOD
)并从每行项目中删除第一列(从
COUNTA
中减去1,在
MOD
之外添加1),然后:

之后:

代码:

之前:

之后:

代码:


您的示例每行显示3个名称。每行中是否始终有3个名称?是的,所有行的列数都相同。我已对示例进行了编辑以添加图片如果您使用Excel 2010或更高版本,您可以使用
Power Query
(2010/2013免费MS addin)或
Data-->Get&Transform-->From table/range
(2016年提供)取消“名称”的锁定列。您的示例在每行中显示3个名称。每行中是否始终有3个名称?是的,所有行的列数都相同。我已对示例进行了编辑以添加图片如果您使用Excel 2010或更高版本,您可以使用
Power Query
(2010/2013免费MS addin)或
Data-->Get&Transform-->From table/range
(2016年提供)取消“名称”的锁定columns.抱歉,如果我在问题中不清楚,我已对其进行了编辑:*逗号(,)表示数据在水平方向上位于不同的单元格。@mike_x_这就是为什么数据片段通常首选截图:)是的,我假设数据位于一个单元格中抱歉,如果我在问题中不清楚,我已对其进行了编辑:*逗号(,)表示数据在水平方向上位于不同的单元格。@mike_x_这就是为什么数据片段通常首选截图:)是的,我假设数据位于一个单元格中