【问题标题】:Convert Multiple Rows into Single Stacked Column in Excel在 Excel 中将多行转换为单个堆积列
【发布时间】:2018-04-16 23:17:08
【问题描述】:

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

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

还必须考虑空单元格。

还有可能在其他 Sheet 中获取输出吗?

【问题讨论】:

  • 输出数据和原始数据有什么区别?您应该更具体地了解原始数据的外观以及您希望它在应用宏后的外观。
  • @Ankur - 你应该展示你到目前为止所做的尝试,所以我们不会重复已经完成的工作。理想情况下,您只需遍历每一行,然后继续下一行。但是,您如何知道自己何时排在最后?
  • 可以有2个空单元格相邻吗?
  • 行的宽度都是固定的 4 吗?

标签: excel rows transpose vba


【解决方案1】:

更改为 INDEX 以获得处理器密集度较低的版本

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

=INDEX($A$1:$D$4,INT((ROW()-1)/4)+1,MOD(ROW()-1,4)+1)

复制下来,一旦开始出现零,你就结束了。 (这是唯一的问题 - 空白单元格将变为零。如果您也希望保留空白,那么您需要这个:

=IF(ISBLANK(INDEX($A$1:$D$4,INT((ROW()-1)/4)+1,MOD(ROW()-1,4)+1)),"" ,INDEX($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改成合适的数

【讨论】:

  • 我正要回答类似的问题,但由于您的回答而取消了:+1!我要做的唯一更改:使用INDEX 而不是OFFSET - 它会提供相同的结果,但它是非易失性的,因此在第一次计算运行后要快得多!!!
  • @PeterAlbert,好主意。我将公式固定为 INDEX
  • 我没有看到提到这是一个数组公式,需要使用 Ctrl+Shift+Enter 方法输入...我错了吗?
  • @CodeJockey,这不是数组公式。它使用当前行的计算来确定从哪里获取数据。 INDEX 将允许您指示数组中的位置,很像 vba 数组
【解决方案2】:

根据 SeanC 的回答(感谢好友)修改为通用用法,以便具有其他范围维度和起始单元格的人可以使用它:

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

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

向下拖动。当然,请确保 $RANGE$ 和 $CELL$ 在行和列上都用“$”符号固定。

【讨论】:

  • (ROW()-ROW($CELL$)) 从0开始,而第一列的ROW()从1开始,所以应该是(ROW()-ROW($CELL$ ) + 1) 编辑:我现在注意到你删除了他的 -1,所以我的评论无效
  • 非常好!我已将 $Range$ 和 $Cell$ 替换为范围名称,现在将其作为一个不错的实用公式,无需自定义
【解决方案3】:

假设您的范围是 A1:D4,这里有一个 VBA 宏可以做到这一点(只需将值放在 E 列下方)。

Sub RangeToColumn()

Dim varray As Variant
Dim i As Long, j As Long, k As Long

Application.ScreenUpdating = False
k = 1

varray = Range("A1:D4").value
For i = 1 To UBound(varray, 1)
    For j = 1 To UBound(varray, 2)
        Cells(k, 5).value = varray(i, j)
        k = k + 1
    Next
Next

Application.ScreenUpdating = True

End Sub

您可能会喜欢并使用字典对象并将数组转置到列上,但这更简单,并且字典对象在 Mac 上不起作用。您也可以使用 "Range("E" & k)" 代替 "Cells(k, 5)" 但 Cells() 速度稍快一些,因为它不需要连接。

另请注意,关闭屏幕更新,运行速度会更快。

【讨论】:

    【解决方案4】:
    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-06
      • 2019-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多