参照URL:
『 How to Use a Visual Basic Macro to Sort Arrays in Excel 』
上記ページによると
VBAで配列を直接ソートする方法はないようです。
代わりに2つの方法
Selection Sort
Bubble Sort
が例示されています。
訳して簡単に説明します。
Selection Sort
プログラムするのが簡単だが、
大きい配列ではthe Bubble Sortより遅い。
要素が1からnまでの配列でSelection Sortをする。
この配列の1からnまでの中で一番大きい要素を見つける。
これがn番目の要素でない(Indexがnより小さい)なら、
これをn番目と入れ替える。
それから、
1からn-1までの中で一番大きい要素を見つける。
これがn-1番目の要素でないなら、
これをn-1番目と入れ替える。
…
1から2までの中で一番大きい要素を見つける。
これが2番目の要素でないなら、
これを2番目と入れ替える。
Bubble Sort
Selection Sortよりプログラムするのが難しいが、
大きい配列をソートする場合はより速く効果的の傾向。
1からn-1までの要素をそれぞれ次の要素と比較し
次の要素のほうが小さいなら入れ替える。
これを入れ替えがなくなるまで繰り返す。
以上で訳終了。
Function SelectionSort、
Function BubbleSortNoteは共に昇順で並び替える方法で、
最後のほうのNoteで降順にする方法が書かれています。
昇順(ascending order)
降順(descending order)
この2つ
いつもどっちが大きいほうからで
どっちが小さいほうからか考えてしまします。
昇順が列の上から下の方向へ大きくなっていく、
降順が列の上から下の方向へ小さくなっていく。
言い換えると、
昇順が列の一番上に小さいものが来て、
降順が列の一番上に大きいものが来る。
列の”下へ向って昇っていく”というところが
感覚と合わないところですね。
さて
Function SelectionSort、Function BubbleSortNoteを改造して
昇順、降順を1つのプロシージャでできるようにします。
それには、引数Orderを1つ増やして
昇順、降順を指定します。
Order = 0 を昇順、
Order = 1を降順にします。
これをIf文で分岐するだけのことです。
コードはこちら
Selection Sortするコード:Function SelectionSort2(TempArray As Variant, Order As Integer) 'Option Base 1で実行 'Order = 0 昇順 'Order = 1 降順
Dim MaxVal As Variant '最大値/最小値 Dim MaxIndex As Integer Dim i, j As Integer If Order <> 0 And Order <> 1 Then MsgBox "Orderは0か1を指定してください。" Exit Function End If ' 配列の後ろから前へ For i = UBound(TempArray) To 1 Step -1
'配列の最大要素の値とインデックス MaxVal = TempArray(i) MaxIndex = i
' 残りの要素とMaxValを比較しMaxValより大きいなら 'その要素をMaxValにする For j = 1 To i If Order = 0 Then '昇順 If TempArray(j) > MaxVal Then MaxVal = TempArray(j) MaxIndex = j End If ElseIf Order = 1 Then '降順 If TempArray(j) < MaxVal Then MaxVal = TempArray(j) MaxIndex = j End If End If Next j
' 残りの要素の最大要素のインデックスがiでないなら 'その要素とiを入れ替える If MaxIndex < i Then TempArray(MaxIndex) = TempArray(i) TempArray(i) = MaxVal End If Next i
End Function
Sub macro110101b() 'SelectionSort2使用例
Sheets.Add Dim TheArray As Variant Dim i As Integer ' ソートする配列 TheArray = Array(15, 8, 11, 7, 33, 4, 46, 19, 20, 27) Range("A1") = "SelectionSort元" For i = 1 To 10 Cells(i + 1, 1) = TheArray(i) Next i
' ソート(昇順) Call SelectionSort2(TheArray, 0) Range("B1") = "昇順" For i = 1 To 10 Cells(i + 1, 2) = TheArray(i) Next i ' ソート(降順) Call SelectionSort2(TheArray, 1) Range("C1") = "降順" For i = 1 To 10 Cells(i + 1, 3) = TheArray(i) Next i End Sub |
Bubble Sortするコード:Function BubbleSort2(TempArray As Variant, Order As Integer) 'Option Base 1で実行 'Order = 0 昇順 'Order = 1 降順
Dim Temp As Variant Dim i As Integer Dim NoExchanges As Integer
' ループの終わりでNoExchanges = Trueで終了 Do NoExchanges = True
For i = 1 To UBound(TempArray) - 1 If Order = 0 Then '昇順 If TempArray(i) > TempArray(i + 1) Then NoExchanges = False Temp = TempArray(i) TempArray(i) = TempArray(i + 1) TempArray(i + 1) = Temp End If ElseIf Order = 1 Then '降順 If TempArray(i) < TempArray(i + 1) Then NoExchanges = False Temp = TempArray(i) TempArray(i) = TempArray(i + 1) TempArray(i + 1) = Temp End If End If Next i Loop While Not (NoExchanges)
End Function
Sub macro110101a() 'BubbleSort2使用例
Sheets.Add Dim TheArray As Variant Dim i As Integer ' ソートする配列 TheArray = Array(15, 8, 11, 7, 33, 4, 46, 19, 20, 27) Range("A1") = "BubbleSort元" For i = 1 To 10 Cells(i + 1, 1) = TheArray(i) Next i
' ソート(昇順) Call BubbleSort2(TheArray, 0) Range("B1") = "昇順" For i = 1 To 10 Cells(i + 1, 2) = TheArray(i) Next i ' ソート(降順) Call BubbleSort2(TheArray, 1) Range("C1") = "降順" For i = 1 To 10 Cells(i + 1, 3) = TheArray(i) Next i End Sub |
macro110101a実行後のシート
上の2つの方法は1次元配列しかソートできないので
使いにくいです。
それにしてもBubble Sortってなんで
バブルという名前なんでしょうか?
たくさんクルクルするからなんでしょうかね~
コメント
Bubble Sortするコードなのですが、エラーになりました。
配列の範囲が0~9なのにソートのときに
For i = 1 To 10と指定していて
TheArray(10)が存在しないのでエラーになるようです。
上記を修正しても、類似内容の問題が別にありました。
For i = 1 To UBound(TempArray) - 1
以下の範囲のTempArray(i)も、
TempArrayは0~9なので描かれているものだと
配列の1~8で並べ返してしまい並べ替え範囲から
もれている配列があって綺麗にならびませんでした。
追記:管理人やむえむ
コメントありがとうございます。
現在、トラブルで別のコメントで返信できないので、
こちらのコメント内にて返信いたします。
上記コードは
「Option Base 1」で実行してください。
通常、配列の番号は0から始まります。
「Option Base 1」と指定することで、
配列の番号を1から始めることを指定できます。
「Option Base 1」で実行するには、
コードの一番上に「Option Base 1」と入力してください。
今後とも
当ブログをよろしくお願いします。
投稿: 通りすがり | 2012年12月14日 (金) 12時13分
バブルソートはターゲット値が水中の泡のように浮いていくからそう呼ばれてます。
投稿: | 2013年4月 2日 (火) 14時57分