基礎から学ぶVBAプログラミング教室

もりさんのお題を解きながら楽しく勉強しよう

スポンサーリンク

【徹底図解】VBAでバブルソートを書いてみよう

f:id:excel-accounting:20180818215026p:plain:w500



ねぇもりさん、この前のもりさんのRPAの話を聞いて、わたしVBAの勉強はじめたんだ

www.excel-prog.com


おっ、ついにプログラミングデビューだね。おめでとう

でね、なにか良いお題ないかなぁ?

それならバブルソートがオススメだね。
ソートアルゴリズムの一つで、これを書けばVBAの基本的な文法が一気に勉強できちゃうんだよ


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

これらの文法が全部勉強できちゃうそうです。

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

さぁ、みてみましょう。

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

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

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]+[→]を押してたどりつく最右列の列番号を取得します

n=5となります
f:id:excel-accounting:20180819172045p:plain:w350

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

動的配列を準備し、要素数を設定します

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

今回のバブルソートでは、Excelの列番号と配列のインデックスを合わせて記述をシンプルにするために、このようにします
f:id:excel-accounting:20180819172056p:plain:w350


【参考】通常、配列のインデックスは0からはじまります
f:id:excel-accounting:20180819172105p:plain:w350

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

f:id:excel-accounting:20180819172128p:plain:w350

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

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

Do~Loopの中にFor文が組み込まれて複雑に感じますね
f:id:excel-accounting:20180819172142p:plain:w400


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

変数は、並び替え対象の基準となる数字の範囲指定(1~x)に使用します

ループ1周目

f:id:excel-accounting:20180819172155p:plain:w350

隣り合う数字を比較して、左側の数字の方が大きい場合、左右の数字を入れ替えます
f:id:excel-accounting:20180819172216p:plain:w400

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


左側の5の方が小さいので入れ替え不要です
f:id:excel-accounting:20180819172233p:plain:w350


左側の9の方が大きいので入れ替えます
f:id:excel-accounting:20180819172242p:plain:w350


一時変数を使用して、隣同士の数字を入れ替えます

f:id:excel-accounting:20180819172252p:plain:w350
これで9と7を入れ替えることができました

同じ要領で、隣り合う数字を比較して並び替えていきます
f:id:excel-accounting:20180819172312p:plain:w350

ループの1周目が終了し、5つの数字のなかで一番大きいが一番右側にきました
f:id:excel-accounting:20180819172323p:plain:w350

【ポイント】ループの最後で、並び替えの範囲を指定する変数xを-1します
x = x - 1

ループ2周目

「小さい順に左から並べていく」ので、一番大きいはこれで位置固定です

残りの数字5,7,1,3を並び替えます
f:id:excel-accounting:20180819172345p:plain:w350

同じように、左から順番にみていきます
f:id:excel-accounting:20180819172406p:plain:w350

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

2番目に大きいの位置が決まりました
f:id:excel-accounting:20180819172417p:plain:w350

ループ3周目

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

残りの数字5,1,3を並び替えます
f:id:excel-accounting:20180819172428p:plain:w350

f:id:excel-accounting:20180819172444p:plain:w350

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

3番目に大きいの位置が決まりました
f:id:excel-accounting:20180819172453p:plain:w350

ループ4周目

f:id:excel-accounting:20180819172505p:plain:w350

ループ5周目

f:id:excel-accounting:20180819172521p:plain:w350

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

配列の中身をセルに書き込みます

f:id:excel-accounting:20180819172538p:plain:w350


うわ~やっぱり図で見るとわかりやすいね~

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

スポンサーリンク