在Excel中对多行进行排序以将空列向右移动

时间:2019-03-01 12:31:45

标签: excel vba

我有一个包含3000行和2500列的电子表格。大多数列都充满零(但由于其他原因,它们确实必须存在于此)。我想对工作表进行排序,以便所有空列都位于右侧。该工作表如下所示:

ID       val1       val2       val3 ..... val2499       val2500   
1         1         2           0            0             1   
2         2         6           0            0             5   
3         0         5           0            0             0  
4         0         3           0            0             0   
5         1         1           0            0             2

我想要的是在左侧(以任何顺序)收集至少具有一个非零条目的所有列,并在右侧收集所有完全为零的列,因此上述示例将看起来像这样:

ID       val1       val2     val2500 ..... val3         val2499   
1         1         2           1            0             0   
2         2         6           5            0             0   
3         0         5           0            0             0  
4         0         3           0            0             0   
5         1         1           2            0             0

val3和val2499是否相反也没关系。我尝试了以下方法,但没有用:

for row=1 to 2500
    Range("A1:CAA2500").Sort Key1:=Range("B" & b), Order1:=xlDescending, Orientation:=xlLeftToRight
next row

我知道上面的代码很愚蠢,并且可能无法遍历每一行,但是我不认为该怎么做,或者根本可以做到。

预先感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

也许有更好的方法可以做到这一点,但这就是我目前所拥有的。

  • 代码假定(排序)数据在表"Sheet1"上,但根据需要进行更改。
  • 使用临时行(紧接在数据下方)并计算出每列中有多少个非零。
  • 每个列均按其非零计数排序(在上一步中计算)
  • 排序后,将清除临时行,并认为排序过程已完成。

不好,可能会变慢,具体取决于数据的大小(例如,影响数千个单元格的公式)。也就是说,它应该可以工作。

在代码前后切换Application.ScreenUpdatingApplication.Calculation可能会有所帮助。另外,如果您的数据位于要排序的范围的正下方,则可以改为Range.Insert用作temporaryRow的新行。

Option Explicit

Private Sub CustomSort()

    With ThisWorkbook.Worksheets("Sheet1")

        Dim rangeToSort As Range
        Set rangeToSort = .Range("A1:F6")

        Dim temporaryRow As Range
        Set temporaryRow = rangeToSort.Offset(rangeToSort.Rows.Count, 0).Resize(1)
        temporaryRow.Formula = "=COUNTIFS(" & rangeToSort.Columns(1).Address(True, False, xlA1) & ",""<>0"")"

        Application.Union(rangeToSort, temporaryRow).Sort Key1:=temporaryRow, Order1:=xlDescending, Orientation:=xlLeftToRight

        temporaryRow.Clear

    End With

End Sub

正如我所说,也许有更好的方法。但是我在Range.Sort的文档中或通过宏记录器都找不到任何内容。因此,这只是一种解决方法。