【问题标题】:Excel VBA to auto update sort, sort on multiple columns, AND apply to a "specific range"Excel VBA 自动更新排序,对多列进行排序,并应用于“特定范围”
【发布时间】:2021-09-03 21:22:44
【问题描述】:

除了应用于特定范围之外,我有以下代码可以执行我想要的操作。换句话说,它确实对多列进行排序,并在数据更改时自动更新:

Private Sub Worksheet_Change(ByVal Target As Range)
On Error Resume Next
If Not Intersect(Target, Range("D3:F")) Is Nothing Then
Columns("A:Z").Sort Key1:=Range("F3"), Key2:=Range("E3"), Key3:=Range("D3"), _
Order1:=xlAscending, Order2:=xlAscending, Order3:=xlAscending, Header:=xlYes, _
OrderCustom:=1, MatchCase:=False, _
Orientation:=xlTopToBottom
End If
End Sub

但是,它的作用是将其应用于“A:Z”的整个范围,而我希望它仅应用于特定范围(例如“A3:Z”)。

我对 Excel VBA 的了解非常有限,并且做了我认为的解决方案,将 Columns("A:Z").Sort 更改为 Columns("A3:Z").SortRange("A3:Z").Sort,但在此更改后代码停止工作。

任何帮助将不胜感激!

【问题讨论】:

  • "A3:Z" 在 VBA 中没有任何意义。事实上,你想做什么?是否要使用从 A3 到 Z:Z 列的最后一个单元格的范围?工作表中的所有列的行数是否相同?
  • 是的,尝试使用您所描述的内容。是的,它们都有相同的行数。
  • 那么,请尝试我在回答中推荐的解决方案。

标签: excel vba sorting


【解决方案1】:

请尝试替换

Columns("A3:Z").Sort

Range("A3:Z" & Range("A" & Rows.count).End(xlUp).Row).Sort

这会将范围设置为从 A3 开始排序到 Z:Z 列中的最后一个单元格,但基于 A:A 列中的最后一个单元格。

已编辑:

您的事件代码应如下所示:

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
 If Not Intersect(Target, Range("D3:F" & Rows.Count)) Is Nothing Then
    Range("B2:Z" & Range("A" & Rows.Count).End(xlUp).Row + 1).Sort Key1:=Range("F2"), Key2:=Range("E2"), Key3:=Range("D2"), _
                                                            Order1:=xlAscending, Order2:=xlAscending, Order3:=xlAscending, Header:=xlYes, _
                                                            OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
 End If
End Sub

请复制上面的代码而不是您的代码并进行测试。当然,当您设置第二行的范围时,Keys 也应该适应这一行。而且您的代码应该永远不会使用Range("D3:F") 到达排序部分。

除此之外,您绝不应该使用On error resume next,直到您有一个工作代码并且需要在那之后来创建错误处理程序。否则,它只会让你看到代码真正的问题/错误......

已编辑:

您也可以使用下一种方法(使用SortFields):

Private Sub Worksheet_Change(ByVal Target As Range)
 If Not Intersect(Target, Range("D3:F" & Rows.Count)) Is Nothing Then
    With ActiveSheet
        .Sort.SortFields.Clear
        .Sort.SortFields.Add2 Key:=Range("F3:F" & Rows.Count) _
                 , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        .Sort.SortFields.Add2 Key:=Range("E3:E" & Rows.Count) _
            , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        .Sort.SortFields.Add2 Key:=Range("D3:D" & Rows.Count) _
            , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        With .Sort
            .SetRange Range("B2:Z" & Range("B" & Rows.Count).End(xlUp).Row + 1)
            .Header = xlYes
            .MatchCase = False
            .Orientation = xlTopToBottom
            .SortMethod = xlPinYin
            .Apply
        End With
  End With
 End If
End Sub

我认为您应该在其中之一中进行选择是显而易见的。如果它们都在工作表代码模块上,则会引发错误...

【讨论】:

  • 感谢您的回答。它不起作用。 (另外,我在 .Sort 之前添加了一个“)”,我猜它不见了?
  • @lovestacksflow 不,不...请刷新页面(这个)并查看我建议的真实代码。第一次,我只是复制了你的错误代码,并且错误地保留了“Columns(”......
  • 再次感谢。它现在可以工作,但是当在第 4 行添加新条目时不会自动更新
  • 很抱歉让您头疼,但如果有可能查看示例文件,我本质上想要做的是保留列标题而不将列标题放在第一行并使用Header:=xlYes
  • @lovestacksflow 它应该“自动更新”。它始终确定最后一个现有行,并构建从第三行开始到最后一个包含值的范围。无论如何,我不明白在哪里查看“示例文件”......
【解决方案2】:

如果像我这样天真的人也有同样的问题,下面是可行的方法:

Private Sub Worksheet_Change(ByVal Target As Range)
On Error Resume Next
If Not Intersect(Target, Range("D3:F")) Is Nothing Then
Range("A3", Range("Z3").End(xlDown)).Sort Key1:=Range("F3"), Key2:=Range("E3"), Key3:=Range("D3"), _
Order1:=xlAscending, Order2:=xlAscending, Order3:=xlAscending, Header:=xlNo, _
OrderCustom:=1, MatchCase:=False, _
Orientation:=xlTopToBottom
End If
End Sub

将公式应用于 A3 下面的所有行

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-03
    • 2014-02-22
    • 1970-01-01
    • 1970-01-01
    • 2018-03-29
    • 1970-01-01
    • 1970-01-01
    • 2015-12-27
    相关资源
    最近更新 更多