目標
For~Nextのネストを理解して利用できる
ネストした繰り返し文の動きをイメージできる
Resizeプロパティを理解して利用できる。
For~Nextステートメントのネストの利用方法と動作
For~Nextステートメントのネストの利用方法
ネストとは入れ子構造のことでした。先ずは、どのような場面で利用されるのかを考えてみたいと思います。
例えば形式の同じ表が複数個用意されているExcelファイルで、それぞれの表に同様の計算や処理を行わせたい場合などがあります。このような場面でひとつ目の表の複数のセルで繰り返しの処理を行わせ、終わったら次の表へ、また終わったら更に次の表へと処理が移動するようなプログラムを記述する時に利用されます。
今回は上記のようなプログラムを記述してみます。次の制御構造(Part.7)ではもう少し複雑な処理のプロシージャを組んでみようと思います。
ネストされた繰り返し文のプログラムの動き
先ずは基本の動きを理解するためにシンプルなFor文のネストを確認します。
サンプルプロシージャ1
Sub NestFor1()
Dim i As Integer, j As Integer
For i = 1 To 5
For j = 1 To 5
Cells(i, j) = i * j
Next j
Next i
End Sub
実行結果
動作の確認
繰り返しの入れ子では外の繰り返しが1回動くごとに、内側の繰り返すが全て動きます。
具体的には
- 外側の「i」が1の時「j」が1,2,3,4,5とカウントされ5回動く
- 外側の「i」が2の時「j」が1,2,3,4,5とカウントされ5回動く
- 外側の「i」が3の時「j」が1,2,3,4,5とカウントされ5回動く
- 外側の「i」が4の時「j」が1,2,3,4,5とカウントされ5回動く
- 外側の「i」が5の時「j」が1,2,3,4,5とカウントされ5回動く
となっています。
サンプルプロシージャ2
次は、冒頭であげた「形式の同じ表が複数個用意されているExcelファイルで、それぞれの表に同様の計算や処理を行わせたい場合」について参考のプロシージャを作成します。
Dim sheetName(3) As String
sheetName(1) = "Sheet1"
sheetName(2) = "Sheet2"
sheetName(3) = "Sheet3"
Sheets("Sheet4").Select
Range("C3").Select
ActiveCell.CurrentRegion.Select
Selection.ClearContents
For i = 1 To 3
Worksheets(sheetName(i)).Select
Range("C3").Select
ActiveCell.CurrentRegion.Select
tableRow = Selection.Rows.Count
tableColumns = Selection.Columns.Count
If i = 1 Then
Selection.Copy
Sheets("Sheet4").Select
Range("C3").Select
ActiveSheet.Paste
Range("C3").Select
ElseIf i <> 1 Then
ActiveCell.Offset(1, 0).Resize(tableRow - 1, tableColumns).Select
Selection.Copy
Sheets("Sheet4").Select
Range("C3").Select
Selection.End(xlDown).Select
ActiveCell.Offset(1, 0).Select
ActiveSheet.Paste
End If
Application.CutCopyMode = False
If i = 3 Then
ActiveCell.CurrentRegion.Select
tableRow = Selection.Rows.Count
tableColumns = Selection.Columns.Count
ActiveSheet.Range("H5").Select
Application.ScreenUpdating = False
Application.EnableEvents = False
For j = 1 To tableRow - 2
ActiveCell.FormulaR1C1 = "=R[-1]C+RC[-2]-RC[-1]"
ActiveCell.Offset(1, 0).Select
Next j
Application.ScreenUpdating = True
Application.EnableEvents = True
End If
Next i
End Sub
ネストされているFor文は下から8行目の「For j = 1 To tableRow」の部分となります。
このプログラムでは下のキャプチャのような日計計算のエクセルファイルがあったと仮定して最終的な月次の収支を出すような場面を想定しています。シートは「現金収支のシート(Sheet1)」「口座収支のシート(Sheet2)」「ガード入金(Sheet3)」の三種類があり、最終的に一枚のシート(Sheet4)へ併合して月の収支を出すものです。
それぞれの収支はキャプチャのようになっています。
実行結果
Sheet4に事前に準備していた表で月次の計算を行わせます。(この表はVBAではなく通常のワークシート関数を利用したエクセルの表です。)
補足説明部分
Selection.ClearContents…選択された範囲の値を消去します。
サンプルプロシージャ2の中身はこれまでの記事で取り上げていたものばかりなのでネストの動きさえ理解できていれば全ての動きを把握することができます。
Resizeプロパティの概要と利用方法
Resizeプロパティの概要
Resizeプロパティとは指定した行数と列数を基にして範囲選択をできるプロパティです。
指定された範囲のサイズを変更します。 サイズが変更されたセル範囲 (Range オブジェクト) を返します。
https://learn.microsoft.com/ja-jp/office/vba/api/excel.range.resize
Resizeプロパティの利用方法
Resizeプロパティは任意のセルを起点にして指定した行数と列数分の範囲を取得することができます。例えばセルB5を起点のセルとした場合、次のように記述します。
「Range(“B5”).Resize(3,3).Select」
これでセルB5からD7の範囲を取得して返してくれます。
Resizeプロパティの利用例
Resizeプロパティは一覧表を取得する場合に「見出し部分(フィールド部分)を省く」といいた処理を可能にしてくれます。
例えば、下の表で赤い枠部分を選択範囲から除外するといった場合は、次のようにResizeプロパティを利用します。
以下手順。(今回は一覧表の一番上の行を除外するときの処理)
1.取得したい表の左上を選択(アクティブセルに)する。
2.ActiveCell.CurrentRegion.Selectで一覧表の全選択を行う。
3.Selection.Rows.Countで取得した一覧表の行の数を取得する。
4.Selection.Columns.Countで取得した一覧表の列の数を取得する。
5.アクティブセルをひとつ下に移動する。
6.Resizeプロパティを利用してアクティブセルから5行6列の範囲を取得選択する。
「ActiveCell.Resize(5,6).Select」
今回のプロシージャでは
ActiveCell.Offset(1, 0).Resize(tableRow – 1, tableColumns).Selectとしています。
意味:「アクティブセル.ひとつ下のセル.Resize(行数-1, 列数).選択」となります。
今回は以上です。
ブックマークのすすめ
「ほわほわぶろぐ」を常に検索するのが面倒だという方はブックマークをお勧めします。ブックマークの設定は別記事にて掲載しています。