![見出し画像](https://assets.st-note.com/production/uploads/images/163099698/rectangle_large_type_2_46e6712370144d4ac84a91bf9e0b1763.png?width=1200)
Photo by
mericanadesico
マクロVBA練習問題03
問題
エクセルの神髄さんの練習問題03(二重ループの練習)を解いた。
https://www.excel-ubara.com/excelvba9/EXCELVBA603.html
解答(For~Next版)
Sub 練習問題03_1()
With Sheet3
'設定
Dim StartRow As Long: StartRow = 2 '開始行番号の設定
Dim EndRow As Long: EndRow = .Cells(Rows.Count, "A").End(xlUp).Row '終了行番号の設定
Dim StartCol As Long: StartCol = 2 '開始列番号の設定
Dim EndCol As Long: EndCol = .Cells(1, Columns.Count).End(xlToLeft).Column '終了列番号の設定
'処理
Dim R As Long, C As Long
For R = StartRow To EndRow
For C = StartCol To EndCol
.Cells(R, C).Value = .Cells(R, "A").Value * .Cells(1, C).Value
Next C
Next R
End With
End Sub
For~Next文で書くとこんな感じです。
設定として開始行、終了行、開始列、終了列を予め指定しています。
コードの意図をわかりやすくするためにあえて変数に入れてますが、1回しか使わないので、そのまま書いた方がコードとしてはスッキリすると思います。(どう書くとメンテナンスするときにしやすいのか悩み中)
解答(For Each~Next版)
Sub 練習問題03_2()
'設定
Dim Table As Range
Set Table = Sheet3.Range("A1").CurrentRegion
'処理
Dim Rng As Range
For Each Rng In Table.Cells
If Rng.Row > 1 And Rng.Column > 1 Then
Rng.Value = _
Table.Cells(Rng.Row, "A").Value * Table.Cells(1, Rng.Column).Value
End If
Next Rng
End Sub
For Each~Next文で書いてみました。
こちらの方法だと、二重ループさせずに処理することが可能です。
設定で表範囲をオブジェクト変数(Table)に入れています。
.CurrentRegionはA1セルでCtrl + Aを押したときに選ばれる範囲という意味になります。
処理のループ部分は、Tableだけでも意図した動作します。
ただ、Table.Cellsと書く方がセルひとつずつを順番に処理してくれることがメンテナンス時などに明確になるためこちらの書き方が良いと思います。
If文で1行目と1列より大きくないと処理しないという条件分岐をかけています。
計算時はRng.Cellsではなく、Table.Cellsで指定しないと予期せぬ場所が計算対象となるので注意です。