【问题标题】:Sorting blocks of data in Excel在 Excel 中对数据块进行排序
【发布时间】:2021-08-12 20:42:21
【问题描述】:

我的 Excel 数据格式如下例所示,信息块分布在 3 行中。有没有办法通过块中的一条数据对列进行排序?即按教师或房间对 A 列中的块进行排序?

Column A Column B Column C
ClassA/Sc ClassA/Sc ClassB/Sp
Teacher A Teacher A Teacher B
Room 1 Room 1 Room 2
ClassA/Hi ClassA/En ClassB/Sp
Teacher C Teacher D Teacher B
Room 3 Room 4 Room 2
ClassA/Re ClassA/Ge ClassB/Ru
Teacher C Teacher B Teacher F
Room 5 Room 2 Room 3

我精通 VBA,但我想不出任何可以用于这种数据排列的排序方法。

非常感谢您的帮助。

编辑:结果将根据列出的字符之一对每一列进行独立排序,因此在上面的数据中,可以看到 A 列已按 Room (1,3,5) 排序,而 B 列不是(1,4,2)。

【问题讨论】:

  • 预期的结果是什么?
  • 我已经编辑了这个问题,试图给出更多的想法。

标签: excel vba sorting


【解决方案1】:

编辑:当我开始发帖时,没有看到已经接受的答案。我将保留此答案作为替代方法。


由于我们知道在将数据添加到数组时需要对其进行排序,因此我只使用可用的排序列表类之一。您必须包含有关记录高度的一些信息,以及有关如何将其存储回工作表的一些详细信息。

在下面的示例中,我使用了 SortedList 类。一个函数获取我们想要排序的记录“字段”。因此,如果要根据 Class 进行排序,请为第一个元素传入 1。对于老师,第二个元素传递 2 等等。(我肯定会包括一些边界检查以确保有人不会传递太大的数字。

由于数据最终排序,您只需将数据推回工作表即可。

如果您有任何后续问题,请告诉我。

Const HEIGHT_OF_RECORD As Integer = 3

Private Function SortColumnCuston(rng As Range, nSortElement As Integer) As Object
    Dim oList As Object
    Dim oTempDict As Object
    Dim startingCell As Range
    
    'Below just takes the first cell of the passed range and stores it to a variable
    'Doesn't matter if it's actually range("A1")
    Set startingCell = rng.Range("A1")
    
    Set oList = CreateObject("System.Collections.SortedList")
    
    For i = 0 To rng.Rows.Count - HEIGHT_OF_RECORD Step HEIGHT_OF_RECORD
        Set oTempDict = CreateObject("Scripting.Dictionary")
        oTempDict.Add "Class", startingCell.Offset(i).Value
        oTempDict.Add "Teacher", startingCell.Offset(i + 1).Value
        oTempDict.Add "Room", startingCell.Offset(i + 2).Value
        
        oList.Add rng.Range("A1").Offset(i + nSortElement - 1).Value, _
            oTempDict
    Next i
    
    Set SortColumnCuston = oList
End Function

Sub Test()
    Dim oDang As Object
    Dim sortDestinationStart As Range
    
    Set oDang = SortColumnCuston(Range("A1:A9"), 3)
    
    'This is where you want to paste the sorted data.
    'Note: it WILL overwrite what's there now, so be aware
    'of formulas, etc.
    Set sortDestinationStart = Range("F1")
    
    For i = 0 To oDang.Count - 1
        sortDestinationStart.Offset(i * HEIGHT_OF_RECORD).Value = _
            oDang.GetByIndex(i)("Class")
        sortDestinationStart.Offset(i * HEIGHT_OF_RECORD + 1).Value = _
            oDang.GetByIndex(i)("Teacher")
        sortDestinationStart.Offset(i * HEIGHT_OF_RECORD + 2).Value = _
            oDang.GetByIndex(i)("Room")
    Next i
End Sub

【讨论】:

    【解决方案2】:

    我的处理方法是将所有数据收集到一个数组中,并确保我拥有属于同一“行”的所有数据加上列字母...

    那么第一行将如下所示: A, ClassA/Sc, 老师 A, Room 1

    然后我会使用冒泡排序功能以正确的顺序获取数据,然后在工作表上再次打印数据..

    我不确定这是否可行,但对我来说这听起来是个好主意:)

    你怎么看?

    【讨论】:

    • 这可能是一个选项,但我不确定之后如何根据新排序的数组对单元格进行排序。然后我可能会粘贴回我认为的范围内......我必须试一试!
    • 是的,正是我的意思,只需在工作表上再次打印数据即可。祝你好运!
    猜你喜欢
    • 2014-02-23
    • 1970-01-01
    • 2013-08-22
    • 2013-07-25
    • 2015-03-17
    • 2022-11-21
    • 2012-10-19
    • 2018-02-09
    • 1970-01-01
    相关资源
    最近更新 更多