Excel中的自定义宏,具有选择和排序功能

时间:2014-02-21 21:51:05

标签: excel vba excel-vba

我有一个大型Excel文件,其中包含大量需要排序的数据。

第一行包含列标题,第二行包含位置,第三行以数据开头。一旦每个位置的数据结束,就会有一个空白行,然后是下一行中的位置名称,然后是数据。这个过程重复18次。

我正在尝试编写一个宏来开始在A3处抓取数据,这是第一列包含数据的列,并跨越到G列,然后向下直到第一个空白行。找到选择后,它应按C列排序,然后按B列排序。

我已经完成了整个第一次迭代并且正在工作,但是我不知道如何找到下一个数据所在的列。

基本上在每个空白行之后,有一行,然后是数据,这就是我正在寻找的。

我在VBA写这篇文章。

Sub DataCleanup()
'Rows("1:3").EntireRow.Select
'Selection.Delete Shift:=xlUp
For i = 1 To 18
    Range("A3:G" & Range("A1").End(xlDown).Row).Select
    'Sort the rows C, B
    Selection.Sort Key1:=Range("C1"), Order1:=xlAscending, Key2:=Range("B1") _
        , Order2:=xlAscending, Header:=xlGuess, OrderCustom:=1, MatchCase:= _
        False, Orientation:=xlTopToBottom
    Next
End Sub

2 个答案:

答案 0 :(得分:1)

也许这会奏效。我冒昧地删除了硬编码的假设,总是会有18个数据块。这将遍历尽可能多的块,并在它到达工作簿底部时停止。因此,我的假设是,你不希望在18号区块之外找到一些你不希望被分类的东西。

Sub DataCleanup()
Dim TopLeft As Range
Dim SortRange As Range

Set TopLeft = Range("A2")
Do
    Set TopLeft = TopLeft.Offset(1, 0)
    Set SortRange = Range(Range(TopLeft, TopLeft.End(xlDown)), TopLeft.End(xlToRight))
    SortRange.Select ' this line for show only, should be commented out
    SortRange.Sort Key1:=Range("C1"), Order1:=xlAscending, Key2:=Range("B1") _
        , Order2:=xlAscending, Header:=xlGuess, OrderCustom:=1, MatchCase:= _
        False, Orientation:=xlTopToBottom
    Set TopLeft = TopLeft.End(xlDown).End(xlDown)
Loop Until TopLeft.Row = ActiveSheet.Rows.Count
End Sub

注意:

  1. 我将起始位置更改为$A$2。这只是适当地设置循环(假设至少有一个块要排序)。
  2. SortRange.Select可以安全地被注释掉。我只是把它留在那里,以防你想要看到代码在做什么。
  3. Protip:您可能希望将Sort Header参数更改为xlNo,因为数据范围肯定不包含标题。

答案 1 :(得分:1)

"Essentially after each blank line, there is one row, then the data..."  

根据您提供的信息,以下代码假定您不希望在空白行之后对下一行进行排序。

Private Sub SortLocations()

Dim firstAddress As String
Dim lastRow As Long
Dim Rng As Range
Dim R As Range

With ActiveSheet
    'Set the entire range to work with.
    lastRow = Range("A:A").Find("*", searchdirection:=xlPrevious).Row
    Set Rng = .Range("A1:A" & lastRow)

    'Sort the first group of locations.
    .Range("A3:G" & .Range("A1").End(xlDown).Row).Sort _
        Key1:=.Range("C1"), Order1:=xlAscending, _
        Key2:=.Range("B1"), Order2:=xlAscending, _
        HEADER:=xlGuess, OrderCustom:=1, MatchCase:=False, _
        Orientation:=xlTopToBottom

    Set R = Rng.Find(vbNullString)
    If Not R Is Nothing Then
        firstAddress = R.Address
        Do
            'Sort each subsequent group locations.
            .Range(R.Offset(2, 0), .Range("G" & R.Offset(2, 0).Row).End(xlDown)).Sort _
                Key1:=.Range("C" & R.Offset(2).Row), Order1:=xlAscending, _
                Key2:=.Range("B" & R.Offset(2).Row), Order2:=xlAscending, _
                HEADER:=xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
            'Find next empty cell
            Set R = Rng.FindNext(R)
        Loop While Not R Is Nothing And R.Address <> firstAddress
    End If
End With
End Sub

供参考:.FindNext