0

作成した関数に 2 つの問題があります。1 つ目は、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.035%0.035% 0.035%
0.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% 0.184%0.184%0.184%0.184%0.184%0.184%
0.184%
0.184%

すぐにわかるように、出力の最後の行は上位のどこかにあるはずです。

また、配列全体を範囲に出力することはできません。エラーは表示されず、関数は単に終了します。これで何か助けていただければ幸いです。コードを以下に示します。ありがとうございます。

    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 の組み込みの並べ替えメソッドを使用するのが最も簡単です。したがって、次の方法を試してください。

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) を使用すると、2 列の範囲にサイズ変更されます
  • 最初のループ全体が少し冗長で、おそらく間違っているようです (少なくとも、常に range1 の値をすべての列に割り当てます)。通常、 を使用して配列に全範囲を割り当てることができますvarArray = YourRange.Cells。リダイムする必要はありません。
  • バブル ソートでは、最初のループで 2 番目にチェックされる列のチェックをネストする必要があります。それ以外の場合、最初にチェックする列に同じ値の 2 つの行が複数ある場合、間違った結果が得られる可能性があります。
  • 配列を範囲に割り当てるときは、より適切に に割り当てRange.Cellsます。また、範囲が同じ次元であることを確認してください。
  • 最後になりましたが、サブを柔軟にします。つまり、任意のパラメーターを許可しますが、結果をハードコードされた範囲に割り当てます。これは、他の範囲で呼び出すと失敗します-またはワークブックの構造が変更されます! これもより柔軟にします (たとえば、`Range("NamedRangeName").Resize(UBound(Q, 1), UBound(Q,2)).Cells = Q を使用します)。
于 2013-03-25T20:43:22.063 に答える