Excel VBA如何对单行范围进行排序

时间:2016-11-13 05:42:07

标签: excel vba excel-vba

我将范围定义为

Set myRange=Range("$E$10,$G$10,$I$10")

这些单元格中的值 -1,-1.2,1 当我遍历范围时,我得到了打印的值 顺序 -1,-1.2,1

我想对这个范围进行排序,以便在迭代范围时 我会看见: -1.2,-1,1

我不想在实际工作表中重新组织这些单元格。

我基本上试图用普通的编程语言模仿排序函数,但是对于Excel范围,我期望'单元'在范围数据结构中重新排列

我尝试过天真的

myRange.Sort key1:=myRange.Item(1, 1), order1:=xlAscending, Header:=xlNo

但它没有做任何事情

2 个答案:

答案 0 :(得分:3)

Excel不会对非连续范围进行排序。

但是使用ArrayList对值进行排序很容易按顺序获取范围值。使用SortAnyRange并将Desc参数设置为true将按降序对范围进行排序。

enter image description here

仅限WINDOWS

Sub TestSortAnyRange()
    SortAnyRange Range("$E$10,$G$10,$I$10")
End Sub

Sub SortAnyRange(Target As Range, Optional Desc As Boolean)
    Dim r As Range
    Dim list As Object
    Set list = CreateObject("System.Collections.ArrayList")
    For Each r In Target
        list.Add r.Value
    Next

    list.Sort

    If Desc Then list.Reverse

    For Each r In Target
        r.Value = list(0)
        list.Remove list(0)
    Next

End Sub

MAC或WINDOWS

OP要求提供可在Mac或Windows平台上运行的子程序。出于这个原因,我重构了我的代码,用数组和BubbleSort例程替换ArrayList(在Mac上不可用)。

Sub SortAnyRange(Target As Range, Optional Desc As Boolean)
    Dim r As Range
    Dim list
    Dim i As Long, j As Long

    ReDim list(0 To Target.Cells.Count - 1)

    For Each r In Target
      list(i) = r.Value
      i = i + 1
    Next

    For i = LBound(list) To UBound(list)
        For j = i + 1 To UBound(list)
            If list(i) > list(j) Then
                SrtTemp = list(j)
                list(j) = list(i)
                list(i) = SrtTemp
            End If
        Next j
    Next i

    i = IIf(Desc, UBound(list), 0)

    For Each r In Target
        r.Value = list(i)
        i = i + IIf(Desc, -1, 1)
    Next

End Sub

答案 1 :(得分:0)

在OP澄清目标操作系统(Windows和MAC OS)并且他/她实际上希望细胞“重组”之后

已编辑

我使用Range对象的excel Sort()方法并利用其所有内置功能

为此,我将使用“帮助器”范围,将传递的范围值放入,排序,并将排序值从后面传递到传递范围,如下所示:

Sub OrderRange(rng As Range)
    Dim cell As Range
    Dim iCell As Long

    With rng.Parent.UsedRange
        With .Resize(1, 1).Offset(, .Columns.Count)
            For Each cell In rng '<-- fill "helper" range with passed range values
                .Offset(iCell).Value = cell.Value
                iCell = iCell + 1
            Next cell
            .Resize(iCell).Sort key1:=.Range("A1"), order1:=xlAscending, Header:=xlNo '<-- sort "helper" range values
            iCell = 0
            For Each cell In rng '<-- write sorted "helper" range values back to passed range
                cell.Value = .Offset(iCell).Value
                iCell = iCell + 1
            Next cell
            .Resize(iCell).ClearContents '<--| clear "helper" range
        End With
    End With
End Sub

用作:

OrderRange Range("$E$10,$G$10,$I$10")