如何以正确的顺序基于三列对数据列表进行排序?

时间:2019-04-25 14:10:38

标签: excel vba sorting columnsorting

下面您将看到一段代码,该代码用于: 首先,根据第一个“实体”列,第二个“ GREN”列和第三个“ IC”列对数据列表进行排序。然后编译具有相同Entity,GREN和IC列的数据。

由于某种原因,运行代码时出现以下错误:

  

运行时错误'1004':对象'_Global'的方法'Range'失败。

在对其他列进行排序时并没有失败,当我使用较少的数据时,它似乎工作得很好。有人知道哪里出了问题吗?更重要的是如何解决它?

Sub itest()

Dim EntityCol As Long, GRENCol As Long, ICCol As Long, ValueCol As Long, i As Long
Dim firstrow As Long, lastrow As Long, rngData As Range

Worksheets("FC_OUTPUT").Activate
Application.ScreenUpdating = False

EntityCol = 4 ' column D
GRENCol = 8
ICCol = 9
ValueCol = 12 ' column L
firstrow = 7
lastrow = Cells(Rows.Count, EntityCol).End(xlUp).Row

With ActiveSheet.Sort
     .SortFields.Add Key:=Range(Cells(firstrow, EntityCol)), Order:=xlAscending
     .SortFields.Add Key:=Range(Cells(firstrow, GRENCol)), Order:=xlAscending
     .SortFields.Add Key:=Range(Cells(firstrow, ICCol)), Order:=xlAscending
     .SetRange Range(Cells(firstrow, 1), Cells(lastrow, 96))
     .Header = xlNo
     .Apply
End With


Set rngData = Range(Cells(firstrow, 1), Cells(lastrow, 96)) ' this line should be adjusted but you'll need to also adjust firstrow and lastrow

With rngData
' Here I'll start a loop for every row going from the end to the beginning, to prevent issues when removing rows
    For i = lastrow To firstrow Step -1
    ' Here I'll use the If statement to check if the values are the same as the previous row

        If .Cells(i, EntityCol) = .Cells(i - 1, EntityCol) And _
                .Cells(i, GRENCol) = .Cells(i - 1, GRENCol) And _
                .Cells(i, ICCol) = .Cells(i - 1, ICCol) Then
            ' This is where you'll do your addition and delete
            .Cells(i - 1, ValueCol).Value2 = .Cells(i - 1, ValueCol) + .Cells(i, ValueCol)
            .Rows(i).Delete
        End If
    Next i
End With

End Sub

1 个答案:

答案 0 :(得分:0)

这就是我要做的:

Sub tgr()

    Const lEntityCol As Long = 4    'Column D
    Const lGRENCol As Long = 8      'Column H
    Const lICCol As Long = 9        'Column I
    Const lValueCol As Long = 12    'Column L
    Const lDataStartRow As Long = 7 'Actual data (not headers) starts on row 7

    Dim ws As Worksheet
    Dim rData As Range
    Dim rDel As Range
    Dim hUnq As Object
    Dim aData As Variant
    Dim sTemp As String
    Dim sDelim As String
    Dim i As Long

    Set ws = ActiveWorkbook.Worksheets("FC_OUTPUT")
    Set rData = ws.Range("A" & lDataStartRow & ":CR" & ws.Cells(ws.Rows.Count, lEntityCol).End(xlUp).Row)
    Set hUnq = CreateObject("Scripting.Dictionary")
    sDelim = "|"    'This is a character that will not be in your data

    With rData
        If .Row < lDataStartRow Then Exit Sub   'No data
        .Sort Key1:=Intersect(.Cells, ws.Columns(lEntityCol)), Order1:=xlAscending, _
              Key2:=Intersect(.Cells, ws.Columns(lGRENCol)), Order2:=xlAscending, _
              Key3:=Intersect(.Cells, ws.Columns(lICCol)), Order3:=xlAscending, _
              Header:=xlNo
        aData = .Value
    End With

    For i = LBound(aData, 1) To UBound(aData, 1)
        If Len(Trim(aData(i, lEntityCol))) > 0 _
        And Len(Trim(aData(i, lGRENCol))) > 0 _
        And Len(Trim(aData(i, lICCol))) > 0 Then
            sTemp = LCase(Trim(aData(i, lEntityCol))) & sDelim & LCase(Trim(aData(i, lGRENCol))) & sDelim & LCase(Trim(aData(i, lICCol)))
            If Not hUnq.exists(sTemp) Then
                'New unique combination of Entity, GREN, and IC found
                hUnq.Add sTemp, sTemp

                'Get the total sum of values for the unique combination
                rData.Cells(i, lValueCol).Value = WorksheetFunction.SumIfs(ws.Columns(lValueCol), _
                                                                           ws.Columns(lEntityCol), aData(i, lEntityCol), _
                                                                           ws.Columns(lGRENCol), aData(i, lGRENCol), _
                                                                           ws.Columns(lICCol), aData(i, lICCol))
            Else
                'Not a new unique combination, add it to the list of rows to be deleted
                If rDel Is Nothing Then Set rDel = rData.Cells(i, 1) Else Set rDel = Union(rDel, rData.Cells(i, 1))
            End If
        End If
    Next i

    If Not rDel Is Nothing Then rDel.EntireRow.Delete

End Sub