連続するセルに対してループ処理を作成する際の2つのコーディングのタイプを紹介!
連続するセルに対してループ処理を作成する際、プログラマーは以下の2つの方法のうち、いずれかでコーディングします。
(この章では、タイプA・タイプBと命名します。)
次のコーディング例は、以下のケースを想定して作成したものです。
ケース1
- 以下の表のA列に対して、2行目から最終行まで、1からの連番をセットする。
タイプA
Option Explicit
Sub set_number()
Dim ws_employeelist As Worksheet
Dim num_row As Long
Application.ScreenUpdating = False
Set ws_employeelist = ThisWorkbook.Worksheets("社員一覧")
For num_row = 2 To ws_employeelist.Cells(Rows.Count, 2).End(xlUp).Row
ws_employeelist.Range("A" & num_row) = num_row - 1
Next num_row
ThisWorkbook.Save
Application.ScreenUpdating = True
End Sub
タイプB
Option Explicit
Sub set_number()
Dim ws_employeelist As Worksheet
Dim num_row As Long
Application.ScreenUpdating = False
Set ws_employeelist = ThisWorkbook.Worksheets("社員一覧")
For num_row = 2 To ws_employeelist.Cells(Rows.Count, 2).End(xlUp).Row
ws_employeelist.Cells(num_row, 1) = num_row - 1
Next num_row
ThisWorkbook.Save
Application.ScreenUpdating = True
End Sub
ケース1のタイプAとタイプBの比較結果
上記のタイプAとタイプBのソースコードで違いがあるのは、13行目の以下の箇所になります。
タイプA | Range(“A” & num_row) |
---|---|
タイプB | Cells(num_row, 1) |
ループ処理を行う際に、2行目~最終行までを「num_row」というカウンターを使って繰り回すしてセルをずらしていく処理で、タイプAではRangeを使用し、タイプBではCellsを使用しています。
この例ではそれほど大きな違いはなく、一概に優劣を付けられないため、次のような場合を検討してみます。
二重ループ処理のコーディング例
二重ループというのは、ループ処理の中にループ処理がある、入れ子構造のループ処理のことを指します。
Excelマクロで作成される二重ループでは、行に対するループ処理の中に、列のループ処理があるといった、行と列の入れ子構造の二重ループが想定されます。
次のコーディング例は、以下のケースを想定して作成したものです。
ケース2
- 10行×10列の表領域の各セルに、1~100までの連番をセットした2つのワークシートを作成する。
- 2つのワークシートの同一行・同一列のセルの値を取得して、その2つを比較した結果、値が異なる場合は、2つのワークシートの2つの該当セルの背景色を黄色にする。
- なお、今回のケースでは、1~99までは同一の値だが、100個目のセルを「sheet1」は「100」、「sheet1」は「200」をセットし、背景色を黄色にするデータとなっている。
sheet1
sheet2
タイプA
Option Explicit
Sub compare_worksheets()
Dim ws_sheet1 As Worksheet
Dim ws_sheet2 As Worksheet
Dim num_row As Long
Dim num_col As Long
Dim num_sheet1 As Long
Dim num_sheet2 As Long
Application.ScreenUpdating = False
Set ws_sheet1 = ThisWorkbook.Worksheets(1)
Set ws_sheet2 = ThisWorkbook.Worksheets(2)
For num_row = 1 To 10
'A列の処理
num_sheet1 = ws_sheet1.Range("A" & num_row)
num_sheet2 = ws_sheet2.Range("A" & num_row)
If num_sheet1 <> num_sheet2 Then
ws_sheet1.Range("A" & num_row).Interior.Color = vbYellow
ws_sheet2.Range("A" & num_row).Interior.Color = vbYellow
End If
'B列の処理
num_sheet1 = ws_sheet1.Range("B" & num_row)
num_sheet2 = ws_sheet2.Range("B" & num_row)
If num_sheet1 <> num_sheet2 Then
ws_sheet1.Range("B" & num_row).Interior.Color = vbYellow
ws_sheet2.Range("B" & num_row).Interior.Color = vbYellow
End If
'C列の処理
num_sheet1 = ws_sheet1.Range("C" & num_row)
num_sheet2 = ws_sheet2.Range("C" & num_row)
If num_sheet1 <> num_sheet2 Then
ws_sheet1.Range("C" & num_row).Interior.Color = vbYellow
ws_sheet2.Range("C" & num_row).Interior.Color = vbYellow
End If
'D列の処理
num_sheet1 = ws_sheet1.Range("D" & num_row)
num_sheet2 = ws_sheet2.Range("D" & num_row)
If num_sheet1 <> num_sheet2 Then
ws_sheet1.Range("D" & num_row).Interior.Color = vbYellow
ws_sheet2.Range("D" & num_row).Interior.Color = vbYellow
End If
'E列の処理
num_sheet1 = ws_sheet1.Range("E" & num_row)
num_sheet2 = ws_sheet2.Range("E" & num_row)
If num_sheet1 <> num_sheet2 Then
ws_sheet1.Range("E" & num_row).Interior.Color = vbYellow
ws_sheet2.Range("E" & num_row).Interior.Color = vbYellow
End If
'F列の処理
num_sheet1 = ws_sheet1.Range("F" & num_row)
num_sheet2 = ws_sheet2.Range("F" & num_row)
If num_sheet1 <> num_sheet2 Then
ws_sheet1.Range("F" & num_row).Interior.Color = vbYellow
ws_sheet2.Range("F" & num_row).Interior.Color = vbYellow
End If
'G列の処理
num_sheet1 = ws_sheet1.Range("G" & num_row)
num_sheet2 = ws_sheet2.Range("G" & num_row)
If num_sheet1 <> num_sheet2 Then
ws_sheet1.Range("G" & num_row).Interior.Color = vbYellow
ws_sheet2.Range("G" & num_row).Interior.Color = vbYellow
End If
'H列の処理
num_sheet1 = ws_sheet1.Range("H" & num_row)
num_sheet2 = ws_sheet2.Range("H" & num_row)
If num_sheet1 <> num_sheet2 Then
ws_sheet1.Range("H" & num_row).Interior.Color = vbYellow
ws_sheet2.Range("H" & num_row).Interior.Color = vbYellow
End If
'I列の処理
num_sheet1 = ws_sheet1.Range("I" & num_row)
num_sheet2 = ws_sheet2.Range("I" & num_row)
If num_sheet1 <> num_sheet2 Then
ws_sheet1.Range("I" & num_row).Interior.Color = vbYellow
ws_sheet2.Range("I" & num_row).Interior.Color = vbYellow
End If
'J列の処理
num_sheet1 = ws_sheet1.Range("J" & num_row)
num_sheet2 = ws_sheet2.Range("J" & num_row)
If num_sheet1 <> num_sheet2 Then
ws_sheet1.Range("J" & num_row).Interior.Color = vbYellow
ws_sheet2.Range("J" & num_row).Interior.Color = vbYellow
End If
Next num_row
ThisWorkbook.Save
Application.ScreenUpdating = True
End Sub
タイプB
Option Explicit
Sub compare_worksheets()
Dim ws_sheet1 As Worksheet
Dim ws_sheet2 As Worksheet
Dim num_row As Long
Dim num_col As Long
Dim num_sheet1 As Long
Dim num_sheet2 As Long
Application.ScreenUpdating = False
Set ws_sheet1 = ThisWorkbook.Worksheets(1)
Set ws_sheet2 = ThisWorkbook.Worksheets(2)
For num_row = 1 To 10
For num_col = 1 To 10
num_sheet1 = ws_sheet1.Cells(num_row, num_col)
num_sheet2 = ws_sheet2.Cells(num_row, num_col)
If num_sheet1 <> num_sheet2 Then
ws_sheet1.Cells(num_row, num_col).Interior.Color = vbYellow
ws_sheet2.Cells(num_row, num_col).Interior.Color = vbYellow
End If
Next num_col
Next num_row
ThisWorkbook.Save
Application.ScreenUpdating = True
End Sub
ケース2のタイプAとタイプBの比較結果
タイプAはRangeを使用しているため、列をアルファベットで表現するしかなく、列に対してのループ処理ができないので、非常に冗長なソースコードとなっています。
タイプBはCellsを使用しているため、行と列の入れ子構造の二重ループでのコーディングが可能なため、非常にシンプルなソースコードとなっています。
今回は10列しかないため、タイプAでもコーディングが可能な数でしたが、対象の列数が非常に多い場合や、データのよって列数が変動する可能性がある場合などを想定すると、ケース2のような行と列の両方を繰り回しが発生するループ処理は、タイプAでの実装は、事実上不可能と考えられます。
一方、タイプBは行と列の数が多い場合でも変動する可能性がある場合でも、基本的にはケース2と同様のシンプルなソースコードで対応可能です。
[emalabo式] ループ処理を作成する際のコーディングルール
ケース2のタイプAとタイプBの比較結果の結論から、emalabo式のコーディングルールはタイプBを採用することといたします。