VBA100本ノック 34本目:配列の左右回転
2次元配列を、左に90度回転または右90度回転する問題です。
ツイートでの見やすさを考慮して、ブック・シート指定等を適宜省略しています。
出題
今回は2次元配列を使った頭の体操です。
2次元配列と回転方向を引数で受け取り、以下の変換後の配列を返すFunctionを作成してください。
回転方向は2種類
・右90度回転
・左90度回転
※引数のデータ型、指定方法は任意
※回転サンプルは画像を参照

頂いた回答
解説
VBAでは2次元配列を扱う事は多くなるので、2次元配列の扱いには慣れておきたいところです。
ただし今回のような回転をさせることはほとんど無く、大抵はTRANSPOSE関数の縦横入替で事足りるでしょう。
あくまで、ある規則の元でセル位置を動かす練習です。
Function VBA100_34_01(ByRef aAry, ByVal 左or右 As String) As Variant
Dim LB1 As Long, UB1 As Long, LB2 As Long, UB2 As Long
LB1 = LBound(aAry, 1): UB1 = UBound(aAry, 1)
LB2 = LBound(aAry, 2): UB2 = UBound(aAry, 2)
Dim oAry()
ReDim oAry(LB2 To UB2, LB1 To UB1)
Dim i As Long, j As Long
For i = LB1 To UB1
For j = LB2 To UB2
Select Case 左or右
Case "左"
oAry(UB2 + LB2 - j, i) = aAry(i, j)
Case "右"
oAry(j, UB1 + LB1 - i) = aAry(i, j)
Case Else
MsgBox 左or右 & vbLf & "この指定はない"
Exit Function
End Select
Next
Next
VBA100_34_01 = oAry
End Function
よほど大きい配列でない限りは構わないと思いますが、練習としてもう少し工夫してみたいと思います。
このあたりについては、記事補足に掲載しました。
補足
3*4→4*3
1,1 → 4,1
1,2 → 3,1
1,3 → 2,1
1,4 → 1,1
2,1 → 4,2
2,2 → 3,2
2,3 → 2,2
2,4 → 1,2
3,1 → 4,3
3,2 → 3,3
3,3 → 2,3
3,4 → 1,3
1次元の数値が2次元の数値へ、2次元の数値は大小を反転させて1次元の数値にすることになります。
同様に右回転も変換を考えて、そして左右回転で分岐させたものが先のVBAになります。
もちろん条件分岐をループの外に出して、それぞれの条件内でループさせるだけでも良いです。
また、そもそもプロシージャーを分けてしまうという考え方もあります。
oAry(UB2 + LB2 - j, i) = aAry(i, j)
oAry(j, UB1 + LB1 - i) = aAry(i, j)
違うのは左辺だけになっているので、違う数式部分を単純に足しちゃいます。
((UB2 + LB2 - j, i) + (j), (i) + (UB1 + LB1 - i)) = aAry(i, j)
そして、各項に0または1をかけて元のそれぞれの数式になるようにすれば、とりあえずは1本化できます。
0または1の変数をLとRとすると、
oAry(((UB2 + LB2 - j) * L) + (j * R), (i * L) + ((UB1 + LB1 - i) * R)) = aAry(i, j)
左回転の時にはL=1:R=0
右回転の時にはL=0:R=1
このようにすると、
左回転なら、
oAry(((UB2 + LB2 - j) * 1) + (j * 0), (i * 1) + ((UB1 + LB1 - i) * 0)) = aAry(i, j)
右回転なら、
oAry(((UB2 + LB2 - j) * 0) + (j * 1), (i * 0) + ((UB1 + LB1 - i) * 1)) = aAry(i, j)
これで元の数式の左右パターンに戻ることになります。
Function VBA100_34_02(ByRef aAry, ByVal 左or右 As String) As Variant
Dim LB1 As Long, UB1 As Long, LB2 As Long, UB2 As Long
LB1 = LBound(aAry, 1): UB1 = UBound(aAry, 1)
LB2 = LBound(aAry, 2): UB2 = UBound(aAry, 2)
Dim oAry()
ReDim oAry(LB2 To UB2, LB1 To UB1)
Dim L As Long, R As Long
Select Case 左or右
Case "左"
L = 1: R = 0
Case "右"
L = 0: R = 1
Case Else
MsgBox 左or右 & vbLf & "この指定はない"
Exit Function
End Select
Dim i As Long, j As Long
For i = LB1 To UB1
For j = LB2 To UB2
oAry(((UB2 + LB2 - j) * L) + (j * R), (i * L) + ((UB1 + LB1 - i) * R)) = aAry(i, j)
Next
Next
VBA100_34_02 = oAry
End Function
このような数式の組み立て方はいろいろありますし、引数の与え方でも変わってきます。
ただし、こういうのは作るのは良いのですが、後で見た時に理解するのが大変ですね。
あくまで頭の体操だと思って、いろいろ挑戦してみるのは良いと思います。
引数で変えることもできますし、直接呼び出す事も出来ます。
※両方使えるようにする事が良いかどうかは作成するシステムによると思いますが。
Function VBA100_34_03(ByRef aAry, ByVal 左or右 As String) As Variant
Select Case 左or右
Case "左"
VBA100_34_03 = 配列左回転(aAry)
Case "右"
VBA100_34_03 = 配列右回転(aAry)
Case Else
MsgBox 左or右 & vbLf & "この指定はない"
End Select
End Function
Function 配列左回転(ByRef aAry) As Variant
Dim LB1 As Long, UB1 As Long, LB2 As Long, UB2 As Long
LB1 = LBound(aAry, 1): UB1 = UBound(aAry, 1)
LB2 = LBound(aAry, 2): UB2 = UBound(aAry, 2)
Dim oAry()
ReDim oAry(LB2 To UB2, LB1 To UB1)
Dim i As Long, j As Long
For i = LB1 To UB1
For j = LB2 To UB2
oAry(UB2 + LB2 - j, i) = aAry(i, j)
Next
Next
配列左回転 = oAry
End Function
Function 配列右回転(ByRef aAry) As Variant
Dim LB1 As Long, UB1 As Long, LB2 As Long, UB2 As Long
LB1 = LBound(aAry, 1): UB1 = UBound(aAry, 1)
LB2 = LBound(aAry, 2): UB2 = UBound(aAry, 2)
Dim oAry()
ReDim oAry(LB2 To UB2, LB1 To UB1)
Dim i As Long, j As Long
For i = LB1 To UB1
For j = LB2 To UB2
oAry(j, UB1 + LB1 - i) = aAry(i, j)
Next
Next
配列右回転 = oAry
End Function
サイト内関連ページ
同じテーマ「VBA100本ノック」の記事
31本目:入力規則
32本目:Excel終了とテキストファイル出力
33本目:マクロ記録の改修
34本目:配列の左右回転
35本目:条件付き書式
36本目:列の並べ替え
37本目:グラフの色設定
38本目:1シートを複数シートに振り分け
39本目:数値リストの統合(マージ)
40本目:複数ブックの統合
41本目:暗算練習アプリ
新着記事NEW ・・・新着記事一覧を見る
PropertyのSetはLetでも良い|VBA技術解説(2021-03-31)
エクセル麻雀ミニゲーム|VBAサンプル集(2021-03-09)
VBA100本ノック 100本目:WEBから100本ノックのリストを取得|VBA練習問題(2021-03-03)
VBA100本ノック 魔球編:2桁の最小公倍数|VBA練習問題(2021-02-02)
Select Caseでの短絡評価(ショートサーキット)の使い方|VBA技術解説(2021-01-03)
VBA100本ノック 迷宮編:巡回セル問題|VBA練習問題(2020-12-31)
VBA100本ノック 魔球編:閉領域の塗り潰し|VBA練習問題(2020-12-16)
VBA100本ノック 魔球編:組み合わせ問題|VBA練習問題(2020-12-02)
将棋とプログラミングについて~そこには型がある~|エクセル雑感(2020-11-22)
VBA100本ノック 1本目:セルのコピー|VBA練習問題(2020-10-19)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.マクロって何?VBAって何?|VBA入門
5.Excelショートカットキー一覧|Excelリファレンス
6.繰り返し処理(For Next)|VBA入門
7.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
8.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
9.セルに文字を入れるとは(Range,Value)|VBA入門
10.とにかく書いてみよう(Sub,End Sub)|VBA入門
- ホーム
- マクロVBA入門編
- VBA100本ノック
- 34本目:配列の左右回転
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。