<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>For Each &#8211; biz-tactics</title>
	<atom:link href="https://mashukabu.com/tag/for-each/feed/" rel="self" type="application/rss+xml" />
	<link>https://mashukabu.com</link>
	<description></description>
	<lastBuildDate>Mon, 08 Jun 2026 15:50:42 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://mashukabu.com/wp-content/uploads/2022/04/cropped-site-icon-32x32.png</url>
	<title>For Each &#8211; biz-tactics</title>
	<link>https://mashukabu.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>VBAで複数シート間のデータを転記・集約する方法｜For Eachで全シート一括コピー</title>
		<link>https://mashukabu.com/vba-copy-data-between-sheets/</link>
					<comments>https://mashukabu.com/vba-copy-data-between-sheets/#respond</comments>
		
		<dc:creator><![CDATA[まっしゅ]]></dc:creator>
		<pubDate>Mon, 08 Jun 2026 15:50:42 +0000</pubDate>
				<category><![CDATA[VBA・マクロ]]></category>
		<category><![CDATA[Excel]]></category>
		<category><![CDATA[For Each]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[シート転記]]></category>
		<category><![CDATA[マクロ]]></category>
		<category><![CDATA[複数シート]]></category>
		<guid isPermaLink="false">https://mashukabu.com/?p=7847</guid>

					<description><![CDATA[VBAで複数シート間のデータを転記・集約する方法を3パターンのコードで解説。単純転記・For Eachによる全シート集約・条件付き転記まで、コピペで動く完成コードと仕組みの説明をセットで紹介します。]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">「Sheet1に入力したデータを、Sheet2にも手で写している」。「月別シートの数字を、毎月集計シートにコピペでまとめている」。こんな作業を繰り返していませんか。</p>



<p class="wp-block-paragraph">シートが増えるほど、コピペの回数も増えていきます。1枚あたり数分でも、10枚あれば30分以上。しかも貼り間違いや行のズレといったミスもつきまといます。</p>



<p class="wp-block-paragraph">そんなシート間のデータ転記・集約は、VBAで一瞬で片づけられます。この記事では、コピペでそのまま動く完成コードを3パターン用意しました。単純な別シート転記から、For Eachによる全シート一括集約、条件付き転記までを順番に解説します。</p>




  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-1" checked><label class="toc-title" for="toc-checkbox-1">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">VBAでシート間のデータを転記・集約してできること</a></li><li><a href="#toc2" tabindex="0">VBEの起動とマクロを書く準備</a><ol><li><a href="#toc3" tabindex="0">VBEの開き方</a></li><li><a href="#toc4" tabindex="0">標準モジュールの挿入</a></li><li><a href="#toc5" tabindex="0">.xlsmで保存することに注意</a></li></ol></li><li><a href="#toc6" tabindex="0">パターン1：別シートにデータを転記する基本コード</a><ol><li><a href="#toc7" tabindex="0">コードの仕組みを理解する</a></li></ol></li><li><a href="#toc8" tabindex="0">パターン2：For Eachで全シートを集計シートに集約する</a><ol><li><a href="#toc9" tabindex="0">コードの仕組みを理解する</a></li></ol></li><li><a href="#toc10" tabindex="0">パターン3：条件に合うデータだけを別シートに転記する</a><ol><li><a href="#toc11" tabindex="0">コードの仕組みを理解する</a></li></ol></li><li><a href="#toc12" tabindex="0">VBAのシート転記でよくあるエラーと対処法</a><ol><li><a href="#toc13" tabindex="0">実行時エラー9：インデックスが有効範囲にありません</a></li><li><a href="#toc14" tabindex="0">実行時エラー13：型が一致しません</a></li><li><a href="#toc15" tabindex="0">実行時エラー1004：Rangeの指定が不正</a></li><li><a href="#toc16" tabindex="0">大量データは画面更新を止めると速い</a></li></ol></li><li><a href="#toc17" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">VBAでシート間のデータを転記・集約してできること</span></h2>



<p class="wp-block-paragraph">まずは、VBAを使うとシート間のデータ処理がどう変わるのかを見ておきましょう。</p>



<p class="wp-block-paragraph">手作業では、シートを切り替えてコピーして、別のシートに貼り付ける、という操作の繰り返しです。シートが10枚あれば、この往復を10回行うことになります。</p>



<p class="wp-block-paragraph">VBAなら、この往復をコードに書いておくだけです。マクロを実行すれば、全シートの処理が数秒で終わります。</p>



<p class="wp-block-paragraph">具体的には、次のような処理を自動化できます。</p>



<ul class="wp-block-list"><li>特定のシートのデータを、別のシートに丸ごと転記する</li><li>複数のシートを1枚の集計シートにまとめて集約する</li><li>「ステータスが完了の行だけ」のように条件付きで転記する</li></ul>



<p class="wp-block-paragraph">手作業とVBAの違いを、簡単な表で比べてみます。</p>



<figure class="wp-block-table"><table><thead><tr><th>項目</th><th>手作業</th><th>VBA</th></tr></thead><tbody><tr><td>10シートの集約</td><td>約30分</td><td>数秒</td></tr><tr><td>貼り付けミス</td><td>起きやすい</td><td>起きない</td></tr><tr><td>翌月の再実行</td><td>また30分</td><td>ボタン1つ</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">一度コードを作ってしまえば、翌月以降は実行するだけです。この「作り置き」ができるのがVBAの強みですね。</p>



<h2 class="wp-block-heading"><span id="toc2">VBEの起動とマクロを書く準備</span></h2>



<p class="wp-block-paragraph">コードを書く前に、VBE（Visual Basic Editor）という編集画面を開きます。VBEは、VBAのコードを書くための専用エディタです。</p>



<h3 class="wp-block-heading"><span id="toc3">VBEの開き方</span></h3>



<p class="wp-block-paragraph">VBEを開く方法は2つあります。一番早いのは、Excelの画面で <code>Alt + F11</code> を押す方法です。これだけでVBEが立ち上がります。</p>



<p class="wp-block-paragraph">もう1つは、リボンの「開発」タブから開く方法です。「開発」タブの「Visual Basic」ボタンをクリックします。</p>



<p class="wp-block-paragraph">「開発」タブが見当たらない場合は、表示設定が必要です。次の手順で追加してください。</p>



<ol class="wp-block-list"><li>「ファイル」→「オプション」を開く</li><li>「リボンのユーザー設定」を選ぶ</li><li>右側の一覧で「開発」にチェックを入れる</li><li>「OK」を押す</li></ol>



<p class="wp-block-paragraph">これで「開発」タブがリボンに表示されます。</p>



<h3 class="wp-block-heading"><span id="toc4">標準モジュールの挿入</span></h3>



<p class="wp-block-paragraph">VBEが開いたら、コードを書く場所を用意します。メニューの「挿入」→「標準モジュール」を選んでください。</p>



<p class="wp-block-paragraph">すると「Module1」という白い画面が開きます。ここにコードを書いていきます。VBEの画面構成をもっと詳しく知りたい方は、<a href="https://mashukabu.com/excel-vba-vbe-menu-explanation/">VBEの画面の見方を図解で解説</a>もあわせてご覧ください。</p>



<h3 class="wp-block-heading"><span id="toc5">.xlsmで保存することに注意</span></h3>



<p class="wp-block-paragraph">マクロを書いたブックは、必ず <code>.xlsm</code>（マクロ有効ブック）形式で保存します。普段の <code>.xlsx</code> 形式では、マクロが保存できません。</p>



<p class="wp-block-paragraph"><code>.xlsx</code> のまま保存しようとすると、「マクロなしのブックとして保存されます」という警告が出ます。このまま保存すると、せっかく書いたコードが消えてしまいます。</p>



<p class="wp-block-paragraph">保存時は「名前を付けて保存」で、ファイルの種類を「Excel マクロ有効ブック（.xlsm）」に変えてください。詳しい違いは<a href="https://mashukabu.com/excel-vba-filetype-explanation/">.xlsxと.xlsmの違い</a>で解説しています。</p>



<h2 class="wp-block-heading"><span id="toc6">パターン1：別シートにデータを転記する基本コード</span></h2>



<p class="wp-block-paragraph">最初は一番シンプルな、別シートへの転記です。「Sheet1のデータを、Sheet2の続きに追記する」という、よくあるパターンから見ていきましょう。</p>



<p class="wp-block-paragraph">ここでは、Sheet1のA1からC5までのデータを、Sheet2の末尾に追記する例を使います。</p>



<pre class="wp-block-code"><code>Sub データ転記_基本()

    '--- コピー元とコピー先のシートを指定 ---
    Dim wsFrom As Worksheet '転記元シート
    Dim wsTo As Worksheet   '転記先シート
    Set wsFrom = Worksheets(&quot;Sheet1&quot;)
    Set wsTo = Worksheets(&quot;Sheet2&quot;)

    '--- 転記先の最終行を取得して、次の行を書き込み位置にする ---
    Dim tRow As Long '転記先の書き込み行
    tRow = wsTo.Cells(Rows.Count, 1).End(xlUp).Row + 1

    '--- A1:C5の範囲を、転記先の末尾に値だけコピー ---
    wsTo.Range(&quot;A&quot; &amp; tRow &amp; &quot;:C&quot; &amp; tRow + 4).Value = wsFrom.Range(&quot;A1:C5&quot;).Value

    MsgBox &quot;転記が完了しました&quot;

End Sub</code></pre>



<p class="wp-block-paragraph">このコードを書いたら、<code>F5</code> キーかメニューの「実行」でマクロを動かします。Sheet2の続きにSheet1のデータが追記されれば成功です。</p>



<p class="wp-block-paragraph">自分の環境に合わせて変えるのは、次の3か所です。</p>



<ul class="wp-block-list"><li><code>Worksheets("Sheet1")</code> … 転記元のシート名</li><li><code>Worksheets("Sheet2")</code> … 転記先のシート名</li><li><code>Range("A1:C5")</code> … コピーするデータの範囲</li></ul>



<h3 class="wp-block-heading"><span id="toc7">コードの仕組みを理解する</span></h3>



<p class="wp-block-paragraph">このコードのポイントは、別シートを操作するときに必ずシート名を付けている点です。<code>wsFrom.Range(...)</code> のように、どのシートのどの範囲かを明示しています。</p>



<p class="wp-block-paragraph">シート名を付けずに <code>Range("A1")</code> と書くと、今表示しているシートを指してしまいます。別シート操作では、シートの指定を省略しないのがポイントです。</p>



<p class="wp-block-paragraph">最終行は <code>Cells(Rows.Count, 1).End(xlUp).Row</code> で取得しています。これは「A列の一番下から上に詰めて、最初にデータがある行」を返す定番のテクニックです。最終行の取得方法は<a href="https://mashukabu.com/excel-vba-howto-get-lastrow/">VBA最終行の取得</a>でも詳しく解説しています。</p>



<p class="wp-block-paragraph">また、<code>コピー先.Value = コピー元.Value</code> のように範囲ごと値を代入しています。セルを1つずつコピーするより、この書き方のほうがずっと高速です。</p>



<h2 class="wp-block-heading"><span id="toc8">パターン2：For Eachで全シートを集計シートに集約する</span></h2>



<p class="wp-block-paragraph">次は、複数のシートを1枚にまとめる集約です。「月別シートを、集計シートに全部まとめたい」というニーズに応えます。</p>



<p class="wp-block-paragraph">ここでは、「集計」という名前のシートを用意しておきます。そして、それ以外の全シートのデータを、集計シートに順番に追記していきます。</p>



<pre class="wp-block-code"><code>Sub 全シート集約()

    '--- 集約先シートを指定 ---
    Dim wsSum As Worksheet '集約先シート
    Set wsSum = Worksheets(&quot;集計&quot;)

    '--- 全シートを1枚ずつ処理する ---
    Dim ws As Worksheet '処理中のシート
    For Each ws In Worksheets

        '--- 集計シート自身は処理しない ---
        If ws.Name &lt;&gt; &quot;集計&quot; Then

            '--- 各シートの最終行を取得 ---
            Dim lastRow As Long '各シートのデータ最終行
            lastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row

            '--- 集約先の書き込み位置（最終行の次）を取得 ---
            Dim tRow As Long '集約先の書き込み行
            tRow = wsSum.Cells(Rows.Count, 1).End(xlUp).Row + 1

            '--- 2行目から最終行までを集約先に転記（1行目は見出しとして除外） ---
            ws.Range(&quot;A2:C&quot; &amp; lastRow).Copy wsSum.Range(&quot;A&quot; &amp; tRow)

        End If

    Next ws

    MsgBox &quot;全シートの集約が完了しました&quot;

End Sub</code></pre>



<p class="wp-block-paragraph">このコードを実行すると、集計シート以外の全シートのデータが、集計シートに1つにまとまります。シートが何枚あっても、コードはそのままで動きます。</p>



<p class="wp-block-paragraph">ちょっとむずかしく見えますが、やっていることはシンプルです。「1枚ずつシートを取り出して、集計シートの末尾に貼る」を全シートで繰り返しているだけです。</p>



<h3 class="wp-block-heading"><span id="toc9">コードの仕組みを理解する</span></h3>



<p class="wp-block-paragraph">ここで使っている <code>For Each ws In Worksheets</code> は、全シートを1つずつ取り出すループです。<code>ws</code> には、処理中のシートが順番に入っていきます。For Eachの基本は<a href="https://mashukabu.com/vba-howto-use-for-each-next/">VBA For Eachの使い方</a>で解説しています。</p>



<p class="wp-block-paragraph">処理の流れは次の3ステップです。</p>



<ol class="wp-block-list"><li><code>For Each</code> で全シートを1枚ずつ取り出す</li><li><code>If ws.Name <> "集計"</code> で集計シート自身を除外する</li><li>各シートの2行目以降を、集計シートの末尾にコピーする</li></ol>



<p class="wp-block-paragraph">集計シート自身を除外するガードは、必ず入れてください。これがないと、集計シート自身のデータも集計シートに貼り付けてしまいます。</p>



<p class="wp-block-paragraph">見出し行を除くため、コピー範囲を <code>A2</code> から始めています。各シートの1行目が見出しの場合、この指定でデータ部分だけをまとめられます。</p>



<p class="wp-block-paragraph">ここでは書式ごとコピーする <code>Copy</code> を使いました。値だけでよければ、パターン1のように <code>Value</code> での代入のほうが高速です。</p>



<h2 class="wp-block-heading"><span id="toc10">パターン3：条件に合うデータだけを別シートに転記する</span></h2>



<p class="wp-block-paragraph">最後は、条件付きの転記です。「ステータスが完了の行だけ、完了シートに移したい」のように、特定の値の行だけを抜き出します。</p>



<p class="wp-block-paragraph">ここでは、Sheet1のC列に入った「ステータス」を見て、「完了」の行だけを「完了」シートに転記する例を使います。</p>



<pre class="wp-block-code"><code>Sub 条件付き転記()

    '--- 転記元と転記先のシートを指定 ---
    Dim wsFrom As Worksheet '転記元シート
    Dim wsTo As Worksheet   '転記先シート
    Set wsFrom = Worksheets(&quot;Sheet1&quot;)
    Set wsTo = Worksheets(&quot;完了&quot;)

    '--- 転記元の最終行を取得 ---
    Dim lastRow As Long '転記元のデータ最終行
    lastRow = wsFrom.Cells(Rows.Count, 1).End(xlUp).Row

    '--- 転記先の書き込み開始行を取得 ---
    Dim tRow As Long '転記先の書き込み行
    tRow = wsTo.Cells(Rows.Count, 1).End(xlUp).Row + 1

    '--- 2行目から最終行まで1行ずつ判定する ---
    Dim i As Long 'ループ用の行カウンター
    For i = 2 To lastRow

        '--- C列が「完了」の行だけ転記する ---
        If wsFrom.Cells(i, 3).Value = &quot;完了&quot; Then
            wsTo.Range(&quot;A&quot; &amp; tRow &amp; &quot;:C&quot; &amp; tRow).Value = _
                wsFrom.Range(&quot;A&quot; &amp; i &amp; &quot;:C&quot; &amp; i).Value
            tRow = tRow + 1 '転記したので書き込み行を1つ進める
        End If

    Next i

    MsgBox &quot;条件に合うデータの転記が完了しました&quot;

End Sub</code></pre>



<p class="wp-block-paragraph">実行すると、C列が「完了」の行だけが、完了シートに集まります。条件を変えたいときは、<code>If wsFrom.Cells(i, 3).Value = "完了"</code> の部分を書き換えます。</p>



<p class="wp-block-paragraph">たとえば「金額が10000以上の行だけ」にしたいなら、<code>wsFrom.Cells(i, 4).Value >= 10000</code> のように変えるだけです。</p>



<h3 class="wp-block-heading"><span id="toc11">コードの仕組みを理解する</span></h3>



<p class="wp-block-paragraph">このコードは、1行ずつ条件をチェックしていく作りです。<code>For i = 2 To lastRow</code> で、2行目から最終行までを順番に見ていきます。</p>



<p class="wp-block-paragraph">ポイントは、転記先の書き込み行 <code>tRow</code> を変数で管理している点です。条件に合う行を転記するたびに、<code>tRow = tRow + 1</code> で1つ進めます。これで、転記先に隙間なく詰めて書き込めます。</p>



<p class="wp-block-paragraph"><code>Cells(i, 3)</code> の <code>3</code> はC列を意味します。判定する列を変えたいときは、この数字を変えます。1ならA列、2ならB列という対応です。</p>



<p class="wp-block-paragraph">行と列を数字で指定する <code>Cells</code> の使い方は、<a href="https://mashukabu.com/excel-vba-range-cells/">VBA RangeとCellsの違い</a>で詳しく解説しています。ループ処理の中では、この <code>Cells</code> が便利です。</p>



<h2 class="wp-block-heading"><span id="toc12">VBAのシート転記でよくあるエラーと対処法</span></h2>



<p class="wp-block-paragraph">シート転記のコードでつまずきやすいエラーを、3つにしぼって紹介します。</p>



<h3 class="wp-block-heading"><span id="toc13">実行時エラー9：インデックスが有効範囲にありません</span></h3>



<p class="wp-block-paragraph">これは、指定したシート名が存在しないときに出るエラーです。原因のほとんどはシート名のタイプミスです。</p>



<p class="wp-block-paragraph">たとえば、コードでは「集計」と書いているのに、実際のシート名が「集計表」だと、このエラーになります。全角と半角の違い、余分なスペースもよくある原因です。</p>



<p class="wp-block-paragraph">シート名を確認するには、次のコードが便利です。</p>



<pre class="wp-block-code"><code>Sub シート名を確認()

    Dim ws As Worksheet '確認用のシート
    For Each ws In Worksheets
        Debug.Print ws.Name '各シート名をイミディエイトウィンドウに出力
    Next ws

End Sub</code></pre>



<p class="wp-block-paragraph">これを実行すると、全シートの正確な名前がイミディエイトウィンドウに表示されます。表示された名前を、コードにそのままコピーすると確実です。</p>



<h3 class="wp-block-heading"><span id="toc14">実行時エラー13：型が一致しません</span></h3>



<p class="wp-block-paragraph">これは、データの型が合っていないときに出ます。たとえば、文字が入ったセルを数値として比較しようとした場合などです。</p>



<p class="wp-block-paragraph">条件付き転記で「金額が10000以上」と判定するとき、その列に文字列が混ざっているとこのエラーが起きます。判定に使う列には、数値だけが入っているか確認してください。</p>



<h3 class="wp-block-heading"><span id="toc15">実行時エラー1004：Rangeの指定が不正</span></h3>



<p class="wp-block-paragraph">Range指定の書き方が間違っているときや、保護されたシートに書き込もうとしたときに出ます。</p>



<p class="wp-block-paragraph">転記先シートが保護されていないか、まず確認しましょう。シートの保護がかかっていると、VBAでも書き込めません。</p>



<p class="wp-block-paragraph">その他のエラーについては、<a href="https://mashukabu.com/vba-error-guide/">VBAマクロのエラー解決ガイド</a>で頻出エラー別にまとめています。</p>



<h3 class="wp-block-heading"><span id="toc16">大量データは画面更新を止めると速い</span></h3>



<p class="wp-block-paragraph">エラーではありませんが、データ量が多いと処理が遅く感じることがあります。そんなときは、画面更新を一時的に止めると体感速度が上がります。</p>



<pre class="wp-block-code"><code>Sub 高速化のひな形()

    Application.ScreenUpdating = False '画面更新を止める

    '--- ここに転記・集約の処理を書く ---

    Application.ScreenUpdating = True '画面更新を元に戻す

End Sub</code></pre>



<p class="wp-block-paragraph">処理の前後で画面更新をオフ・オンにするだけです。最後に必ず <code>True</code> へ戻すのを忘れないでください。</p>



<h2 class="wp-block-heading"><span id="toc17">まとめ</span></h2>



<p class="wp-block-paragraph">VBAで複数シート間のデータを転記・集約する方法を、3つのパターンで解説しました。最後にポイントを整理します。</p>



<ul class="wp-block-list"><li>パターン1：別シートへの単純転記は、シート名を明示して <code>Value</code> で範囲ごと代入する</li><li>パターン2：全シート集約は <code>For Each</code> でループし、集計シート自身を除外する</li><li>パターン3：条件付き転記は1行ずつ判定し、書き込み行を変数で管理する</li><li>別シート操作では、必ずシート名を付ける</li><li>マクロを書いたら <code>.xlsm</code> 形式で保存する</li></ul>



<p class="wp-block-paragraph">まずはパターン1から、自分の業務のシート名に書き換えて試してみてください。動くコードが1つできれば、あとは応用が効きます。</p>



<p class="wp-block-paragraph">ループ処理をもっと深く知りたい方は<a href="https://mashukabu.com/excel-vba-howto-use-for/">VBA For~Next文の使い方</a>を、VBAで業務全体を自動化したい方は<a href="https://mashukabu.com/excel-vba-automation-guide/">Excel VBAで仕事を自動化する方法</a>もあわせてご覧ください。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://mashukabu.com/vba-copy-data-between-sheets/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>VBA RangeとCellsの違いと使い分け｜実務シナリオ別に選び方を解説</title>
		<link>https://mashukabu.com/excel-vba-range-cells/</link>
					<comments>https://mashukabu.com/excel-vba-range-cells/#respond</comments>
		
		<dc:creator><![CDATA[まっしゅ]]></dc:creator>
		<pubDate>Fri, 11 Feb 2022 14:30:39 +0000</pubDate>
				<category><![CDATA[VBA・マクロ]]></category>
		<category><![CDATA[1004エラー]]></category>
		<category><![CDATA[Cells]]></category>
		<category><![CDATA[For Each]]></category>
		<category><![CDATA[Range]]></category>
		<category><![CDATA[Resize]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[セル指定]]></category>
		<category><![CDATA[ループ処理]]></category>
		<category><![CDATA[使い分け]]></category>
		<guid isPermaLink="false">https://mashukabu.com/?p=1024</guid>

					<description><![CDATA[VBAのRangeとCellsの違いと使い分けを実務シナリオ別に解説。For文・For Eachループ、Offset・Resizeとの組み合わせ、Range(Cells,Cells)の動的範囲指定、1004エラーの原因と対処まで、コード例つきでわかりやすく説明します。]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Excel VBAでセルを操作するとき、RangeとCellsのどちらを使うか迷いませんか。</p>



<p class="wp-block-paragraph">書き方がまったく違うので、「結局どっちが正解なの？」と手が止まりがちですよね。使い分けを間違えると、ループ処理でセル番地の文字列結合が必要になったり、別シート操作で1004エラーに悩まされたりします。</p>



<p class="wp-block-paragraph">この記事では、RangeとCellsの違いを比較表で整理し、実務シナリオごとの選び方をお伝えします。Offset・Resizeとの組み合わせやFor Eachでのループ処理も取り上げるので、読み終わるころには「この場面ならこっち」と迷わず選べるようになりますよ。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p><strong>NOTE</strong></p><p>VBAを初めて触る方は、先に「<a href="https://mashukabu.com/excel-vba-vbe-menu-explanation/">VBE画面の見方</a>」をチェックしておくとスムーズです。</p></blockquote>




  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-2" checked><label class="toc-title" for="toc-checkbox-2">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">RangeとCellsの違いを一覧でおさらい</a><ol><li><a href="#toc2" tabindex="0">Range：アドレス直書きでわかりやすい</a></li><li><a href="#toc3" tabindex="0">Cells：行番号・列番号で指定できる</a></li></ol></li><li><a href="#toc4" tabindex="0">VBA Cellsを使うべき場面</a><ol><li><a href="#toc5" tabindex="0">For文でループするとき</a></li><li><a href="#toc6" tabindex="0">行列を動的に計算したいとき</a></li></ol></li><li><a href="#toc7" tabindex="0">VBA Rangeを使うべき場面</a><ol><li><a href="#toc8" tabindex="0">セルアドレスが固定のとき</a></li><li><a href="#toc9" tabindex="0">名前付き範囲を指定するとき</a></li></ol></li><li><a href="#toc10" tabindex="0">For Eachで範囲内のセルを一括処理する</a><ol><li><a href="#toc11" tabindex="0">For EachとRangeの基本パターン</a></li><li><a href="#toc12" tabindex="0">For EachとCellsの使い分け</a></li><li><a href="#toc13" tabindex="0">For Eachで実務に使えるパターン：条件に合うセルを集計</a></li></ol></li><li><a href="#toc14" tabindex="0">Offset・Resizeで基準セルからの相対指定</a><ol><li><a href="#toc15" tabindex="0">Offset：基準セルから行・列をずらす</a></li><li><a href="#toc16" tabindex="0">Resize：範囲のサイズを変更する</a></li><li><a href="#toc17" tabindex="0">Offset + Resize の組み合わせ：ヘッダーを除外する実例</a></li></ol></li><li><a href="#toc18" tabindex="0">Range(Cells, Cells)の組み合わせ技</a><ol><li><a href="#toc19" tabindex="0">基本構文</a></li><li><a href="#toc20" tabindex="0">開始・終了行を動的に変える実例</a></li></ol></li><li><a href="#toc21" tabindex="0">実務シナリオ別の選択ガイド</a><ol><li><a href="#toc22" tabindex="0">一覧表を上から順に処理する</a></li><li><a href="#toc23" tabindex="0">For Eachで条件付き書式を動的に適用する</a></li><li><a href="#toc24" tabindex="0">可変範囲をまるごとコピーする</a></li><li><a href="#toc25" tabindex="0">集計行をループの外に固定する</a></li><li><a href="#toc26" tabindex="0">シナリオ別まとめ表</a></li></ol></li><li><a href="#toc27" tabindex="0">1004エラーの原因と対処法</a><ol><li><a href="#toc28" tabindex="0">Worksheetオブジェクトの明示</a></li><li><a href="#toc29" tabindex="0">OffsetやResizeでも同じ原則</a></li></ol></li><li><a href="#toc30" tabindex="0">まとめ：迷ったときの使い分け早見表</a><ol><li><a href="#toc31" tabindex="0">関連記事</a></li></ol></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">RangeとCellsの違いを一覧でおさらい</span></h2>



<p class="wp-block-paragraph">まず結論から整理しましょう。RangeとCellsはどちらも「セルを指定する方法」ですが、得意な場面が違います。</p>



<figure class="wp-block-table"><table><thead><tr><th>比較項目</th><th>Range</th><th>Cells</th></tr></thead><tbody><tr><td>書き方</td><td><code>Range("A1")</code></td><td><code>Cells(1, 1)</code></td></tr><tr><td>指定方法</td><td>アドレス文字列</td><td>行番号・列番号（数値）</td></tr><tr><td>複数セル範囲</td><td><code>Range("A1:C10")</code> で直接指定</td><td>単体では1セルのみ</td></tr><tr><td>名前付き範囲</td><td><code>Range("売上合計")</code> で参照可</td><td>非対応</td></tr><tr><td>変数との相性</td><td>文字列結合が必要</td><td>数値をそのまま渡せる</td></tr><tr><td>ループ処理</td><td>For Eachと好相性</td><td>For文カウンターと好相性</td></tr><tr><td>Offset/Resize</td><td>両方で使える</td><td>両方で使える</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">ひとことで言えば、「文字列で指定するか、数値で指定するか」の違いです。この違いが使い分けの根拠になっています。</p>



<h3 class="wp-block-heading"><span id="toc2">Range：アドレス直書きでわかりやすい</span></h3>



<p class="wp-block-paragraph">RangeはExcelシート上の「A1」形式をそのまま使えます。普段のExcel操作と同じ感覚なので、直感的に読み書きできるのが強みです。</p>



<pre class="wp-block-code"><code>' 1つのセルに値を入力
Range(&quot;A1&quot;).Value = &quot;こんにちは&quot;

' 範囲をまとめて太字にする
Range(&quot;A1:C10&quot;).Font.Bold = True

' 離れたセルを一括指定
Range(&quot;A1,C3,E5&quot;).Font.Color = vbRed</code></pre>



<p class="wp-block-paragraph">Rangeの詳しい使い方は「<a href="https://mashukabu.com/excel-vba-howto-use-range/">VBA Rangeの使い方</a>」でも解説しています。</p>



<h3 class="wp-block-heading"><span id="toc3">Cells：行番号・列番号で指定できる</span></h3>



<p class="wp-block-paragraph">Cellsは行と列を数値で指定します。「Cells(行, 列)」の形で、列もアルファベットではなく数字で書くのがポイントです。</p>



<pre class="wp-block-code"><code>' A1セル（1行目・1列目）に値を入力
Cells(1, 1).Value = &quot;こんにちは&quot;

' B3セル（3行目・2列目）に値を入力
Cells(3, 2).Value = 100</code></pre>



<p class="wp-block-paragraph">数値だけで指定するので、変数と組み合わせやすいのが最大の強みです。</p>



<h2 class="wp-block-heading"><span id="toc4">VBA Cellsを使うべき場面</span></h2>



<p class="wp-block-paragraph">Cellsが本領を発揮するのは、セルの位置を動的に変えたいときです。</p>



<h3 class="wp-block-heading"><span id="toc5">For文でループするとき</span></h3>



<p class="wp-block-paragraph">Cellsの最大の強みは、変数をそのまま行番号に渡せることです。</p>



<pre class="wp-block-code"><code>' A列の1行目〜10行目に連番を入力
Dim i As Long
For i = 1 To 10
    Cells(i, 1).Value = i
Next i</code></pre>



<p class="wp-block-paragraph">同じ処理をRangeで書くとこうなります。</p>



<pre class="wp-block-code"><code>' Rangeだと文字列結合が必要
Dim i As Long
For i = 1 To 10
    Range(&quot;A&quot; &amp; i).Value = i
Next i</code></pre>



<p class="wp-block-paragraph">動きは同じですが、<code>"A" & i</code> と文字列結合が入ります。列も変数にしたい場合はさらに複雑になるので、ループ処理ではCellsがおすすめです。</p>



<p class="wp-block-paragraph">For文の書き方をもっと知りたい方は「<a href="https://mashukabu.com/excel-vba-howto-use-for/">VBA For文の使い方</a>」もチェックしてみてください。</p>



<h3 class="wp-block-heading"><span id="toc6">行列を動的に計算したいとき</span></h3>



<p class="wp-block-paragraph">行も列も変数で動かしたい場合、Cellsの数値指定が活きます。</p>



<pre class="wp-block-code"><code>' 5×5の掛け算表を作る
Dim r As Long  ' 行カウンター
Dim c As Long  ' 列カウンター
For r = 1 To 5
    For c = 1 To 5
        Cells(r, c).Value = r * c
    Next c
Next r</code></pre>



<p class="wp-block-paragraph">二重ループとの相性は抜群です。Rangeでこれをやると、列番号をアルファベットに変換する処理が必要になり、かなり面倒になります。</p>



<p class="wp-block-paragraph">変数（<code>Dim</code>）の宣言ルールが気になる方は「<a href="https://mashukabu.com/excel-vba-variable-explanation/">変数の使い方とルール</a>」を参照してください。宣言を強制する<a href="https://mashukabu.com/excel-vba-option-explicit/">Option Explicit</a>もあわせて覚えておくと安心ですよ。</p>



<h2 class="wp-block-heading"><span id="toc7">VBA Rangeを使うべき場面</span></h2>



<p class="wp-block-paragraph">一方、Rangeが適しているのは「セルの位置が決まっている」場面です。</p>



<h3 class="wp-block-heading"><span id="toc8">セルアドレスが固定のとき</span></h3>



<p class="wp-block-paragraph">操作対象が固定セルなら、Rangeが読みやすいです。</p>



<pre class="wp-block-code"><code>' 決まったセル範囲をクリアする
Range(&quot;A1:D1&quot;).ClearContents

' ヘッダー行を太字にする
Range(&quot;A1:F1&quot;).Font.Bold = True</code></pre>



<p class="wp-block-paragraph">「A1:D1」とそのまま書けるので、コードを読んだ人がすぐに対象範囲を把握できます。可読性の高さがRangeの大きなメリットです。</p>



<h3 class="wp-block-heading"><span id="toc9">名前付き範囲を指定するとき</span></h3>



<p class="wp-block-paragraph">Excelで名前を定義している場合、Rangeから直接参照できます。</p>



<pre class="wp-block-code"><code>' 名前定義「売上合計」の値を取得
Dim total As Long
total = Range(&quot;売上合計&quot;).Value</code></pre>



<p class="wp-block-paragraph">名前付き範囲はCellsでは参照できません。名前定義を使う場面ではRangeの一択になります。</p>



<p class="wp-block-paragraph">セルの位置が変わってもコードを修正しなくて済むので、実務ではとても便利ですよ。なお、RangeやCellsで取得した値をExcel関数で処理したい場合は「<a href="https://mashukabu.com/excel-vba-howto-use-worksheetfunction/">WorksheetFunctionの使い方</a>」もあわせてチェックしてみてください。</p>



<h2 class="wp-block-heading"><span id="toc10">For Eachで範囲内のセルを一括処理する</span></h2>



<p class="wp-block-paragraph">For Each文を使うと、Range内の各セルを1つずつ取り出して処理できます。「何行目か」を自分で管理しなくていいので、コードがシンプルになるのが魅力です。</p>



<h3 class="wp-block-heading"><span id="toc11">For EachとRangeの基本パターン</span></h3>



<pre class="wp-block-code"><code>Sub 空欄セルに初期値を入れる()
    Dim cell As Range
    For Each cell In Range(&quot;B2:B20&quot;)
        If cell.Value = &quot;&quot; Then
            cell.Value = 0
        End If
    Next cell
End Sub</code></pre>



<p class="wp-block-paragraph"><code>For Each cell In Range(...)</code> と書くだけで、範囲内のセルを上から順に処理してくれます。行番号を管理する <code>i</code> 変数が不要なので、コードの見通しがよくなります。</p>



<p class="wp-block-paragraph">For Each文の詳しい使い方は「<a href="https://mashukabu.com/vba-howto-use-for-each-next/">For Eachの使い方</a>」で解説しています。</p>



<h3 class="wp-block-heading"><span id="toc12">For EachとCellsの使い分け</span></h3>



<p class="wp-block-paragraph">For EachとFor文（Cells）のどちらを選ぶかは、「処理中に行番号が必要かどうか」で決まります。</p>



<pre class="wp-block-code"><code>' ケース1: 行番号が不要 → For Each がシンプル
Sub 負の値を赤くする()
    Dim cell As Range
    For Each cell In Range(&quot;C2:C100&quot;)
        If cell.Value &lt; 0 Then
            cell.Font.Color = vbRed
        End If
    Next cell
End Sub

' ケース2: 行番号を使って別列に書き込む → For + Cells が便利
Sub 判定結果を隣の列に出力する()
    Dim lastRow As Long
    lastRow = Cells(Rows.Count, 3).End(xlUp).Row

    Dim i As Long
    For i = 2 To lastRow
        If Cells(i, 3).Value &gt;= 80 Then
            Cells(i, 4).Value = &quot;合格&quot;
        Else
            Cells(i, 4).Value = &quot;不合格&quot;
        End If
    Next i
End Sub</code></pre>



<p class="wp-block-paragraph">「同じセルだけ触る処理」ならFor Each、「隣の列や別のセルにも書き込む処理」ならFor + Cellsと覚えておくと迷いません。</p>



<h3 class="wp-block-heading"><span id="toc13">For Eachで実務に使えるパターン：条件に合うセルを集計</span></h3>



<p class="wp-block-paragraph">実務でよくあるのが、範囲内のセルを条件でフィルタしながら集計するパターンです。</p>



<pre class="wp-block-code"><code>Sub 部門別の売上を集計する()
    Dim cell As Range
    Dim totalSales As Long

    ' A列が「営業部」の行だけ、B列の金額を合計
    For Each cell In Range(&quot;A2:A50&quot;)
        If cell.Value = &quot;営業部&quot; Then
            totalSales = totalSales + cell.Offset(0, 1).Value
        End If
    Next cell

    Range(&quot;D1&quot;).Value = &quot;営業部合計&quot;
    Range(&quot;E1&quot;).Value = totalSales
End Sub</code></pre>



<p class="wp-block-paragraph">ここで使っている <code>Offset</code> については、次のセクションで詳しく説明します。</p>



<h2 class="wp-block-heading"><span id="toc14">Offset・Resizeで基準セルからの相対指定</span></h2>



<p class="wp-block-paragraph">RangeやCellsで取得したセルを「起点」として、そこから相対的に位置をずらしたり範囲を広げたりできます。これがOffsetとResizeです。</p>



<h3 class="wp-block-heading"><span id="toc15">Offset：基準セルから行・列をずらす</span></h3>



<p class="wp-block-paragraph"><code>Offset(行方向, 列方向)</code> で、基準セルからの相対位置を指定します。</p>



<pre class="wp-block-code"><code>' A1セルから2行下・1列右 → B3セル
Range(&quot;A1&quot;).Offset(2, 1).Value = &quot;ここはB3&quot;

' 現在のセルの1つ右に値を入力
Cells(5, 1).Offset(0, 1).Value = &quot;B5に入力&quot;</code></pre>



<p class="wp-block-paragraph">行方向の正の値は下、負の値は上。列方向の正の値は右、負の値は左です。</p>



<p class="wp-block-paragraph">Offsetが特に活躍するのは、For Eachループの中で隣のセルにアクセスするときです。</p>



<pre class="wp-block-code"><code>Sub 単価と数量から金額を計算する()
    Dim cell As Range
    ' B列（単価）をループして、C列（数量）と掛けた結果をD列に出力
    For Each cell In Range(&quot;B2:B20&quot;)
        If cell.Value &lt;&gt; &quot;&quot; Then
            cell.Offset(0, 2).Value = cell.Value * cell.Offset(0, 1).Value
        End If
    Next cell
End Sub</code></pre>



<p class="wp-block-paragraph">For Eachでは行番号を直接持たないので、「隣のセル」「2列右のセル」にアクセスするにはOffsetが必須です。この組み合わせは実務で非常によく使います。</p>



<h3 class="wp-block-heading"><span id="toc16">Resize：範囲のサイズを変更する</span></h3>



<p class="wp-block-paragraph"><code>Resize(行数, 列数)</code> で、基準セルから指定した大きさの範囲を作ります。</p>



<pre class="wp-block-code"><code>' A1セルを起点に、5行3列の範囲を選択
Range(&quot;A1&quot;).Resize(5, 3).Select

' ヘッダー行を除いたデータ範囲を取得
Dim dataRange As Range
Set dataRange = Range(&quot;A1&quot;).Resize(10, 4)  ' A1:D10</code></pre>



<p class="wp-block-paragraph">Resizeは「データの先頭セルはわかっているが、範囲の大きさを動的に決めたい」ときに重宝します。</p>



<h3 class="wp-block-heading"><span id="toc17">Offset + Resize の組み合わせ：ヘッダーを除外する実例</span></h3>



<p class="wp-block-paragraph">OffsetとResizeを組み合わせると、「ヘッダー行をスキップしてデータ範囲だけ取得する」といった実務的な操作が1行で書けます。</p>



<pre class="wp-block-code"><code>Sub ヘッダーを除いてデータ範囲に色をつける()
    Dim lastRow As Long
    lastRow = Cells(Rows.Count, 1).End(xlUp).Row

    ' A1から始まるテーブルのヘッダーを除外して色付け
    ' Offset(1, 0) で1行下にずらし、Resize(lastRow - 1, 4) でデータ行分の範囲を確保
    Range(&quot;A1&quot;).Offset(1, 0).Resize(lastRow - 1, 4).Interior.Color = RGB(230, 240, 255)
End Sub</code></pre>



<p class="wp-block-paragraph">ちょっとむずかしく見えますが、やっていることはシンプルです。Offset(1, 0) でA2に移動し、Resize(lastRow &#8211; 1, 4) でA2からデータ最終行までの4列分を取得しています。</p>



<p class="wp-block-paragraph">Offset・Resizeの詳しい使い方は「<a href="https://mashukabu.com/excel-vba-howto-use-range/">VBA Rangeの使い方</a>」でも解説しています。</p>



<h2 class="wp-block-heading"><span id="toc18">Range(Cells, Cells)の組み合わせ技</span></h2>



<p class="wp-block-paragraph">RangeとCellsは組み合わせて使えます。これを覚えると、動的な範囲指定がぐっと楽になります。</p>



<h3 class="wp-block-heading"><span id="toc19">基本構文</span></h3>



<p class="wp-block-paragraph"><code>Range(Cells(開始行, 開始列), Cells(終了行, 終了列))</code> の形で書きます。</p>



<pre class="wp-block-code"><code>' A1からE10までを選択
Range(Cells(1, 1), Cells(10, 5)).Select</code></pre>



<p class="wp-block-paragraph">開始位置も終了位置も数値で制御できるのがポイントです。固定範囲にはRange単体、動的範囲にはこの組み合わせと覚えておきましょう。</p>



<h3 class="wp-block-heading"><span id="toc20">開始・終了行を動的に変える実例</span></h3>



<p class="wp-block-paragraph">実務で最もよく使うのが、最終行を取得して動的に範囲を決めるパターンです。</p>



<pre class="wp-block-code"><code>Sub 動的範囲に罫線を引く()
    ' A列の最終行を取得
    Dim lastRow As Long
    lastRow = Cells(Rows.Count, 1).End(xlUp).Row

    ' A1から最終行のC列まで罫線を引く
    Range(Cells(1, 1), Cells(lastRow, 3)).Borders.LineStyle = xlContinuous
End Sub</code></pre>



<p class="wp-block-paragraph"><code>Cells(Rows.Count, 1).End(xlUp).Row</code> でA列の一番下から上に向かって最終行を探しています。データの件数が増減しても自動で対応できるので、実務では非常に重宝します。</p>



<p class="wp-block-paragraph">最終行の取得方法をもっと詳しく知りたい方は「<a href="https://mashukabu.com/excel-vba-howto-get-lastrow/">最終行を取得する3つの方法</a>」もどうぞ。</p>



<p class="wp-block-paragraph">もうひとつ、可変範囲をコピーする実例も見てみましょう。</p>



<pre class="wp-block-code"><code>Sub データ範囲をコピーして貼り付ける()
    Dim lastRow As Long
    Dim lastCol As Long

    ' データの最終行・最終列を取得
    lastRow = Cells(Rows.Count, 1).End(xlUp).Row
    lastCol = Cells(1, Columns.Count).End(xlToLeft).Column

    ' データ範囲をまるごとコピー
    Range(Cells(1, 1), Cells(lastRow, lastCol)).Copy

    ' Sheet2のA1に貼り付け
    Sheets(&quot;Sheet2&quot;).Range(&quot;A1&quot;).PasteSpecial xlPasteValues
    Application.CutCopyMode = False
End Sub</code></pre>



<p class="wp-block-paragraph">最終行だけでなく最終列も動的に取得すれば、列が増えても自動で対応できます。</p>



<h2 class="wp-block-heading"><span id="toc21">実務シナリオ別の選択ガイド</span></h2>



<p class="wp-block-paragraph">ここまでの内容を、よくある実務シナリオで整理しましょう。</p>



<h3 class="wp-block-heading"><span id="toc22">一覧表を上から順に処理する</span></h3>



<p class="wp-block-paragraph">請求書データや社員名簿を1行ずつ処理するパターンです。</p>



<pre class="wp-block-code"><code>Sub 一覧表を順に処理する()
    Dim lastRow As Long
    lastRow = Cells(Rows.Count, 1).End(xlUp).Row

    Dim i As Long
    For i = 2 To lastRow  ' 2行目から（1行目はヘッダー）
        ' B列が空欄ならスキップ
        If Cells(i, 2).Value &lt;&gt; &quot;&quot; Then
            ' D列に計算結果を入力
            Cells(i, 4).Value = Cells(i, 2).Value * Cells(i, 3).Value
        End If
    Next i
End Sub</code></pre>



<p class="wp-block-paragraph">行を変数 <code>i</code> で動かすので<strong>Cells一択</strong>です。「<a href="https://mashukabu.com/excel-vba-howto-use-for/">For文</a>」と「<a href="https://mashukabu.com/vba-howto-use-for-each-next/">For Each</a>」のどちらでもCellsが活躍します。条件分岐の詳しい書き方は「<a href="https://mashukabu.com/excel-vba-conditional-branch-explanation/">VBA If文の使い方</a>」も参考にしてみてください。</p>



<h3 class="wp-block-heading"><span id="toc23">For Eachで条件付き書式を動的に適用する</span></h3>



<p class="wp-block-paragraph">For Eachを使えば、セルの値に応じて書式を変えるといった処理もシンプルに書けます。</p>



<pre class="wp-block-code"><code>Sub 売上達成状況に色をつける()
    Dim cell As Range
    For Each cell In Range(&quot;D2:D50&quot;)
        Select Case True
            Case cell.Value &gt;= 1000000
                cell.Interior.Color = RGB(198, 239, 206)  ' 緑（達成）
            Case cell.Value &gt;= 500000
                cell.Interior.Color = RGB(255, 235, 156)  ' 黄（もう少し）
            Case Else
                cell.Interior.Color = RGB(255, 199, 206)  ' 赤（未達）
        End Select
    Next cell
End Sub</code></pre>



<p class="wp-block-paragraph">行番号を使わず「セルそのもの」を操作するだけなので、For Eachが最適です。Select Caseの詳しい書き方は「<a href="https://mashukabu.com/excel-vba-howto-use-select-case/">Select Caseの使い方</a>」もチェックしてみてください。</p>



<h3 class="wp-block-heading"><span id="toc24">可変範囲をまるごとコピーする</span></h3>



<p class="wp-block-paragraph">データの最終行・最終列が変わる範囲を一括操作するパターンです。</p>



<pre class="wp-block-code"><code>Sub 可変範囲を書式設定する()
    Dim lastRow As Long
    Dim lastCol As Long
    lastRow = Cells(Rows.Count, 1).End(xlUp).Row
    lastCol = Cells(1, Columns.Count).End(xlToLeft).Column

    ' データ範囲全体に背景色をつける
    Range(Cells(2, 1), Cells(lastRow, lastCol)).Interior.Color = RGB(230, 240, 255)
End Sub</code></pre>



<p class="wp-block-paragraph"><strong>Range(Cells, Cells)の組み合わせ</strong>が最適です。開始・終了を変数で制御しつつ、範囲全体をまとめて操作できます。</p>



<h3 class="wp-block-heading"><span id="toc25">集計行をループの外に固定する</span></h3>



<p class="wp-block-paragraph">ヘッダーや集計行など、位置が固定のセルを操作するパターンです。</p>



<pre class="wp-block-code"><code>Sub 集計処理()
    Dim lastRow As Long
    lastRow = Cells(Rows.Count, 1).End(xlUp).Row

    ' ループ部分はCells
    Dim total As Long
    Dim i As Long
    For i = 2 To lastRow
        total = total + Cells(i, 3).Value
    Next i

    ' 固定セルへの書き込みはRange
    Range(&quot;A1&quot;).Value = &quot;集計結果&quot;
    Range(&quot;B1&quot;).Value = total
End Sub</code></pre>



<p class="wp-block-paragraph"><strong>ループ内はCells、固定セルはRange</strong>と使い分けるのがスマートです。コードの意図が明確になり、後から読んでも何をしているか一目でわかります。</p>



<h3 class="wp-block-heading"><span id="toc26">シナリオ別まとめ表</span></h3>



<figure class="wp-block-table"><table><thead><tr><th>シナリオ</th><th>おすすめ</th><th>理由</th></tr></thead><tbody><tr><td>一覧を上から順に処理</td><td>Cells + For文</td><td>行番号を変数で動かす</td></tr><tr><td>範囲内のセルを一括処理</td><td>Range + For Each</td><td>行番号管理が不要でシンプル</td></tr><tr><td>可変範囲を一括操作</td><td>Range(Cells, Cells)</td><td>動的な開始・終了を範囲指定</td></tr><tr><td>固定セルへの読み書き</td><td>Range</td><td>アドレス直書きで可読性が高い</td></tr><tr><td>名前付き範囲の参照</td><td>Range</td><td>Cellsでは名前定義を参照できない</td></tr><tr><td>二重ループ（行×列）</td><td>Cells</td><td>行列ともに数値で制御できる</td></tr><tr><td>隣のセルにアクセス</td><td>Offset</td><td>For Each内で行番号なしに隣接セルを操作</td></tr><tr><td>動的な範囲サイズ変更</td><td>Resize</td><td>基準セルから任意サイズの範囲を作成</td></tr></tbody></table></figure>



<h2 class="wp-block-heading"><span id="toc27">1004エラーの原因と対処法</span></h2>



<p class="wp-block-paragraph">RangeとCellsの組み合わせで最もハマりやすいのが、実行時エラー1004（「アプリケーション定義またはオブジェクト定義のエラー」）です。</p>



<h3 class="wp-block-heading"><span id="toc28">Worksheetオブジェクトの明示</span></h3>



<p class="wp-block-paragraph">このエラーは、別シートのCellsをRange引数に渡すときに起きます。</p>



<pre class="wp-block-code"><code>' エラーになるコード
Sheets(&quot;Sheet2&quot;).Range(Cells(1, 1), Cells(10, 3)).Select</code></pre>



<p class="wp-block-paragraph">一見すると正しく見えますが、問題があります。<code>Range</code> は Sheet2 を指していますが、<code>Cells</code> はアクティブシートを指しています。シートの参照先がバラバラなのでエラーになるのです。</p>



<p class="wp-block-paragraph">正しくはこう書きます。</p>



<pre class="wp-block-code"><code>' 正しいコード：Withでシートを統一する
With Sheets(&quot;Sheet2&quot;)
    .Range(.Cells(1, 1), .Cells(10, 3)).Select
End With</code></pre>



<p class="wp-block-paragraph">ポイントは <code>.Range</code> と <code>.Cells</code> の先頭にドット（<code>.</code>）をつけることです。ドットをつけると、Withで指定したSheet2のプロパティとして認識されます。</p>



<p class="wp-block-paragraph">ドットを1つでも忘れるとエラーになるので注意してください。</p>



<p class="wp-block-paragraph">もうひとつ、シートを変数に入れて書く方法もあります。</p>



<pre class="wp-block-code"><code>' 変数でシートを指定する方法
Dim ws As Worksheet
Set ws = Sheets(&quot;Sheet2&quot;)
ws.Range(ws.Cells(1, 1), ws.Cells(10, 3)).Select</code></pre>



<p class="wp-block-paragraph">どちらの書き方でもOKです。大事なのは「Range・Cells・すべてのシート参照を揃える」ことです。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p><strong>NOTE</strong></p><p>1004エラーは実行時に発生するため、コードを書いた時点では気づけません。別シートを操作するコードを書いたら、必ずテスト実行して確認しましょう。</p></blockquote>



<h3 class="wp-block-heading"><span id="toc29">OffsetやResizeでも同じ原則</span></h3>



<p class="wp-block-paragraph">Offset・Resizeを使う場合もシート参照を揃える必要があります。</p>



<pre class="wp-block-code"><code>' NGパターン：シート参照が混在
Sheets(&quot;Sheet2&quot;).Range(&quot;A1&quot;).Offset(1, 0).Resize(10, 3).Value = &quot;&quot;

' OKパターン：Withで統一
With Sheets(&quot;Sheet2&quot;)
    .Range(&quot;A1&quot;).Offset(1, 0).Resize(10, 3).Value = &quot;&quot;
End With</code></pre>



<p class="wp-block-paragraph">Offset・Resizeは基準セルのシートを引き継ぐので、基準となるRange/Cellsのシート指定さえ正しければ問題ありません。Withブロックを使う習慣をつけておくと安全です。</p>



<h2 class="wp-block-heading"><span id="toc30">まとめ：迷ったときの使い分け早見表</span></h2>



<p class="wp-block-paragraph">RangeとCellsの使い分けを最終確認しましょう。</p>



<figure class="wp-block-table"><table><thead><tr><th>やりたいこと</th><th>使うもの</th><th>書き方の例</th></tr></thead><tbody><tr><td>固定セルに値を入れる</td><td>Range</td><td><code>Range("A1").Value = 100</code></td></tr><tr><td>名前付き範囲を参照</td><td>Range</td><td><code>Range("売上合計").Value</code></td></tr><tr><td>ループで行を動かす</td><td>Cells</td><td><code>Cells(i, 1).Value</code></td></tr><tr><td>行列ともに変数で動かす</td><td>Cells</td><td><code>Cells(r, c).Value</code></td></tr><tr><td>範囲内のセルを一括処理</td><td>For Each + Range</td><td><code>For Each cell In Range("A1:A10")</code></td></tr><tr><td>隣のセルにアクセス</td><td>Offset</td><td><code>cell.Offset(0, 1).Value</code></td></tr><tr><td>動的なサイズの範囲を作る</td><td>Resize</td><td><code>Range("A2").Resize(lastRow, 4)</code></td></tr><tr><td>動的範囲を一括操作</td><td>Range + Cells</td><td><code>Range(Cells(1,1), Cells(lastRow,3))</code></td></tr><tr><td>別シートのセルを操作</td><td>With + ドット付き</td><td><code>.Range(.Cells(1,1), .Cells(10,3))</code></td></tr></tbody></table></figure>



<p class="wp-block-paragraph">判断に迷ったら、次の順番で考えてみてください。</p>



<ol class="wp-block-list"><li>名前付き範囲を使う？ → <strong>Range</strong></li><li>セルの位置が固定？ → <strong>Range</strong></li><li>範囲内を順に処理（行番号不要）？ → <strong>For Each + Range</strong></li><li>変数で位置を動かす？ → <strong>Cells</strong></li><li>動的な範囲指定？ → <strong>Range(Cells, Cells)</strong></li><li>基準セルから相対的にずらす？ → <strong>Offset / Resize</strong></li></ol>



<p class="wp-block-paragraph">どちらが正解ということではなく、場面で使い分けるのがベストです。VBAに慣れてくると、これらを自然に組み合わせて使えるようになりますよ。</p>



<p class="wp-block-paragraph">ぜひVBEを開いて、両方のコードを試してみてくださいね。VBA全体の学習順序に迷ったら「<a href="https://mashukabu.com/excel-vba-learning-roadmap/">VBA学習の順番ガイド</a>」も参考にしてください。</p>



<h3 class="wp-block-heading"><span id="toc31">関連記事</span></h3>



<ul class="wp-block-list"><li><a href="https://mashukabu.com/excel-vba-howto-use-range/">VBA Rangeの使い方</a></li><li><a href="https://mashukabu.com/excel-vba-howto-use-for/">For文で処理を繰り返す方法</a></li><li><a href="https://mashukabu.com/vba-howto-use-for-each-next/">For Eachでセル・シートを一括処理</a></li><li><a href="https://mashukabu.com/excel-vba-howto-get-lastrow/">最終行を取得する3つの方法</a></li><li><a href="https://mashukabu.com/excel-vba-conditional-branch-explanation/">VBA If文の使い方</a></li><li><a href="https://mashukabu.com/excel-vba-howto-use-select-case/">Select Caseの使い方</a></li><li><a href="https://mashukabu.com/how-to-use-do-loop/">Do Loopの使い方</a></li><li><a href="https://mashukabu.com/excel-vba-vbe-menu-explanation/">VBE画面の見方</a></li><li><a href="https://mashukabu.com/excel-vba-option-explicit/">Option Explicitで変数宣言を強制する方法</a></li><li><a href="https://mashukabu.com/excel-vba-variable-explanation/">変数の使い方とルール</a></li><li><a href="https://mashukabu.com/excel-vba-howto-use-worksheetfunction/">WorksheetFunctionの使い方</a></li><li><a href="https://mashukabu.com/excel-vba-learning-roadmap/">VBA学習の順番ガイド</a></li></ul>
]]></content:encoded>
					
					<wfw:commentRss>https://mashukabu.com/excel-vba-range-cells/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>VBA For Eachの使い方 &#8212; セル・シート・配列を1行でループ処理</title>
		<link>https://mashukabu.com/vba-howto-use-for-each-next/</link>
					<comments>https://mashukabu.com/vba-howto-use-for-each-next/#respond</comments>
		
		<dc:creator><![CDATA[まっしゅ]]></dc:creator>
		<pubDate>Sun, 26 Dec 2021 14:59:27 +0000</pubDate>
				<category><![CDATA[VBA・マクロ]]></category>
		<category><![CDATA[For Each]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[コレクション]]></category>
		<category><![CDATA[セル範囲]]></category>
		<category><![CDATA[マクロ]]></category>
		<category><![CDATA[ループ]]></category>
		<category><![CDATA[繰り返し処理]]></category>
		<guid isPermaLink="false">https://mashukabu.com/?p=638</guid>

					<description><![CDATA[VBAのFor Each~Nextの書き方と実務での使い方を解説します。セル範囲の一括処理・全シートへの処理適用・配列のループという3パターンをサンプルコードつきで紹介。For~Nextとの違いや使い分け判断軸もわかります。]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">「セル範囲を全部チェックしたいのに、番号の指定が面倒&#8230;&#8230;」</p>



<p class="wp-block-paragraph">そんな悩み、VBAを書いていると一度は感じますよね。<br>ループ回数を自分で管理するのは手間ですし、範囲が変わるたびにコードを直すのも大変です。</p>



<p class="wp-block-paragraph">For Each~Nextを使えば、対象のセルやシートをまるごとループできます。<br>番号の管理が不要になり、コードもすっきり書けますよ。</p>



<p class="wp-block-paragraph">この記事では、For Eachの基本構文から実務パターンまでまとめて解説します。</p>




  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-3" checked><label class="toc-title" for="toc-checkbox-3">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">VBA For Each~Nextとは？基本の書き方をおさらい</a><ol><li><a href="#toc2" tabindex="0">For~Nextとの違いはなに？</a></li></ol></li><li><a href="#toc3" tabindex="0">For Eachでセル範囲を一括処理する</a><ol><li><a href="#toc4" tabindex="0">Rangeに対してFor Eachを使う基本構文</a></li><li><a href="#toc5" tabindex="0">実務サンプル：指定範囲のセルに処理を一括適用</a></li></ol></li><li><a href="#toc6" tabindex="0">For Eachで全シートに同じ処理をする</a><ol><li><a href="#toc7" tabindex="0">WorksheetsコレクションとFor Eachの組み合わせ</a></li><li><a href="#toc8" tabindex="0">実務サンプル：全シートのA1セルをクリアする</a></li><li><a href="#toc9" tabindex="0">実務サンプル：全シートにヘッダーを一括設定する</a></li></ol></li><li><a href="#toc10" tabindex="0">For Eachで配列をループする</a><ol><li><a href="#toc11" tabindex="0">配列に対してFor Eachを使う書き方</a></li><li><a href="#toc12" tabindex="0">配列でのFor Each vs For~Nextの比較</a></li></ol></li><li><a href="#toc13" tabindex="0">VBA For Eachの使い分け判断チャート</a><ol><li><a href="#toc14" tabindex="0">3つのループ構文の使い分け</a></li></ol></li><li><a href="#toc15" tabindex="0">For Eachでよくあるエラーと対処法</a><ol><li><a href="#toc16" tabindex="0">ループ内でシートを削除したいときの対処</a></li></ol></li><li><a href="#toc17" tabindex="0">VBEの起動方法（はじめてマクロを使う方へ）</a><ol><li><a href="#toc18" tabindex="0">VBEの開き方</a></li><li><a href="#toc19" tabindex="0">標準モジュールの挿入と実行</a></li></ol></li><li><a href="#toc20" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">VBA For Each~Nextとは？基本の書き方をおさらい</span></h2>



<p class="wp-block-paragraph">For Each~Nextは、<strong>コレクション（まとまり）の中身を1つずつ取り出して処理する</strong>ループ構文です。</p>



<p class="wp-block-paragraph">「セル範囲のすべてのセル」「ブック内のすべてのシート」など、グループの要素をまとめて処理したいときに使います。</p>



<p class="wp-block-paragraph">基本の構文は次のとおりです。</p>



<pre class="wp-block-code"><code>For Each 変数 In コレクション
    '--- 繰り返したい処理 ---
Next 変数</code></pre>



<p class="wp-block-paragraph"><code>変数</code>にはコレクションの要素が1つずつ代入されます。<br>すべての要素を処理し終わると、自動的にループを抜けます。</p>



<p class="wp-block-paragraph">ポイントは、ループの回数を指定しなくてよいことです。<br>コレクションの要素数が変わっても、コードの修正は不要ですよ。</p>



<h3 class="wp-block-heading"><span id="toc2">For~Nextとの違いはなに？</span></h3>



<p class="wp-block-paragraph"><a href="https://mashukabu.com/excel-vba-howto-use-for/">For~Next</a>は、<strong>回数を指定して繰り返す</strong>ループ構文です。<br>一方、For Eachは<strong>対象のまとまりを順に処理する</strong>構文です。</p>



<p class="wp-block-paragraph">ざっくりまとめると、こんなイメージになります。</p>



<ul class="wp-block-list"><li><strong>For~Next</strong>: 「1番目から10番目まで処理して」</li><li><strong>For Each</strong>: 「この中の全部を処理して」</li></ul>



<p class="wp-block-paragraph">回数が決まっている処理にはFor~Nextが向いています。<br>「全部に同じ処理をしたい」ならFor Eachが便利です。</p>



<p class="wp-block-paragraph">使い分けの詳しい判断軸は、記事の後半で解説しますね。</p>



<h2 class="wp-block-heading"><span id="toc3">For Eachでセル範囲を一括処理する</span></h2>



<p class="wp-block-paragraph">For Eachでもっともよく使うのが、セル範囲のループです。<br>指定した範囲のすべてのセルに、同じ処理を適用できます。</p>



<h3 class="wp-block-heading"><span id="toc4">Rangeに対してFor Eachを使う基本構文</span></h3>



<p class="wp-block-paragraph">セル範囲をFor Eachで処理するときは、<a href="https://mashukabu.com/excel-vba-howto-use-range/">Range</a>オブジェクトをコレクションに指定します。</p>



<pre class="wp-block-code"><code>Sub セル範囲をループ()
    Dim cell As Range '--- 処理対象のセル ---

    For Each cell In Range(&quot;A1:A10&quot;)
        cell.Value = cell.Value * 2 '--- 値を2倍にする ---
    Next cell
End Sub</code></pre>



<p class="wp-block-paragraph"><code>cell</code>には、A1、A2、A3&#8230;&#8230;と順にセルが代入されます。<br>各セルの値を2倍にする、シンプルな処理ですね。</p>



<p class="wp-block-paragraph">なお、セルの処理順序は公式には保証されていません。<br>通常は左上から右下へ処理されますが、<strong>順序に依存するコードは避ける</strong>のがベターです。</p>



<h3 class="wp-block-heading"><span id="toc5">実務サンプル：指定範囲のセルに処理を一括適用</span></h3>



<p class="wp-block-paragraph">実務では、動的な範囲を対象にすることが多いです。<br><a href="https://mashukabu.com/excel-vba-howto-get-lastrow/">最終行の取得</a>と組み合わせたサンプルを見てみましょう。</p>



<pre class="wp-block-code"><code>Sub 空欄セルを強調表示()
    Dim lastRow As Long '--- 最終行 ---
    Dim cell As Range   '--- 処理対象のセル ---

    lastRow = Cells(Rows.Count, &quot;A&quot;).End(xlUp).Row

    For Each cell In Range(&quot;A1:C&quot; &amp; lastRow)
        If cell.Value = &quot;&quot; Then
            cell.Interior.Color = RGB(255, 200, 200) '--- 薄い赤で塗る ---
        End If
    Next cell
End Sub</code></pre>



<p class="wp-block-paragraph">A列の最終行までの範囲で、空欄セルを薄い赤色にハイライトします。<br>データの入力漏れチェックに、そのまま使えますよ。</p>



<p class="wp-block-paragraph">ループの途中で処理を抜けたいときは、<code>Exit For</code>を使います。<br>最初の空欄が見つかった時点で止めるなら、こう書きます。</p>



<pre class="wp-block-code"><code>If cell.Value = &quot;&quot; Then
    MsgBox cell.Address &amp; &quot; が空欄です&quot;
    Exit For '--- 最初の空欄で停止 ---
End If</code></pre>



<p class="wp-block-paragraph">なお、ループ内で<a href="https://mashukabu.com/excel-vba-conditional-branch-explanation/">If文</a>を組み合わせるのは定番パターンです。<br>条件に合うセルだけを対象にしたいときに活用してくださいね。</p>



<h2 class="wp-block-heading"><span id="toc6">For Eachで全シートに同じ処理をする</span></h2>



<p class="wp-block-paragraph">ブック内の全シートにまとめて処理をかけたいとき、For Eachが活躍します。<br>シート数が増減しても、コードの変更は不要です。</p>



<h3 class="wp-block-heading"><span id="toc7">WorksheetsコレクションとFor Eachの組み合わせ</span></h3>



<p class="wp-block-paragraph"><code>Worksheets</code>コレクションをFor Eachに渡すと、全シートを順に処理できます。</p>



<pre class="wp-block-code"><code>Sub 全シート名を表示()
    Dim ws As Worksheet '--- 処理対象のシート ---

    For Each ws In Worksheets
        Debug.Print ws.Name '--- イミディエイトウィンドウに出力 ---
    Next ws
End Sub</code></pre>



<p class="wp-block-paragraph"><a href="https://mashukabu.com/excel-vba-variable-explanation/">変数</a><code>ws</code>は<code>Worksheet</code>型で宣言するのがポイントです。</p>



<p class="wp-block-paragraph">ひとつ注意があります。<br><code>Worksheets</code>は<strong>非表示のシートも含みます</strong>。<br><code>xlSheetVeryHidden</code>で隠したシートも対象になるので、気をつけてください。<br>表示シートだけ処理したいときは、条件を追加しましょう。</p>



<h3 class="wp-block-heading"><span id="toc8">実務サンプル：全シートのA1セルをクリアする</span></h3>



<pre class="wp-block-code"><code>Sub 全シートA1クリア()
    Dim ws As Worksheet '--- 処理対象のシート ---

    For Each ws In Worksheets
        If ws.Visible = xlSheetVisible Then '--- 表示シートのみ ---
            ws.Range(&quot;A1&quot;).ClearContents
        End If
    Next ws
End Sub</code></pre>



<p class="wp-block-paragraph"><code>ws.Visible = xlSheetVisible</code>の条件で、表示中のシートだけを対象にしています。</p>



<p class="wp-block-paragraph">特定のシートを除外したい場合もあるでしょう。<br>そのときは<code>If ws.Name <> "集計" Then</code>のように、シート名で判定してください。</p>



<h3 class="wp-block-heading"><span id="toc9">実務サンプル：全シートにヘッダーを一括設定する</span></h3>



<p class="wp-block-paragraph">月別シートを持つブックで、全シートに同じヘッダーを設定するコードです。</p>



<pre class="wp-block-code"><code>Sub 全シートにヘッダー設定()
    Dim ws As Worksheet '--- 処理対象のシート ---

    For Each ws In Worksheets
        If ws.Visible = xlSheetVisible Then '--- 表示シートのみ ---
            ws.Range(&quot;A1&quot;).Value = &quot;日付&quot;
            ws.Range(&quot;B1&quot;).Value = &quot;担当者&quot;
            ws.Range(&quot;C1&quot;).Value = &quot;金額&quot;
            ws.Range(&quot;A1:C1&quot;).Font.Bold = True '--- ヘッダーを太字 ---
        End If
    Next ws

    MsgBox &quot;全シートにヘッダーを設定しました&quot;
End Sub</code></pre>



<p class="wp-block-paragraph">毎月シートを追加するようなブックで、ヘッダーの設定漏れを防げます。<br>手動で1枚ずつ入力するよりも、ずっと確実ですよ。</p>



<h2 class="wp-block-heading"><span id="toc10">For Eachで配列をループする</span></h2>



<p class="wp-block-paragraph">For Eachは配列のループにも使えます。<br>ただし、注意点があるので確認しておきましょう。</p>



<h3 class="wp-block-heading"><span id="toc11">配列に対してFor Eachを使う書き方</span></h3>



<pre class="wp-block-code"><code>Sub 配列をループ()
    Dim arr As Variant  '--- 配列 ---
    Dim item As Variant '--- 配列の要素（Variant型が必須） ---

    arr = Array(&quot;東京&quot;, &quot;大阪&quot;, &quot;名古屋&quot;)

    For Each item In arr
        Debug.Print item
    Next item
End Sub</code></pre>



<p class="wp-block-paragraph">ここで大事なポイントがあります。<br><strong>配列をFor Eachで回すとき、変数は必ずVariant型にしてください。</strong><br><code>Dim item As String</code>のように宣言すると、型の不一致エラーになります。</p>



<p class="wp-block-paragraph">コレクション（Worksheetsなど）では専用の型が使えます。<br>しかし、配列はVariant限定です。<br>つまずきやすいので覚えておきましょう。</p>



<h3 class="wp-block-heading"><span id="toc12">配列でのFor Each vs For~Nextの比較</span></h3>



<p class="wp-block-paragraph">配列のループでは、<a href="https://mashukabu.com/excel-vba-howto-use-for/">For~Next</a>のほうが向いているケースもあります。</p>



<figure class="wp-block-table"><table><thead><tr><th>比較項目</th><th>For Each</th><th>For~Next</th></tr></thead><tbody><tr><td>インデックス（番号）の取得</td><td>できない</td><td>できる</td></tr><tr><td>要素の書き換え</td><td>できない（読み取り専用）</td><td>できる</td></tr><tr><td>コードのシンプルさ</td><td>シンプル</td><td>やや冗長</td></tr><tr><td>変数の型</td><td>Variant限定</td><td>自由に指定可</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">配列の要素を<strong>読み取るだけ</strong>ならFor Eachが手軽です。<br>要素の<strong>書き換え</strong>や<strong>番号が必要</strong>な処理には、For~Nextを選びましょう。</p>



<h2 class="wp-block-heading"><span id="toc13">VBA For Eachの使い分け判断チャート</span></h2>



<p class="wp-block-paragraph">ここまで3つのパターンを見てきました。<br>「結局どのループを使えばいいの？」と迷ったときの判断軸をまとめます。</p>



<h3 class="wp-block-heading"><span id="toc14">3つのループ構文の使い分け</span></h3>



<figure class="wp-block-table"><table><thead><tr><th>やりたいこと</th><th>おすすめの構文</th></tr></thead><tbody><tr><td>セル範囲に同じ処理をしたい</td><td><strong>For Each</strong></td></tr><tr><td>全シートに同じ処理をしたい</td><td><strong>For Each</strong></td></tr><tr><td>配列を読み取りたい</td><td><strong>For Each</strong></td></tr><tr><td>ループ回数が決まっている</td><td><strong><a href="https://mashukabu.com/excel-vba-howto-use-for/">For~Next</a></strong></td></tr><tr><td>インデックス番号が必要</td><td><strong><a href="https://mashukabu.com/excel-vba-howto-use-for/">For~Next</a></strong></td></tr><tr><td>配列の要素を書き換えたい</td><td><strong><a href="https://mashukabu.com/excel-vba-howto-use-for/">For~Next</a></strong></td></tr><tr><td>条件で繰り返し回数が変わる</td><td><strong><a href="https://mashukabu.com/how-to-use-do-loop/">Do Loop</a></strong></td></tr></tbody></table></figure>



<p class="wp-block-paragraph">迷ったら「対象のまとまりがあるか」で判断するのがコツです。<br>Range・WorksheetsなどのコレクションがあるならFor Eachです。<br>回数やインデックスが重要ならFor~Nextを選びましょう。</p>



<h2 class="wp-block-heading"><span id="toc15">For Eachでよくあるエラーと対処法</span></h2>



<p class="wp-block-paragraph">For Eachを使っていて発生しやすいエラーをまとめました。</p>



<figure class="wp-block-table"><table><thead><tr><th>エラー</th><th>原因</th><th>対処法</th></tr></thead><tbody><tr><td>型が一致しません（エラー13）</td><td>配列のループ変数をVariant以外で宣言した</td><td><code>Dim item As Variant</code>に変更する</td></tr><tr><td>オブジェクト変数またはWithブロック変数が設定されていません（エラー91）</td><td>オブジェクト変数への<code>Set</code>忘れ</td><td><code>Set cell = Range("A1")</code>のように<code>Set</code>を付ける</td></tr><tr><td>コンパイルエラー: Next に対する For がありません</td><td><code>Next</code>の変数名がFor Eachと不一致</td><td><code>For Each cell</code>なら<code>Next cell</code>と揃える</td></tr><tr><td>実行時エラー: コレクションは変更できません</td><td>ループ内でコレクションの要素を追加・削除した</td><td>ループ外で削除対象を配列に格納し、後からまとめて削除する</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">特に「型が一致しません」は初心者がつまずきやすいエラーです。<br>配列のループでは、必ず<code>Variant</code>型を使ってください。</p>



<h3 class="wp-block-heading"><span id="toc16">ループ内でシートを削除したいときの対処</span></h3>



<p class="wp-block-paragraph">For Eachのループ中にコレクションを変更すると、エラーになります。<br>シートを削除したい場合は、逆順ループで対処しましょう。</p>



<pre class="wp-block-code"><code>Sub 空シートを削除()
    Dim i As Long '--- ループカウンター ---

    Application.DisplayAlerts = False '--- 確認ダイアログを非表示 ---

    For i = Worksheets.Count To 1 Step -1
        If WorksheetFunction.CountA(Worksheets(i).UsedRange) = 0 Then
            Worksheets(i).Delete
        End If
    Next i

    Application.DisplayAlerts = True '--- 確認ダイアログを復帰 ---
End Sub</code></pre>



<p class="wp-block-paragraph">逆順（<code>Step -1</code>）にするのがポイントです。<br>順方向だと削除後にインデックスがずれて、正しく処理できません。<br>このパターンは<a href="https://mashukabu.com/excel-vba-howto-use-for/">For~Next</a>の逆順ループが適しています。</p>



<h2 class="wp-block-heading"><span id="toc17">VBEの起動方法（はじめてマクロを使う方へ）</span></h2>



<p class="wp-block-paragraph">VBAのコードは、VBE（Visual Basic Editor）で入力して実行します。<br>はじめてマクロを使う方は、以下の手順で準備してくださいね。</p>



<h3 class="wp-block-heading"><span id="toc18">VBEの開き方</span></h3>



<p class="wp-block-paragraph">キーボードで <strong>Alt + F11</strong> を押すと、VBEが起動します。</p>



<p class="wp-block-paragraph">リボンから開く場合は「開発」タブを使います。<br>開発タブが表示されていない場合は、次の手順で追加してください。</p>



<ol class="wp-block-list"><li>「ファイル」→「オプション」→「リボンのユーザー設定」を開く</li><li>右側の一覧で「開発」にチェックを入れる</li><li>「OK」をクリックする</li></ol>



<h3 class="wp-block-heading"><span id="toc19">標準モジュールの挿入と実行</span></h3>



<p class="wp-block-paragraph">VBEを開いたら、コードを書く場所を用意します。</p>



<ol class="wp-block-list"><li>メニューの「挿入」→「標準モジュール」をクリック</li><li>表示されたコードウィンドウにコードを貼り付ける</li><li><strong>F5キー</strong>を押すか、メニューの「実行」→「Sub/ユーザーフォームの実行」で実行</li></ol>



<p class="wp-block-paragraph">VBAの基本から体系的に学びたい方は、<a href="https://mashukabu.com/excel-vba-learning-roadmap/">VBA学習ロードマップ</a>も参考にしてみてください。</p>



<h2 class="wp-block-heading"><span id="toc20">まとめ</span></h2>



<p class="wp-block-paragraph">この記事では、VBAのFor Each~Nextについて解説しました。</p>



<ul class="wp-block-list"><li><strong>基本構文</strong>: <code>For Each 変数 In コレクション ... Next</code></li><li><strong>セル範囲</strong>: Rangeを指定して全セルを一括処理</li><li><strong>全シート</strong>: Worksheetsで全シートをまとめて処理</li><li><strong>配列</strong>: Variant型の変数で要素を読み取り</li><li><strong>使い分け</strong>: コレクションがあればFor Each、回数指定ならFor~Next</li></ul>



<p class="wp-block-paragraph">For Eachを使いこなすと、繰り返し処理がぐっとシンプルになります。<br>まずはセル範囲のループから、ぜひ試してみてくださいね。</p>



<p class="wp-block-paragraph">なお、作成したマクロは<code>.xlsm</code>（マクロ有効ブック）形式で保存してください。<br><code>.xlsx</code>で保存するとマクロが消えてしまうので注意です。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://mashukabu.com/vba-howto-use-for-each-next/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
