【初心者向けエクセルVBA】For~Next文で簡潔にプログラムを書く


Nest

Kapa65 / Pixabay

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

今回は請求データ一覧から請求書を自動で作成するを目的とした初心者向けエクセルVBA講座の第3回で

【初心者向けエクセルVBA】ワークシートをオブジェクト名で取り扱う方法
初心者向けエクセルVBAで請求書を作成するシリーズ。今回は、エクセルVBAで頻繁に取り扱うワークシートを「オブジェクト名」を使って指定する方法です。オブジェクト名とは何か、またその編集方法もお伝えします。

こちらの記事の続きです。

エクセルVBAでは特定のデータを別のところに転記する、いわゆるコピー&ペーストを自動化するという処理がよく活用されていますが、その際にセルの一つ一つについていちいち記述するのは面倒ですしミスも多くなります。

そのような繰り返しのときはFor~Next文を使うとスッキリします。前回の例を用いて解説をしていきますね。

コンピュータは繰り返しが大得意ですので、しっかり命令をして私たちの代わりに大いに働いてもらいましょう。

ちなみに、本記事は以下のYouTube動画と連動していますので、合わせてごらんくださいませ。

では、いってみます!

スポンサーリンク

前回のおさらい:一つ一つのセルをいちいちコピペ…

「請求データ」シートから「請求書ひな形」にデータを転記するというプログラムを作りました。

Sub 請求書作成()

'2行目を請求書ひな形に転記
wsTemplate.Cells(21, 1).Value = wsData.Cells(2, 1).Value
wsTemplate.Cells(21, 2).Value = wsData.Cells(2, 2).Value
wsTemplate.Cells(21, 3).Value = wsData.Cells(2, 3).Value

'3行目を請求書ひな形に転記
wsTemplate.Cells(22, 1).Value = wsData.Cells(3, 1).Value
wsTemplate.Cells(22, 2).Value = wsData.Cells(3, 2).Value
wsTemplate.Cells(22, 3).Value = wsData.Cells(3, 3).Value

'4行目を請求書ひな形に転記
wsTemplate.Cells(23, 1).Value = wsData.Cells(4, 1).Value
wsTemplate.Cells(23, 2).Value = wsData.Cells(4, 2).Value
wsTemplate.Cells(23, 3).Value = wsData.Cells(4, 3).Value

End Sub

はい、明らかにダルい書き方です。

セルを一つ一つコピペをするような命令になっています。

いちいち記述するのが面倒ですし、行数や列数の数値を間違えてしまいそうです。

こういうときはFor~Nextを使う絶好のチャンス!

For~Next文の書き方

For~Next文は繰り返しの回数が決まっているときの反復処理の際に使用します。

書式は以下のとおりです。

For カウント変数 = 最初の値 To 最後の値
 ’繰り返したい処理
Next カウント変数

カウント変数は、For~Nextを繰り返すたびに値が1ずつ加算されていくという特性を持つ変数で、たいがいiやjなどのアルファベット1文字の変数を使います。

エクセルVBAの場合は繰り返しながら行や列を移動しながら何かしらかの処理をする場合が多いので、1つずつ増えてくれるという特性は大変重宝します。

従ってFor~Nextの構文で決めるべきは最初の値、最後の値、処理内容の3つを決めるだけです。

具体的な例ですと

Sub test()
Dim i As Long
For i = 1 To 3
    Debug.Print i    
Next i
End Sub

これは、「イミディエイトウィンドウにiの内容を表示する」という処理をi=1からi=3になるまで繰り返すということになりますので、結果としては

For~Nextの例

と表示されます。

For~Nextで行を移動しながらコピぺを繰り返し

今回のケースでは「請求データ」シートの2行目から4行目のデータを

エクセルVBAで使用する請求データ

以下の「請求書ひな形」の21行目から23行目に転記というものです。

エクセルVBAで使用する請求書ひな形

「請求データ」シートの開始行は2、「請求書ひな形」の開始行は21ですから、以下のように書くことができます。

Dim i As Long
For i = 0 To 2
    wsTemplate.Cells(21 + i, 1).Value = wsData.Cells(2 + i, 1).Value
    wsTemplate.Cells(21 + i, 2).Value = wsData.Cells(2 + i, 2).Value
    wsTemplate.Cells(21 + i, 3).Value = wsData.Cells(2 + i, 3).Value
Next i

「請求書ひな形」用のカウント変数を用意する

ですが、「21+」とか「2+」とかいちいち足し算を入れるのが、ちょっとややこしいかも知れません。

そんな場合は、もう一つ別のカウント変数を用意すると、むしろスッキリするかも知れません。

以下のようにするのです。

Dim i As Long, k As Long
k = 21
For i = 2 To 4
    wsTemplate.Cells(k, 1).Value = wsData.Cells(i, 1).Value
    wsTemplate.Cells(k, 2).Value = wsData.Cells(i, 2).Value
    wsTemplate.Cells(k, 3).Value = wsData.Cells(i, 3).Value
    k = k + 1
Next i

つまり、それぞれのカウント変数が以下のような役割を果たします。

  • i:「請求データ」の現在の行を表すカウント変数
  • k:「請求書ひな形」の現在の行を表すカウント変数

