0

我创建的函数有 2 个问题。首先是二维数组上 2 列的冒泡排序(降序排序 - 首先是第 2 列,然后是第 1 列)。我相信我已经正确地实施了这一点,但结果往往不同。

输入
COL 1 COL 2
35.484%38.296%
1.075%0.112%
1.075%0.056%
48.387%0.124%
1.075%0.005% 2.151
%0.051%
2.151%0.006%
2.151%0.002%
3.226%0.003%
1.075%0.032%
1.075%0.184%
1.075 % 0.263%

输出
35.484%38.296%
48.387%0.124%
1.075%0.112% 2.151
%0.051%
2.151%0.006%
1.075%0.056%
3.226%0.003%
1.075%0.005%
1.075%0.032%
1.075%0.184%
2.151%0.002%
1.075%0.263%

您可以立即看到,输出的最后一行应该位于更高阶的某个位置。

而且我无法将整个数组输出到一个范围。没有显示错误,函数简单地退出。我很感激这方面的任何帮助。代码如下所示,再次感谢。

    Function larger(range1 As Range, range2 As Range)

    Dim Q() As Variant
    Dim x As Range, y As Range
    Dim i As Integer, j As Integer
    Dim varTemp(1 To 2) As Variant



    Q = Range(range1.address, range2.address)
    ReDim Q(1 To UBound(Q, 1), 1 To UBound(Q, 2))

    j = 1
    i = 1
    While i < UBound(Q, 1)
        For Each x In range1
            While j < UBound(Q, 2)
                Q(i, j) = x
                j = j + 1
                Q(i, j) = range2(i)
            Wend

            i = i + 1
            j = 1
        Next
    Wend


 ' Bubble sort  - first with the 2nd col and then the 1st col

 '2nd col
    For i = LBound(Q) To UBound(Q) - 1

            If Q(i, 2) < Q(i + 1, 2) Then

                For j = 1 To 2
                    varTemp(j) = Q(i, j)
                    Q(i, j) = Q(i + 1, j)
                    Q(i + 1, j) = varTemp(j)
                Next j
            End If
        Next

   '1st col
    For i = LBound(Q) To UBound(Q) - 1
          If Q(i, 1) < Q(i + 1, 1) Then
            For j = 1 To 2

                varTemp(j) = Q(i, j)
                Q(i, j) = Q(i + 1, j)
                Q(i + 1, j) = varTemp(j)
            Next j
            End If
        Next



  j = 1
 For i = LBound(Q, 1) To UBound(Q, 1)
    MsgBox (Q(i, j) & " " & Q(i, j + 1))

 Next
    MsgBox ("end")


Range("P3:Q14") = Q         'Not writing entire queue into specified range

End Function
4

1 回答 1

0

首先,要对范围进行排序,最简单的方法是使用 Excel 内置的 Sort 方法!因此,试试这个方法:

Sub SortRange(rng As Range)
    rng.Sort rng.Resize(, 1).Offset(, 1), xlAscending, rng.Resize(, 1)
End Sub

你可以这样称呼它:SortRange Range("A1:B12")

如果您想自己对它进行排序以迎合某些专业,这里是冒泡排序:

Sub Sort(rng As Range)
    Dim varValues As Variant
    Dim i As Long, j As Long

    varValues = rng.Cells

    For i = 1 To UBound(varValues, 1)
        For j = i + 1 To UBound(varValues, 1)
            Select Case varValues(i, 2)
                Case Is > varValues(j, 2): subSwap varValues, i, j
                Case varValues(j, 2):
                    If varValues(i, 1) > varValues(j, 1) Then subSwap varValues, i, j
            End Select
        Next j
    Next i

    rng.Cells = varValues
End Sub

Private Sub subSwap(varValues As Variant, i As Long, j As Long)
    Dim varTemp As Variant
    Dim k As Long

    For k = 1 To UBound(varValues, 2)
        varTemp = varValues(i, k)
        varValues(i, k) = varValues(j, k)
        varValues(j, k) = varTemp
    Next
End Sub

查看您的代码,我注意到了一些事情(这就是为什么我从头开始重新制作而不是“修复”您的代码):

  • 而不是Range(range1.address, range2.address)你可以使用Range(range1, range2),或者事件更好,将其声明为一个完整的范围(例如 Range("A1:B12")` 直接。此外,使用 range1.Resize(,2) 将调整大小为两列范围
  • 您的整个第一个循环似乎有点多余并且可能是错误的(至少您总是将 range1 中的值分配给所有列)。通常,您可以使用varArray = YourRange.Cells. 无需重新调整。
  • 在冒泡排序中,您需要在第一个循环中嵌套要检查的列的检查。否则,当首先要检查的列有更多具有相同值的 2 行时,您可能会得到错误的结果
  • 将数组分配回范围时,最好分配给Range.Cells. 此外,请确保范围具有相同的维度。
  • 最后但并非最不重要的一点是,您使您的子灵活,即允许任何参数 - 但然后将结果分配给硬编码范围。当您使用其他范围调用它时,这将失败 - 或者您的工作簿结构发生变化!也更好地灵活处理(例如使用 `Range("NamedRangeName").Resize(UBound(Q, 1), UBound(Q,2)).Cells = Q
于 2013-03-25T20:43:22.063 回答