VBA

【プログラミングお題】VBAでバブルソートを書いてみよう

bubbleサムネイル
ねぇもりさん、今日もなにかお題だしてよ
もり
もり
じゃあバブルソートでも書いてみよっか~
これを書けばVBAの基本的な文法が一気に勉強できちゃうんだよ

バブルソートとは、ソートアルゴリズムの一つで、隣り合う数字の大小を比較して並び替えていく方法です。

これらのメジャーな文法が一度に勉強できちゃうお題なのです。

  • 配列処理
  • If~End If(条件分岐)
  • For~Next(繰り返し処理)
  • Do~Loop(繰り返し処理)
  • セルへの書き込み処理

さぁ、みてみましょう。

バブルソートのプログラム

エクセルシートのA1セルを起点として適当な数字を入力し、マクロを実行すると、1行目の数列を小さい順に並べ替えた結果が2行目に書き込まれる仕組みです。

bubble0

コードがこちらです

コードだけみてもなにやってるか全然わからないよ~
もり
もり
そうだよね…じゃあとびっきりやさしい解説いくよ~

ソートアルゴリズムの解説

ソート対象の数列[5,9,7,1,3]として解説していきます。

ソート対象のデータ数を特定

A1セルでCtrl+を押した時にたどりつく最右列の列番号を取得します。
ここではE列なので、E列は5列目、よって、n = 5となります
bubble1

数列を格納する配列の準備(n = 5)

通常、配列のインデックスは0からはじまりますが、

bubble3

モジュール宣言部で「Option Base 1」と記述することで、配列のインデックスの下限値を1にすることができます

Excelシートの列番号は1から始まります。そこで、今回のバブルソートでは、Excelの列番号と配列のインデックスを合わせて記述をシンプルにします。

動的配列を宣言してから、要素数(n=5)を設定します。

動的配列とは?
配列を宣言する時点で、要素数がわからない場合に、要素数を決めずに宣言する配列のことです
bubble2
配列を宣言する時点で、n = 5って数が決まってるよね。
Dim arrNum(n) as Longじゃだめなの?
もり
もり
配列を宣言するときの要素数に、変数(この場合、n)は使えないんだ。
だから、いったん動的配列で宣言してから、ReDimで要素数を設定してるんだよ

ソート対象の数字を配列に格納(n = 5)

bubble4

隣り合う数字を比較して並び替え

この部分が並び替え処理です

Do~Loopの中にFor文が組み込まれて複雑に感じますね

ループ処理を1周ずつ順番にみていきましょう

ループ1周目

bubble6
隣り合う数字を比較して、左側の数字の方が大きい場合、左右の数字を入れ替えます

これも順番にみていきましょう

5と9を比べると、左側の5の方が小さいので入れ替え不要です
bubble8
9と7を比べると、左側の9の方が大きいので入れ替えます
bubble9
一時変数tmpを使用して、隣同士の数字を入れ替えます
bubble10
これで9と7を入れ替えることができました

同じ方法で、隣り合う数字を比較して並び替えていきます
bubble11

1周目のループが終了し、5つの数字のなかで一番大きい9が一番右側にきました
bubble12

これで9の位置が決まったので、次のループで並び替えるのは配列(1)~(4)ですよね。並び替えの対象範囲をせばめるため、範囲指定で使用する変数 x を -1 します

【ポイント】ループの最後で、ソートの範囲を狭めていく(x = x – 1)

ループ2周目

残りの数字5,7,1,3を並び替えます
bubble13

同じように、左から順番にみていきます
bubble14
2周目のループが終了しました

2番目に大きい7の位置が決まりました
bubble15

ループ3周目

ここまでで、7と9の位置が決まりました

残りの数字5,1,3を並び替えます
bubble16
bubble17

3周目のループが終了しました

3番目に大きい5の位置が決まりました
bubble18

ループ4周目

bubble19

ループ5周目

ここで、終了条件 Do While x > 0 に合致するので、ループを抜けます

ソート結果を2行目に書き込み

配列arrNumが小さい順に並びました。配列の中身をセルに書き込みます
bubble21

やっぱり図で見るとわかりやすいね~
もり
もり
自分で書いたコードを誰かに説明すると、より理解が深まるんだよ
ひきつづき勉強がんばってね!