【问题标题】:Excel 2013: Sorting columns based on first row value using VBAExcel 2013:使用 VBA 根据第一行值对列进行排序
【发布时间】:2016-04-21 00:26:38
【问题描述】:

我想实现一个 Excel 宏,对从“C”列到包含数据的最后一列的所有列进行排序(A 列和 B 列不受影响)。

列应根据第一行的单元格值从 A->Z 排序(这是一个字符串)。

到目前为止,我想出了以下我不太喜欢的代码,因为它包含排序范围的硬编码数字,这使得代码不是很健壮。

Sub SortAllColumns()
    Application.ScreenUpdating = False

'Sort columns
    With ActiveWorkbook.Worksheets("mySheet").Sort
        .SetRange Range("C1:ZZ1000")
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlLeftToRight
        .Apply
    End With

    Application.ScreenUpdating = True
End Sub

在互联网上搜索,您可能会发现大量关于获取最后使用的列或行的建议。然而,他们中的大多数会比我预期的更严重地破坏代码。

我不是 VBA 专家,如果有人能提出如何以优雅高效的方式解决此问题的建议,那就太好了。

如果这很重要:我们肯定不会超过 1000 行和 1000 列。

非常感谢任何建议。

【问题讨论】:

  • 您提到从 C 列开始,但是,在您指定的范围内,从 E 列开始?应该是哪个?
  • I do not like that much because it contains hardcoded numbers for the Sort range making the code not really robust. 你需要找到最后一行有数据,然后构造你的范围.SetRange Range("E1:ZZ" & LastRow)。请参阅THIS 链接了解如何找到最后一行。
  • 同样你可以找到最后一列:)
  • @Janis S. 你是对的。这是示例代码中的一个错误。谢谢!
  • @SiddharthRout 感谢您的建议。我去看看

标签: vba excel sorting


【解决方案1】:

已编辑:

  • 更改了临时工作表添加语句,使其始终作为最后一个
  • 相应地修改了删除声明

如果您需要通过移动它们来对列进行排序,以便它们的标题从左到右排序,那么试试这个代码

Option Explicit

Sub main()
Dim lastCol As Long

With Sheets("mySheet")
    lastCol = .cells(1, .Columns.Count).End(xlToLeft).Column
    Call OrderColumns(Range(.Columns(3), Columns(lastCol)))
End With

End Sub


Sub OrderColumns(columnsRng As Range)
Dim LastRow As Long

With columnsRng
    LastRow = GetColumnsLastRow(columnsRng)
    With .Resize(LastRow)
        .Copy

        With Worksheets.Add(after:=Worksheets(Worksheets.Count)).cells(1, 1).Resize(.Columns.Count, .Rows.Count) 'this will add a "helper" sheet: it'll be removed
            .PasteSpecial Paste:=xlPasteAll, Transpose:=True
            .Sort key1:=.Columns(1), Order1:=xlAscending, Orientation:=xlTopToBottom, Header:=xlNo 
            .Copy
        End With
        .PasteSpecial Paste:=xlPasteAll, Transpose:=True

        Application.DisplayAlerts = False: Worksheets(Worksheets.Count).Delete: Application.DisplayAlerts = True 'remove the "helper" sheet (it's the (n-1)th sheet)

    End With

End With

End Sub


Function GetColumnsLastRow(rng As Range) As Long
Dim i As Long
'gets last row of the given columns range

GetColumnsLastRow = -1
With rng
    For i = 1 To .Columns.Count
        GetColumnsLastRow = WorksheetFunction.Max(GetColumnsLastRow, .Parent.cells(.Parent.Rows.Count, .Columns(i).Column).End(xlUp).row)
    Next i
End With
End Function

它使用了一个临时的“助手”(它在最后被删除)表。

【讨论】:

  • 非常好的答案。如果需要移动列,这似乎是要走的路。
【解决方案2】:

感谢@SiddharthRout 的建议和修改,我得到了这个:

Sub SortAllColumns()
    Application.ScreenUpdating = False

    Dim ws As Worksheet
    Dim LastRow As Long
    Dim LastColumn As Long
    Dim LastColumnLetter As String

    Set ws = ThisWorkbook.Sheets("mySheet")

    'Get range
    With ws
        LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
        LastColumn = .Cells(1, .Columns.Count).End(xlToLeft).Column
        LastColumnLetter = Split(.Cells(, LastColumn).Address, "$")(1)

       'Sort columns
        Range("C1:" & LastColumnLetter & LastRow).Select
        .Sort.SortFields.Clear
        .Sort.SortFields.Add Key:=Range("C1:" & LastColumnLetter & 1), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal

        With .Sort
            .SetRange ws.Range("C1:" & LastColumnLetter & LastRow)
            .Header = xlYes
            .MatchCase = False
            .Orientation = xlLeftToRight
            .Apply
        End With
    End With

    Application.ScreenUpdating = True
End Sub

【讨论】:

  • 我对您的问题的理解是,您需要通过移动它们来对列进行排序,以便它们的标题从左到右排序。如果这是真的,那么你的代码没有这样做
  • @user3598756 我的问题更清楚了。不,我不想移动列。我的目标是对列进行排序,但要扩展选择,以便同时考虑每列的行值。
  • 那么你最好从你的问题中删除“整个列应该被移动”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-18
  • 1970-01-01
  • 2021-11-02
  • 2015-01-05
  • 2014-12-02
  • 2014-09-26
  • 1970-01-01
相关资源
最近更新 更多