【问题标题】:Most efficient way to sort and sort syntax VBA对语法VBA进行排序和排序的最有效方法
【发布时间】:2014-10-13 22:35:34
【问题描述】:

我对 Excel 的 VBA 宏非常陌生。到目前为止,这个网站非常有帮助。 我有一个宏,它在最后一列之后添加四个列标题,然后如果满足某个条件,则填充这些列,该部分工作正常。在可以填充列之前,我需要对数据进行排序。我目前对数据进行排序的方法是基于记录宏并更改所需的变量。我读过,经常 excel 非常低效地记录宏。我有点像弗兰肯斯坦在一起。以下代码有效。

Sub ineffiecientway()
Dim colltr As String
colltr = Replace(Cells(1, LastColumn).Address(True, False), "$1", "") '<-Input column index, returns column letter
Columns("A:" & colltr).Select
ActiveWorkbook.Worksheets("DSEG").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("DSEG").Sort.SortFields.Add Key:=Range("A:A") _
    , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("DSEG").Sort.SortFields.Add Key:=Range("J:J") _
    , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
    xlSortTextAsNumbers
With ActiveWorkbook.Worksheets("DSEG").Sort
    .SetRange Range("A:" & colltr)
    .Header = xlYes
    .MatchCase = False
    .Orientation = xlTopToBottom
    .SortMethod = xlPinYin
    .Apply
End With

下面的代码是我一直在处理的,并且把我的头发拉出来了。我确信我犯了一百万个新手错误。我认为这可能与我失败的 .sort 语法有关。

注意:

  • GCI() 是一个用户定义的函数,它在第一行搜索输入并返回列索引

  • LastRow() 是一个用户定义的函数,它返回输入的列索引的最后一行。

  • LastColumn 只返回第一行中最后使用的列

    Sub ThisDoesntWork()
    Dim ws As Worksheet
    Dim rngAll As Range
    Dim Col1 As Long 'for sort key1
    Dim Row1 As Long
    Dim Col2 As Long 'for sort key2
    Dim Row2 As Long
    Dim rng1 As Range
    Dim rng2 As Range
    Dim LastCell As Range
    
    Set ws = Worksheets("DSEG")
    Set LastCell = ws.Cells(LastRow(LastColumn), LastColumn)
    Col1 = GCI("CDate")
    Row1 = LastRow(Col1)
    Col2 = GCI("Start Time")
    Row2 = LastRow(Col2)
    
    
    Set rngAll = ws.Range(ws.Cells(1, 1), LastCell)
    Set rng1 = ws.Range(ws.Cells(1, Col1), ws.Cells(Row1, Col1))
    Set rng2 = ws.Range(ws.Cells(1, Col2), ws.Cells(Row2, Col2))
    
    
    MsgBox rng1.Address
    MsgBox rng2.Address
    MsgBox rngAll.Address
    
    With rngAll
    .Sort key1:=Range(rng1), order1:=xlAscending, DataOption1:=xlSortNormal, _
    key2:=.Range(rng2), order2:=xlAscending, DataOption2:=xlSortTextAsNumbers, _
    Header:=xlYes
    End With
    

当我运行此代码时,它会在“.sort”处停止并显示错误“运行时错误'1004':对象'_Global'的方法“范围”失败 我也尝试过使用“DataOption1:=xlSortNormal”,因为我不认为第一个范围需要将文本排序为数字,两者都会导致相同的错误。 我在没有设置范围或“调光”工作表的情况下尝试上面的代码,并认为在运行代码之前设置范围会有所帮助。 我为范围添加了 MsgBox 以确保它们是我想要的范围。

  • 第一个 MsgBox 返回 $A$1:$A$38061

  • 第二个 MsgBox 返回 $J$1:$J$38061

  • 第三个 MsgBox 返回 $A$1:$S$38061

前两个是我要排序的范围,最后一个是我要排序的所有数据的范围,这些是正确的范围。

非常感谢您提供任何建议或帮助来完成这项工作。另外,任何关于更好发布的建议,因为我确信“正确的发布格式”也犯了错误。

编辑:谢谢 Nanashi,我不会重复功能,我很感激这个提示。
谢谢吉普。当前区域位清理了很多。正是 .columns 修复了错误(我正在尝试 .range),感谢你们俩。工作代码如下。

Dim ws As Worksheet
Dim Col1 As Long 
Dim Col2 As Long 
Set ws = Worksheets("DSEG")
Col1 = GCI("CDate") 'searches string and returns column index
Col2 = GCI("Start Time") 'searches string and returns column index

With ws.Cells(1, 1).CurrentRegion.Cells
.Sort key1:=.Columns(Col1), order1:=xlAscending, DataOption1:=xlSortNormal, _
      key2:=.Columns(Col2), order2:=xlAscending, DataOption2:=xlSortTextAsNumbers, Header:=xlYes
End With

【问题讨论】:

  • 风格方面,不要重复使用你的函数。它使代码混乱并降低了可读性。例如,将GCI("CDate") 分配给一个变量。之后代码会被清理干净,你会更容易调试。

标签: excel vba


【解决方案1】:

通常,我 .Sort 的任何区域都没有任何完全空白的行或列破坏 .CurrentRegion,因此我使用它来定义要排序的范围。 .Cells(1,1).CurrentRegion 相当于选择 A1 并点击 Ctrl+A。它包含从 A1 扩展到右侧完全空白列或向下完全空白行的孤岛数据。

Sub prettyefficient()
    With Sheets("DSEG").Cells(1, 1).CurrentRegion.Cells
        .Sort Key1:=.Columns(1), Order1:=xlAscending, DataOption1:=xlSortTextAsNumbers, _
              Key2:=.Columns(10), Order2:=xlAscending, DataOption2:=xlSortTextAsNumbers, _
              Orientation:=xlTopToBottom, Header:=xlYes
    End With
End Sub

您可以在单个命令中使用最多三个键(Key1Key2Key3)。如果您需要更多,请将其分成两个命令。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-07
    • 1970-01-01
    • 2013-05-10
    • 1970-01-01
    • 2021-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多