📊連載第6回！初心者のためのExcel VBA入門：For文とDo文で学ぶループ処理の基本🌟

# Excel VBAにおける繰り返し処理の基本

私はVBAの活用経験を通じて得た知識を整理し、共有する目的で記事を作成しているプログラミング歴1年半になるエンジニアです。 前回は、Excel VBAにおける条件分岐について解説しました。今回は、実務で必須となる繰り返し処理の基本テクニックについて詳しく説明していきます。適切な繰り返し処理の実装は、大量のデータを効率的に処理するための重要な要素です。VBAを使ったデータ処理を効率化したい方、特に大量データの処理を自動化したい方は、ぜひ参考にしてみてください。

- [第1回: Excel VBAの基礎知識とセキュリティ設定](https://qiita.com/CodeLeaf/items/2d3e3185a725480fecc3)
- [第2回: Excel VBAの基本操作とオブジェクトの理解](https://qiita.com/CodeLeaf/items/c65d2531908aaf53649d)
- [第3回: Excel VBAにおける変数と定数の基本](https://qiita.com/CodeLeaf/items/3b36eddf7b5a8b5c5d99)
- [第4回: Excel VBAにおけるシート操作の基本とエラー処理](https://qiita.com/CodeLeaf/items/573fb7c61a756aa123ea)
- [第5回: Excel VBAにおける条件分岐](https://qiita.com/CodeLeaf/items/8be52d682baa097a65c1)
- 第6回: Excel VBAにおける繰り返し処理の基本（本記事）
-  [第7回: Excel VBAにおける配列とFor Eachの活用](https://qiita.com/CodeLeaf/items/bdd8d488e49086219663)
- [第8回: Excel VBAにおけるFormulaとValueの使い分けとユーザー入力の取得](https://qiita.com/CodeLeaf/items/ecf312a53f7ede91bce9)
- [第9回: Excel VBAにおけるファイル操作とフォルダ管理の基本](https://qiita.com/CodeLeaf/items/e5520321e760364f6aae)
- [第10回: Excel VBAにおけるFileSystemObjectを活用した高度なファイル操作](https://qiita.com/CodeLeaf/items/a78e9c7dd2b7e68f1d9e)
- [第11回: Excel VBAにおけるFileSystemObjectを活用した高度なファイル操作 応用編](https://qiita.com/CodeLeaf/items/4607db0151dddfb7f458)
- [第12回: Excel VBAにおけるStrConv関数の活用と応用テクニック](https://qiita.com/CodeLeaf/items/4f6358548bced6c047e0)
- [第13回: Excel VBAにおけるワークブックの安全な操作と管理テクニック](https://qiita.com/CodeLeaf/items/cf136898dd41c7dd5d9f)
- [第14回: Excel VBAにおけるFunction（関数）の作成と活用テクニック](https://qiita.com/CodeLeaf/items/a299f465bdcb1957e2be)
- [第15回: Excel VBAにおける配列を返す関数の作成と活用テクニック](https://qiita.com/CodeLeaf/items/711a93ac86b5c4150e13)
- [第16回: Excel VBAにおけるコレクションの活用と応用テクニック](https://qiita.com/CodeLeaf/items/6a28c65d5f8d19964664)
- [第17回: Excel VBAにおける辞書型（Dictionary）の活用と応用テクニック](https://qiita.com/CodeLeaf/items/5f85b2029e8d51eaa788)
- [第18回: Excel VBAにおけるEnum型を活用した関数設計と実装テクニック](https://qiita.com/CodeLeaf/items/3e91ef9556799d96aeea)
- [第19回: Excel VBAにおけるユーティリティ関数の作成と活用テクニック](https://qiita.com/CodeLeaf/items/bc156b6a9cadd7b10601)
- [第20回: Excel VBAにおける正規表現を活用したファイル名解析テクニック](https://qiita.com/CodeLeaf/items/86284498dee42aab731e)


## 目次
[はじめに](#はじめに)
[繰り返し処理](#繰り返し処理)
[For...Nextステートメント](#fornextステートメント)
[Do...Loopステートメント](#doloopステートメント)
[For...Next文とDo...Loop文の使い分け](#fornext文とdoloop文の使い分け)
[まとめ](#まとめ)

## はじめに

プログラミングにおいて、繰り返し処理とは、「決まった回数」や「条件が満たされるまで」同じ処理を継続して行うためのやり方です。例えば、売上データが登録された数百行のシートから集計を行う場合や、大量の顧客データに対して同じ処理を繰り返し実行する場合など、実務では非常に多く発生します。繰り返し処理を適切に実装することで、これらの作業を自動化し、業務効率を大幅に向上させることができます。

Excel VBA では、`For Next` と `Do...Loop` という2つの代表的な繰り返し処理の方法があります。これらは、異なる特性を持ち、様々な状況に応じて使い分けることが求められます。この記事では、それぞれの構文と使いどころを具体例を交えながら説明しますので、VBAの効率的なコード作成に役立てていただければ幸いです。

## 繰り返し処理
VBAでの繰り返し処理は、特定の条件が満たされるまでまたは指定された回数だけ処理を実行します。代表的なものに `For Next` と `Do...Loop` があります。

## For...Nextステートメント
`For...Next`ステートメントは、指定した回数だけ処理を繰り返す、最も基本的な繰り返し処理です。

### 基本構文
```vb
For カウンタ変数 = 開始値 To 終了値 [Step 増減値]
    ' 繰り返す処理
Next [カウンタ変数]
```

- **カウンタ変数**：繰り返しの回数を管理する変数
- **開始値**：カウンタ変数の初期値
- **終了値**：カウンタ変数の最終値
- **増減値**：カウンタ変数の増減値（省略可能。省略時は1）

### コード例
```vb
Dim i As Long

For i = 1 To 5
    Debug.Print i  ' イミディエイトウィンドウに表示
Next i
```

この例では、変数 `i` が1から5まで1ずつ増加しながら、`Debug.Print i` の処理が実行されます。結果として、イミディエイトウィンドウに1から5までの数字が表示されます。

### Stepキーワードの使用例

`Step`キーワードを使用すると、カウンタ変数の増減値を指定できます。

```vb
Dim i As Long

' 2ずつ増加させる
For i = 0 To 10 Step 2
    Debug.Print i
Next i

' 2ずつ減少させる
For i = 10 To 0 Step -2
    Debug.Print i
Next i
```

この例では、最初に0から10まで2ずつ増加させ、次に10から0まで2ずつ減少させています。

### Exit For ステートメント

`Exit For` ステートメントを使うと、ループの条件が満たされる前にループを途中で抜け出すことができます。

```vb
Dim i As Long

For i = 1 To 10
    If i > 5 Then
        Exit For  ' i が 5 より大きくなったらループを抜ける
    End If
    Debug.Print i
Next i
```

この例では、`i` が5より大きくなったら `Exit For` が実行され、ループが終了します。

### 無限ループ

無限ループとは、終了条件が満たされず、ループが停止しない状態を指します。プログラムがフリーズしたように見える原因となるプログラムのバグです。`For...Next` ステートメントでは、開始値、終了値、増減値の設定ミスによって発生することがあります。

#### 無限ループの例

```vb
' ループ内でカウンタを不適切に操作
For i = 1 To 10
    i = i - 1  ' iが増加せず、永遠に1以下となる
    Debug.Print i
Next i
```

#### 無限ループの防止法

1. 適切な終了条件の設定

    ```vb
    ' カウンタをループ内で変更しない
    For i = 1 To 10
        Debug.Print i
    Next i
    ```

2. 安全装置としての最大ループ回数の設定

    ```vb
    Dim i As Long
    Dim loopCount As Long
    
    For i = 1 To 10
        loopCount = loopCount + 1
        
        ' 安全装置：最大1000回でループを強制終了
        If loopCount > 1000 Then
            Debug.Print "警告：ループ回数が1000回を超えました"
            Exit For ' loopCount が 1000 より大きくなったらループを抜ける
        End If
        
        ' 通常の処理
        Debug.Print i
    Next i
    ```

:::note warn
#### 無限ループを防ぐためのベストプラクティス
- カウンタ変数は処理内で変更しない
- 安全装置として最大ループ回数を設定する
- 無限ループが発生してしまった際は、`esc` キーで処理を強制終了する
:::

### ネスト構造

`For...Next` ステートメントは入れ子にすることができます。これをネスト構造と呼びます。ネスト構造を使うことで、より複雑な処理を記述できます。

```vb
' 九九の表を作成する例
Dim i As Long, j As Long

For i = 1 To 9
    For j = 1 To 9
        Cells(i, j).Value = i * j
    Next j
Next i
```

この例では、外側のループが九九の行を、内側のループが九九の列を表しています。

### 実践的な例：セルの連続処理

```vb
Dim i As Long

' A1からA10まで連番を入力
For i = 1 To 10
    Cells(i, 1).Value = i
    
    ' 偶数の場合は背景色を黄色に
    If i Mod 2 = 0 Then
        Cells(i, 1).Interior.Color = vbYellow
    End If
Next i
```

### トラブル

```vb
' 例1: カウンタの増減が終了条件に近づかない
For i = 1 To 10 Step -1  ' 正の範囲に対して負の増分
    Debug.Print i
Next i

' 開始値を終了値より大きく設定
For i = 10 To 1 Step 1   
    Debug.Print i
Next i
```

:::note info
### For Nextのポイント
- `Step` を指定することで、ループの増減値を変えられる（デフォルトは1）
- `Step` は正数でも、負数でも、指定可能
- `Exit For` を使うことで、ループを途中で抜け出すことも可能
- ネストが深くなりすぎないよう注意（通常3階層までが理想）
:::

## Do...Loopステートメント
`Do...Loop` ステートメントは、条件が成立する（または成立しなくなる）まで処理を繰り返すための構文です。

### 基本構文

条件判定のタイミングと条件の組み合わせにより、4つのパターンがあります。

- `Do While...Loop` **先頭**で条件判定（条件が**真**の間、繰り返し）

```vb
Do While 条件
   ' 繰り返す処理
Loop
```

- `Do Until...Loop` **先頭**で条件判定（条件が**偽**の間、繰り返し）

```vb
Do Until 条件
   ' 繰り返す処理
Loop
```

- `Do...Loop While` **末尾**で条件判定（条件が**真**の間、繰り返し）

```vb
Do
    ' 繰り返し実行する処理
Loop While 条件
```

- `Do...Loop Until` **末尾**で条件判定（条件が**偽**の間、繰り返し）

```vb
Do
    ' 繰り返し実行する処理
Loop Until 条件
```

### コード例

以下は、1から3までカウントアップして表示する4つの異なる書き方です。 どの方法でも同じ結果（1, 2, 3の順で表示）が得られますが、条件の書き方が異なります。

- Do While...Loop（**先頭**で条件判定 - 条件が**真**の間繰り返し）

```vb
Dim count1 As Long
count1 = 1

Do While count1 <= 3    ' count1が3以下の間、繰り返し実行
    Debug.Print count1  ' count1の値を出力
    count1 = count1 + 1 ' count1を1増やす
Loop
```

- Do Until...Loop（**先頭**で条件判定 - 条件が**偽**の間繰り返し）

```vb
Dim count2 As Long
count2 = 1

Do Until count2 > 3     ' count2が3より大きくなるまで繰り返し実行
    Debug.Print count2  ' count2の値を出力
    count2 = count2 + 1 ' count2を1増やす
Loop
```

- Do...Loop While（**末尾**で条件判定 - 条件が**真**の間繰り返し）

```vb
Dim count3 As Long
count3 = 1

Do
    Debug.Print count3  ' count3の値を出力
    count3 = count3 + 1 ' count3を1増やす
Loop While count3 <= 3  ' count3が3以下の間、繰り返し実行
```

- Do...Loop Until（**末尾**で条件判定 - 条件が**偽**の間繰り返し）

```vb
Dim count4 As Long
count4 = 1

Do
    Debug.Print count4  ' count4の値を出力
    count4 = count4 + 1 ' count4を1増やす
Loop Until count4 > 3   ' count4が3より大きくなるまで繰り返し実行
```

#### 実行結果について

それぞれ、条件の確認タイミング（先頭か、末尾か）と条件の表現方法（Whileか、Untilか）が異なりますが、結果は同じになります。

- すべてのパターンで同じ結果（1, 2, 3）が出力されます
- While/Untilの条件式は異なりますが、同じ動作を実現しています
  - While: count <= 3
  - Until: count > 3
  これらは「逆」の条件になっています
  
:::note info
#### 各パターンの使い分け
##### 先頭判定（Do While/Until）
- 最初から条件をチェックしたい場合
- 条件が最初から偽の場合、一度も実行されない

##### 末尾判定（Do...Loop While/Until）
- 最低1回は処理を実行したい場合
- ループ内の処理結果を条件判定に使用する場合
:::

### While文とUntil文の違い
- Whileは「～の間」(条件式がTrueの間続ける)
    例： 変数 `i` が10より小さい間、処理を続ける
- Untilは「～になるまで」(条件式がTrueになるまで＝Falseの間続ける)
    例： 変数 `i` が10以上になるまで、処理を続ける
    
同じ結果を得るための異なる表現方法ですが、 `While` はループを**継続**する条件を、`Until` はループを**終了**する条件を記述すると考えると、 より直感的に理解しやすいでしょう。 

### ループを抜ける方法

`Exit Do` ステートメントを使用すると、`Do...Loop` ステートメントのループから強制的に抜け出すことができます。

```vb
Dim i As Long
i = 1

Do While True ' 無限ループ
    Debug.Print i
    i = i + 1

    ' iが5より大きくなったらループを抜ける
    If i > 5 Then
        Exit Do
    End If
Loop

Debug.Print "ループを抜けました"
```

この例では、`Do While True` で無限ループを作成し、`If i > 5 Then Exit Do` で `i` が5より大きくなった場合にループを抜けています。

:::note info
### Do...Loop文のポイント
- 条件判定のタイミングを柔軟に選択可能
- While/Untilを使い分けることで、条件をより直感的に記述可能
- `Exit Do` ステートメントを使用すると、ループから強制的に抜け出すことが可能
- 無限ループに注意し、途中でループを終了する条件を確実に設定することが重要
### 無限ループの防止策
- 終了条件を明確にする
- ループ内の処理が実行条件を変化させることを確認する 
:::

## For...Next文とDo...Loop文の使い分け

`Do...Loop` 文と `For...Next` 文はどちらも繰り返し処理を行うための構文ですが、それぞれ得意な処理が異なります。

### For...Next文が適している場合

- 繰り返し回数が**決まっている**場合
- **決まった回数だけ**処理を繰り返したい場合
- 特定の範囲の値を**順**に取り出して処理を行いたい場合

例えば、リストの要素を全て処理する場合や、1から10までの数字を順に出力する場合に適しています。

#### For...Next文が適している例

```vb
' 繰り返し回数が明確な場合
Dim i As Long

For i = 1 To 10           ' 10回繰り返すことが明確
    Cells(i, 1).Value = i ' A1からA10まで連番を入力
Next i
```

### Do...Loop文が適している場合

- 繰り返し回数があらかじめ**決まっていない**場合
- **特定の条件が満たされるまで**処理を繰り返したい場合
- ループの途中で条件判定を行い、条件に応じてループを継続/終了させたい場合

例えば、ファイルの終わりまで読み込む処理や、セルが空白になるまで処理を繰り返す場合に適しています。

#### Do...Loop文が適している例

```vb
' セルが空白になるまで処理を続ける
Dim i As Long

i = 1
Do While Cells(i, 1).Value <> ""              ' 空白セルが出るまで続ける
    Cells(i, 2).Value = Cells(i, 1).Value * 2 ' A列の値を2倍してB列に入力
    i = i + 1
Loop
```

### 使い分けまとめ

| 構文 | 繰り返し回数 | 適した状況 |
| ---- | ----------- | --------- |
| `Do...Loop` |	あらかじめ決まっていない | 特定の条件が満たされるまで処理を繰り返す |
| `For...Next` | 決まっている | 決まった回数だけ処理を繰り返す |

## まとめ

繰り返し処理は、VBAプログラミングにおいてデータの効率的な処理を実現する重要な要素です。`For...Next` 文と `Do...Loop` 文は、それぞれの特性を活かして使い分けることで、より効率的で信頼性の高いプログラムを作成することができます。特に、繰り返し回数が明確な場合は `For...Next` 文を、条件に基づく繰り返しには `Do...Loop` 文を使用するという使い分けを意識することで、より読みやすく、メンテナンスしやすいコードを実現できます。また、無限ループを防ぐための適切な終了条件の設定や、`Exit` ステートメントの活用により、プログラムの安全性を高めることができます。

もし記事の内容で不明な点や、より詳しく知りたい部分がありましたら、コメントでお知らせください。また、実務での繰り返し処理の活用例や、より効率的な実装方法など、皆様のノウハウもぜひ共有していただければ幸いです。

次回は、VBAにおける配列について詳しく解説する予定です。配列を理解することで、大量のデータを効率的に処理できるようになります。どうぞお楽しみに！