配列を逆から参照すると可読性が落ちる
配列を利用する際に、配列の逆から参照したい場合があります。
以下は逆順から参照するコード例です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
Sub RevLoop(ar()) Dim i Dim iLen iLen = UBound(ar) '// For文で逆順に書いた場合 For i = iLen To 0 Step -1 Debug.Print ar(i) Next '// Do文で逆順に書いた場合 i = iLen Do If i < 0 Then Exit Do End If Debug.Print ar(i) i = i - 1 Loop End Sub |
このように、逆順に参照した場合はループカウンタの初期値に最大値を設定して、カウンタが-1減るコードになるため、ソースコードの可読性がどうしても落ちてしまいます。
また、For Each文は逆順では使えません。
過去に、通常ループと逆順ループが混在しているソースを見たことがありますが、フラグやインデックス変数が乱立してもうわけわかりませんでした。
こういう場合は通常の順番のループに統一した方がよいでしょうね。
配列を逆順に並べ替え
以下のコードは配列の順番を反転させて逆順になるようにします。
一応Option Base 1の場合の対応としてLBound関数を利用していますが、そうでない場合は12行目をiStart = 0としても問題ありません。
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 |
Sub Reverse(ar()) Dim iStart Dim iEnd Dim s '// 配列でない場合は処理をしない If IsArray(ar) = False Then Exit Sub End If '// 配列の添え字の最小と最大を取得 iStart = LBound(ar) iEnd = UBound(ar) '// 配列の入れ替えが終わるまでループ Do '// 添え字の大小が逆転もしくは一致した場合はループ終了 If iStart >= iEnd Then Exit Do End If '// 配列要素の入れ替え s = ar(iStart) ar(iStart) = ar(iEnd) ar(iEnd) = s '// 添え字の移動 iStart = iStart + 1 iEnd = iEnd - 1 Loop End Sub |
以下がテストコードです。
配列が0から4まで順に設定されていますが、Reverse関数で反転します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Sub ReverseTest() Dim ar() Dim s ReDim ar(4) ar(0) = 0 ar(1) = 1 ar(2) = 2 ar(3) = 3 ar(4) = 4 Call Reverse(ar) For Each s In ar Debug.Print s Next End Sub |
実行結果
4
3
2
1
0