これを書けばVBAの基本的な文法が一気に勉強できちゃうんだよ
バブルソートとは、ソートアルゴリズムの一つで、隣り合う数字の大小を比較して並び替えていく方法です。
これらのメジャーな文法が一度に勉強できちゃうお題なのです。
- 配列処理
- If~End If(条件分岐)
- For~Next(繰り返し処理)
- Do~Loop(繰り返し処理)
- セルへの書き込み処理
さぁ、みてみましょう。
Contents
バブルソートのプログラム
エクセルシートのA1セルを起点として適当な数字を入力し、マクロを実行すると、1行目の数列を小さい順に並べ替えた結果が2行目に書き込まれる仕組みです。
コードがこちらです
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
Option Base 1 Sub VBAでバブルソート() 'ソート対象のデータ数を特定 Dim n As Long n = Cells(1, 1).End(xlToRight).Column '数列を格納する配列の準備 Dim arrNum() As Long ReDim arrNum(n) 'ソート対象の数字を配列に格納 Dim i As Long For i = 1 To n arrNum(i) = Cells(1, i) Next i Dim x As Long x = n - 1 '隣り合う数字を比較して並び替え Do While x > 0 For i = 1 To x If arrNum(i) > arrNum(i + 1) Then '一時変数を利用して値を入れ替える Dim tmp As Long tmp = arrNum(i) arrNum(i) = arrNum(i + 1) arrNum(i + 1) = tmp End If Next i x = x - 1 Loop 'ソート結果を2行目に書き込み For i = 1 To n Cells(2, i) = arrNum(i) Next i End Sub |
ソートアルゴリズムの解説
ソート対象の数列[5,9,7,1,3]として解説していきます。
ソート対象のデータ数を特定
A1セルでCtrl+→を押した時にたどりつく最右列の列番号を取得します。
ここではE列なので、E列は5列目、よって、n = 5となります
数列を格納する配列の準備(n = 5)
通常、配列のインデックスは0からはじまりますが、
モジュール宣言部で「Option Base 1」と記述することで、配列のインデックスの下限値を1にすることができます
Excelシートの列番号は1から始まります。そこで、今回のバブルソートでは、Excelの列番号と配列のインデックスを合わせて記述をシンプルにします。
動的配列を宣言してから、要素数(n=5)を設定します。
Dim arrNum(n) as Longじゃだめなの?
だから、いったん動的配列で宣言してから、ReDimで要素数を設定してるんだよ
ソート対象の数字を配列に格納(n = 5)
隣り合う数字を比較して並び替え
この部分が並び替え処理です
Do~Loopの中にFor文が組み込まれて複雑に感じますね
1 2 3 4 5 6 7 8 9 10 |
x = n - 1 Do While x > 0 For i = 1 To x '隣り合う数字を比較して並べ替え Next i x = x - 1 Loop |
ループ処理を1周ずつ順番にみていきましょう
ループ1周目
隣り合う数字を比較して、左側の数字の方が大きい場合、左右の数字を入れ替えます
1 2 3 |
If arrNum(i) > arrNum(i + 1) Then '数字の入れ替え処理 End If |
これも順番にみていきましょう
5と9を比べると、左側の5の方が小さいので入れ替え不要です
9と7を比べると、左側の9の方が大きいので入れ替えます
一時変数tmpを使用して、隣同士の数字を入れ替えます
これで9と7を入れ替えることができました
同じ方法で、隣り合う数字を比較して並び替えていきます
1周目のループが終了し、5つの数字のなかで一番大きい9が一番右側にきました
これで9の位置が決まったので、次のループで並び替えるのは配列(1)~(4)ですよね。並び替えの対象範囲をせばめるため、範囲指定で使用する変数 x を -1 します
ループ2周目
残りの数字5,7,1,3を並び替えます
同じように、左から順番にみていきます
2周目のループが終了しました
2番目に大きい7の位置が決まりました
ループ3周目
ここまでで、7と9の位置が決まりました
残りの数字5,1,3を並び替えます
3周目のループが終了しました
3番目に大きい5の位置が決まりました
ループ4周目
ループ5周目
ここで、終了条件 Do While x > 0 に合致するので、ループを抜けます
ソート結果を2行目に書き込み
配列arrNumが小さい順に並びました。配列の中身をセルに書き込みます
ひきつづき勉強がんばってね!