ちょっと行数は増えますが、むしろこちらのほうがわかりやすいですよね。

For~Next文を入れ子にして列方向にも繰り返す

さて、これでだいぶスッキリさせることができたのですが、さらに簡略化することができます。

1列目から始まって3列目まで同じ処理を繰り返していますので、列方向でもFor~Next文で置き換えることができます。

Dim i As Long, j As Long, k As Long
k = 21
For i = 2 To 4
    For j = 1 To 3
        wsTemplate.Cells(k, j).Value = wsData.Cells(i, j).Value
    Next j
    k = k + 1
Next i

元々のプログラムが何だったのか、というくらいスッキリしましたね。

このようにFor~Next文の中に、For~Next文を記述するような書き方を入れ子(またはネスト)といいます。

コピペの自動化の場合は、行移動に繰り返す中に、列移動の繰り返しを入れ子するというのが非常にスタンダードな方法ですので、ぜひマスターしちゃってください。

まとめ

今回はFor~Next文をガッツリと解説させて頂きました。

全体のプログラムはこちらです。

Sub 請求書作成()

Dim i As Long, j As Long, k As Long
k = 21
For i = 2 To 4
    For j = 1 To 3
        wsTemplate.Cells(k, j).Value = wsData.Cells(i, j).Value
    Next j
    k = k + 1
Next i

End Sub

エクセルVBAの場合、コピペの自動化をはじめ、For~Next文はかなり使いますので、ここでしっかり慣れて頂けると良いです。

また、For~Nextの考え方や記述法はVBAに限らず、様々なプログラム言語で応用が利く汎用性の高いものです。

エクセルVBAですと、実際に”表”という形で視覚的に動きを見ることができますので、プログラミング初心者としてはとても入りやすいと思います。

次回はこのプログラムをさらに発展させて、より実用的なものに近づけていますので、合わせてお読みください。

【初心者向けエクセルVBA】行の数をカウントする&不要な行を隠す
今回は行数をカウントする、行を隠す、などの「行を取り扱うテクニック」を紹介しています。いずれもデータや帳票を扱ったエクセルVBAではかなり重宝するテクニックですので、知っておいて損はありませんよ。

どうぞお楽しみに!

連載目次:データ一覧から請求書を自動で作る

お仕事において特定のデータ一覧から必要な情報を抽出するということは頻繁にありうると思います。ここではデータ一覧から請求書を作るということを目標に、実務で使えるスキルをまっすぐに身に着けることを目的としています。
  1. 【初心者向けエクセルVBA】データ一覧から請求書を自動で作る
  2. 【初心者向けエクセルVBA】ワークシートをオブジェクト名で取り扱う方法
  3. 【初心者向けエクセルVBA】For~Next文で簡潔にプログラムを書く
  4. 【初心者向けエクセルVBA】行の数をカウントする&不要な行を隠す
  5. 【初心者向けエクセルVBA】文字列の連結&Format関数での書式変更
  6. 【初心者向けエクセルVBA】セル範囲を一気にまとめてコピーする方法
  7. 【初心者向けエクセルVBA】ワークシートのデータのある範囲だけをピッタリ取得する方法
  8. 【初心者向けエクセルVBA】セル範囲の平行移動をする方法・リサイズをする方法
  9. 【初心者向けエクセルVBA】日付データから年・月・日を取り出す
  10. 【初心者向けエクセルVBA】If~Thenを使った条件分岐の超入門
  11. 【初心者向けエクセルVBA】For~Next文でセル範囲を一行ずつ移動させる
  12. 【初心者向けエクセルVBA】セル範囲のクリア~ClearContentsメソッドとClearメソッド
  13. 【初心者向けエクセルVBA】ワークシート・セルを選択する方法の色々について
  14. 【初心者向けエクセルVBA】入力ダイアログを表示するInputBoxメソッドの使い方
  15. 【初心者向けエクセルVBA】日付データから月末日と翌月末日を自動算出する
  16. 【初心者向けエクセルVBA】ワークシートをコピーする方法とそのシート名を変更する方法
  17. 【初心者向けエクセルVBA】オブジェクトを変数にセットして取り扱う方法
  18. 【初心者向けエクセルVBA】Openメソッドで新たなブックを開く方法
  19. 【初心者向けエクセルVBA】現在マクロを書いているブックのフォルダパスを取得する
  20. 【初心者向けエクセルVBA】開いたブックとそのワークシートをオブジェクト変数にセットする
  21. 【初心者向けエクセルVBA】ワークブックを別名で保存して閉じる方法
  22. 【初心者向けエクセルVBA】取引先別に請求書を作成するマクロを作る

コメント

  1. Nats より:

    Cells(21 + i, j)のセルが、結合されたセルだった場合、どのようなコードを使用すればよいでしょうか。
    MargeAreaとかためしているのですが、エラーがでて困っております.
    よろしくお願いいたします.

    • コメントありがとうございます!

      結合セル…難儀ですね。
      元のシートを拝見すれば解決する方法もあるかも知れないのですが、単純にセルの結合を使わないシートにして頂くほうが良いと思います。

      こちらの記事もご参考いただければ幸いです。
      https://tonari-it.com/release-cell-binding/

タイトルとURLをコピーしました