在Excel中将多行转换为单个堆叠列

在Excel中将多行转换为单个堆叠列,excel,rows,transpose,vba,Excel,Rows,Transpose,Vba,我有各种品牌的巨大市场份额数据,如下所示: 1111 2222 3333 4444 5555 7777 8888 9999 0001 0002 0004 0005 0006 0007 哪些宏代码可用于获取以下内容的输出: 1111 2222 3333 4444 5555 <emptyCell> 7777 8888 9999 0001 0002 <emptyCell> 0004 0005 0006 0007 1111 2222 3333 4444 5555 7

我有各种品牌的巨大市场份额数据,如下所示:

1111 2222 3333 4444
5555      7777 8888
9999 0001 0002
0004 0005 0006 0007
哪些宏代码可用于获取以下内容的输出:

1111
2222
3333
4444
5555
<emptyCell>
7777
8888
9999
0001
0002
<emptyCell>
0004
0005
0006
0007
1111
2222
3333
4444
5555
7777
8888
9999
0001
0002
0004
0005
0006
0007
还必须考虑空单元格


还有可能在其他表格中获得输出吗?

对于处理器密集度较低的版本,更改为
索引

在要将数据复制到的任何工作表的第1行中:

=INDEX($A$1:$D$4,INT((ROW()-1)/4)+1,MOD(ROW()-1,4)+1)
把这个复制下来,一旦零开始出现,你就到了终点。(这是唯一的问题-空白单元格将变为零。如果您也希望保留空白,则需要:

=如果(ISBLANK(索引($A$1:$D$4,INT((ROW()-1)/4)+1,MOD(ROW()-1,4)+1)),“”,索引($A$1:$D$4,INT((ROW()-1)/4)+1,MOD(ROW()-1,4)+1))

)

如果不是从第一行开始,则将
row()
更改为
row()-X
,其中X是从顶部向下的行数(即,第2行为1,第3行为2,第800行为799)

如果有不同的列数,请将4更改为适当的数字

假设范围为A1:D4,这里有一个VBA宏可以执行此操作(只需将值放在E列中)

您可以使用dictionary对象并将数组转置到列上,但这更简单,dictionary对象在Mac上不起作用。您也可以使用“Range”(“E”&k)”而不是“Cells(k,5)”,但是Cells()稍快一些,因为它不需要连接


还请注意,通过关闭屏幕更新,这将运行得更快。

根据SeanC的答案(感谢老兄)进行了修改,将其转换为通用用法,以便具有其他范围维度和起始单元格的用户可以使用它:

将“$RANGE$”替换为对您的范围的引用 参照输出列的第一个单元格替换“$CELL$”:

=INDEX( $RANGE$ ,INT((ROW()-ROW( $CELL$ ))/COLUMNS( $RANGE$ ))+1,MOD(ROW()-ROW( $CELL$ ),COLUMNS( $RANGE$ ))+1)

把这个拖下来。当然,确保$RANGE$和$CELL$在行和列上都用“$”符号固定

输出数据和原始数据之间有什么区别?您应该更具体地说明原始数据的外观以及应用宏后希望它的外观。@Ankur-您应该展示您迄今为止所做的尝试,这样我们就不会重复已经完成的工作。理想情况下,您只需在每一行中循环,然后转到下一行。但是,你怎么知道你在一行的末尾?相邻的两个空单元格是否都有?这些行的宽度是否都是固定的4?我正要回答类似的问题,但由于你的回答:+1,所以取消了回答!我要做的唯一更改是:使用
索引
而不是
偏移量
——它将提供相同的结果,但不易波动,因此在第一次计算运行后速度更快@彼得拉尔伯特,好主意。我将我的公式固定为INDEXI,没有提到这是一个数组公式,需要使用Ctrl+Shift+Enter方法输入。。。我错了吗?@CodeJockey,这不是数组公式。它使用当前行的计算来确定从何处获取数据
INDEX
将允许您指示数组中的位置,就像vba数组(ROW()-ROW($CELL$)从0开始,而第一列的ROW()从1开始,因此应该是(ROW()-ROW($CELL$)+1)编辑:我现在注意到,他已经删除了-1,所以我的注释无效非常好!我用范围名称替换了$Range$和$Cell$,现在这是一个很好的实用公式,无需定制
Sub Makealist()

Application.ScreenUpdating = False

Dim rng As Range
' Destination of List
Worksheets("SomeWorksheet1").Activate
Worksheets("SomeWorksheet1").Range("SomeRange1").Select

' Range to Convert to list
Set rng = Worksheets("SomeWorksheet2").Range("SomeRange2")

' Makes sure that all "Blank cells are really Blank"
For Each c In rng.Cells
    If Len(c) = 0 Then
        c.Value = ""
    End If
Next

' Creates the list
For Each c In rng.Cells
    If IsEmpty(c.Value) = False Then
        Selection.Value = c.Value
        Selection.Offset(1, 0).Select
    End If
Next

Application.ScreenUpdating = True

End Sub
Sub Makealist()

Application.ScreenUpdating = False

Dim rng As Range
' Destination of List
Worksheets("SomeWorksheet1").Activate
Worksheets("SomeWorksheet1").Range("SomeRange1").Select

' Range to Convert to list
Set rng = Worksheets("SomeWorksheet2").Range("SomeRange2")

' Makes sure that all "Blank cells are really Blank"
For Each c In rng.Cells
    If Len(c) = 0 Then
        c.Value = ""
    End If
Next

' Creates the list
For Each c In rng.Cells
    If IsEmpty(c.Value) = False Then
        Selection.Value = c.Value
        Selection.Offset(1, 0).Select
    End If
Next

Application.ScreenUpdating = True

End Sub