<?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>無限ループ &#8211; biz-tactics</title>
	<atom:link href="https://mashukabu.com/tag/%E7%84%A1%E9%99%90%E3%83%AB%E3%83%BC%E3%83%97/feed/" rel="self" type="application/rss+xml" />
	<link>https://mashukabu.com</link>
	<description></description>
	<lastBuildDate>Sat, 01 Aug 2026 05:23:42 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0.3</generator>

<image>
	<url>https://mashukabu.com/wp-content/uploads/2022/04/cropped-site-icon-32x32.png</url>
	<title>無限ループ &#8211; biz-tactics</title>
	<link>https://mashukabu.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Excelマクロが止まらない時の強制終了4ステップ</title>
		<link>https://mashukabu.com/how-to-stop-macro/</link>
					<comments>https://mashukabu.com/how-to-stop-macro/#respond</comments>
		
		<dc:creator><![CDATA[まっしゅ]]></dc:creator>
		<pubDate>Sat, 18 Dec 2021 09:00:00 +0000</pubDate>
				<category><![CDATA[VBA・マクロ]]></category>
		<category><![CDATA[DoEvents]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[VBE]]></category>
		<category><![CDATA[トラブルシューティング]]></category>
		<category><![CDATA[マクロ]]></category>
		<category><![CDATA[強制終了]]></category>
		<category><![CDATA[無限ループ]]></category>
		<guid isPermaLink="false">https://mashukabu.com/?p=554</guid>

					<description><![CDATA[Excelマクロが止まらない時の強制終了方法をWindows・Mac別に解説。Escキーからタスクマネージャーまで4段階の対処法と、VBEのBreak Mode・リセットボタンの違い、無限ループを防ぐVBAコードも紹介します。]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">「マクロを実行したら、画面が固まって動かない……」</p>



<p class="wp-block-paragraph">VBAを使っていると、こんな場面に出くわすことがありますよね。無限ループにハマったときは、本当に焦ります。データがどんどん上書きされていくのを見ているしかない……。</p>



<p class="wp-block-paragraph">でも安心してください。Excelマクロの強制終了には、確実な手順があります。この記事では、<strong>4ステップで段階的に止める方法</strong>を解説します。キーボード操作から最終手段まで、順番に試せば必ず止められますよ。</p>



<p class="wp-block-paragraph">さらに後半では、暴走を防ぐ予防策もVBAコード付きで紹介します。</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">Excelマクロが強制終了できない状況とは？</a><ol><li><a href="#toc2" tabindex="0">こんな時に強制終了が必要になる</a></li><li><a href="#toc3" tabindex="0">この記事の4ステップの流れ</a></li></ol></li><li><a href="#toc4" tabindex="0">Excelマクロを強制終了する方法【4ステップ】</a></li><li><a href="#toc5" tabindex="0">「応答なし」でも待つべきか止めるべきか：今すぐ判断できる4つの確認ポイント</a><ol><li><a href="#toc6" tabindex="0">ステップ1: Escキー・Ctrl+Breakで停止する（Win/Mac）</a></li><li><a href="#toc7" tabindex="0">ステップ1.5: VBEのリセットボタンで停止する</a></li><li><a href="#toc8" tabindex="0">ステップ2: 応答なしダイアログから終了する</a></li><li><a href="#toc9" tabindex="0">ステップ3: タスクマネージャー／アクティビティモニタで強制終了する</a></li></ol></li><li><a href="#toc10" tabindex="0">マクロが止まらなくなる原因を知っておこう</a><ol><li><a href="#toc11" tabindex="0">無限ループ（Do Loop / For文の終了条件ミス）</a></li><li><a href="#toc12" tabindex="0">イベントプロシージャ（Worksheet_Change）が引き起こす無限ループ</a></li><li><a href="#toc13" tabindex="0">大量データ処理による長時間実行</a></li><li><a href="#toc14" tabindex="0">ScreenUpdating=Falseによる見た目フリーズ</a></li></ol></li><li><a href="#toc15" tabindex="0">再発防止策：VBAマクロの暴走を防ぐ3つのコード</a><ol><li><a href="#toc16" tabindex="0">実行前にファイルを自動保存する</a></li><li><a href="#toc17" tabindex="0">ループにカウンター上限を設定する（If文活用）</a></li><li><a href="#toc18" tabindex="0">コードで意図的に止める：End / Stop / Exit Sub の違い</a></li><li><a href="#toc19" tabindex="0">DoEventsでEscキーを受け付けるようにする</a></li></ol></li><li><a href="#toc20" tabindex="0">よくあるトラブルと対処法Q&A</a><ol><li><a href="#toc21" tabindex="0">EscもCtrl+Breakも効かない場合</a></li><li><a href="#toc22" tabindex="0">タスクマネージャーすら開かない場合</a></li><li><a href="#toc23" tabindex="0">強制終了後にファイルが破損していた場合</a></li></ol></li><li><a href="#toc24" tabindex="0">Escキーの効き方を変える：Application.EnableCancelKey</a><ol><li><a href="#toc25" tabindex="0">3種類の設定値と動作の違い</a></li><li><a href="#toc26" tabindex="0">xlErrorHandlerで「中断」を「エラー処理」に変える</a></li></ol></li><li><a href="#toc27" tabindex="0">一定時間で自動停止させる：Timer関数でタイムアウト</a><ol><li><a href="#toc28" tabindex="0">60秒で自動停止するコード</a></li></ol></li><li><a href="#toc29" tabindex="0">Excel for the web（Office Scripts）の場合</a></li><li><a href="#toc30" tabindex="0">Break Modeを活用してループ箇所を特定する</a><ol><li><a href="#toc31" tabindex="0">F8キーで1行ずつ実行する（ステップ実行）</a></li><li><a href="#toc32" tabindex="0">ローカルウィンドウでループ変数を監視する</a></li><li><a href="#toc33" tabindex="0">ウォッチウィンドウで条件式を監視する</a></li></ol></li><li><a href="#toc34" tabindex="0">Breakキーがないキーボードでの代替ショートカット</a></li><li><a href="#toc35" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">Excelマクロが強制終了できない状況とは？</span></h2>



<h3 class="wp-block-heading"><span id="toc2">こんな時に強制終了が必要になる</span></h3>



<p class="wp-block-paragraph">通常、マクロは処理が完了すると自動的に終了します。しかし、次のケースでは手動で止める必要があります。</p>



<ul class="wp-block-list"><li>無限ループに入り、処理が永遠に終わらない</li><li>想定外のセル範囲を処理していて、データが壊れそう</li><li>処理に時間がかかりすぎて、他の作業ができない</li></ul>



<p class="wp-block-paragraph">こうした場面で慌てないために、止め方を知っておくことが大切です。</p>



<h3 class="wp-block-heading"><span id="toc3">この記事の4ステップの流れ</span></h3>



<p class="wp-block-paragraph">本記事では、<strong>簡単な方法から順番に</strong>4つのステップで解説します。</p>



<figure class="wp-block-table"><table><thead><tr><th>ステップ</th><th>方法</th><th>難易度</th></tr></thead><tbody><tr><td>ステップ1</td><td>Escキー・Ctrl+Breakで停止</td><td>まずはこれを試す</td></tr><tr><td>ステップ1.5</td><td>VBEのリセットボタンで停止</td><td>Break後の完全終了に</td></tr><tr><td>ステップ2</td><td>応答なしダイアログから終了</td><td>Excelごと閉じる</td></tr><tr><td>ステップ3</td><td>タスクマネージャーで強制終了</td><td>最終手段</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">まずステップ1を試してください。ダメなら次の段階へ進む流れです。</p>



<h2 class="wp-block-heading"><span id="toc4">Excelマクロを強制終了する方法【4ステップ】</span></h2>



<h2 class="wp-block-heading"><span id="toc5">「応答なし」でも待つべきか止めるべきか：今すぐ判断できる4つの確認ポイント</span></h2>



<p class="wp-block-paragraph">ステップ2の説明で少し触れましたが、「応答なし」の状態でも実際には処理が進んでいることがあります。無理に強制終了すると、処理途中のデータが壊れる可能性があります。まず判断してから行動しましょう。</p>



<p class="wp-block-paragraph"><strong>確認ポイント1: ステータスバーを見る</strong></p>



<p class="wp-block-paragraph">Excelウィンドウの左下にあるステータスバーを確認してください。「準備完了」以外の文字（「処理中&#8230;」など、VBAコードで <code>Application.StatusBar</code> に表示している文字列）が出ていれば、マクロはまだ動いています。</p>



<p class="wp-block-paragraph"><strong>確認ポイント2: タスクマネージャーのCPU使用率を見る</strong></p>



<p class="wp-block-paragraph">タスクマネージャー（Ctrl+Shift+Esc）を開いて、Microsoft ExcelのCPU使用率を確認します。使用率が高い状態が続いていれば、Excelが処理を続けているサインです。逆に0%のまま何も変化しないなら、本当に止まっている可能性があります。</p>



<p class="wp-block-paragraph"><strong>確認ポイント3: <code>ScreenUpdating = False</code> を疑う</strong></p>



<p class="wp-block-paragraph">VBAコードの中に <code>Application.ScreenUpdating = False</code> が書いてある場合、画面の更新が止まっているだけで処理は正常に進んでいることがあります。見た目が完全に固まって見えても、しばらく待てば終わるケースです。</p>



<p class="wp-block-paragraph"><strong>確認ポイント4: しばらく待ってみる</strong></p>



<p class="wp-block-paragraph">大量データの処理では、数分〜十数分かかることもあります。ステータスバーとCPU使用率に動きがあるなら、5分程度は待ってみましょう。待てる状況であれば、強制終了よりも完了を待つほうがデータの安全性は高いです。</p>



<p class="wp-block-paragraph">これらを確認してもまったく変化がなく、何をしても応答しない場合に、はじめてステップ2・ステップ3へ進むことを検討してください。マクロ以外の原因でExcel自体が重い場合は<a href="https://mashukabu.com/excel-freeze-solution/">Excelが重い・応答なしを解決する方法</a>を確認してください。</p>



<h3 class="wp-block-heading"><span id="toc6">ステップ1: Escキー・Ctrl+Breakで停止する（Win/Mac）</span></h3>



<p class="wp-block-paragraph">最もシンプルな方法です。マクロの処理が重くなければ、キーボードだけで止められます。</p>



<h4 class="wp-block-heading">Windowsの場合</h4>



<figure class="wp-block-table"><table><thead><tr><th>ショートカット</th><th>説明</th></tr></thead><tbody><tr><td>Esc</td><td>最も基本的な中断キー。まずはこれを試す</td></tr><tr><td>Ctrl + Break（Pause）</td><td>Escで止まらないときに使う</td></tr></tbody></table></figure>



<h4 class="wp-block-heading">Macの場合</h4>



<figure class="wp-block-table"><table><thead><tr><th>ショートカット</th><th>説明</th></tr></thead><tbody><tr><td>Command + .（ピリオド）</td><td>Mac版Excelの標準的な中断コマンド</td></tr><tr><td>Esc</td><td>Command+.で反応しないときに試す</td></tr></tbody></table></figure>



<p class="wp-block-paragraph"><strong>ポイント</strong>: 1回押しただけでは反応しないことがあります。処理が重いとキー入力の受付が遅れます。<strong>連打するか長押し</strong>して粘り強く試してみてください。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p><strong>NOTE</strong></p><p>ノートPCではBreakキーが見当たらないことがあります。その場合は「Fn + B」や「Fn + Ctrl + B」など、機種によって異なります。お使いのPCの取扱説明書を確認してみてください。</p></blockquote>



<p class="wp-block-paragraph">停止に成功すると、VBEが開いてコードが黄色くハイライトされます。これがBreak Mode（中断モード）です。この状態では変数の値が保持されています。F5キーで処理を続行することもできます。</p>



<p class="wp-block-paragraph">ただし、<strong>完全に終了したい場合</strong>は次のステップ1.5へ進んでください。</p>



<h3 class="wp-block-heading"><span id="toc7">ステップ1.5: VBEのリセットボタンで停止する</span></h3>



<p class="wp-block-paragraph">ステップ1でBreak Modeに入ったあと、<strong>完全に終了する</strong>方法です。ここが意外と見落とされがちなポイントです。</p>



<p class="wp-block-paragraph">VBE（Visual Basic Editor）の画面上部にある<strong>リセットボタン（■）</strong>をクリックしてください。メニューからは「実行」→「リセット」でも同じ操作ができます。</p>



<p class="wp-block-paragraph"><a href="https://mashukabu.com/excel-vba-vbe-menu-explanation/">VBEの画面と各メニューの見方</a>を確認しておくと、ボタンの位置がすぐにわかりますよ。</p>



<h4 class="wp-block-heading">Break ModeとDesign Timeの違い</h4>



<p class="wp-block-paragraph">Ctrl+BreakとリセットボタンではVBEの状態が異なります。この違いを知っておくと、デバッグ時に役立ちます。</p>



<figure class="wp-block-table"><table><thead><tr><th>項目</th><th>Break Mode（中断モード）</th><th>Design Time（デザインタイム）</th></tr></thead><tbody><tr><td>操作</td><td>Esc / Ctrl+Break</td><td>リセットボタン / 実行→リセット</td></tr><tr><td>変数の値</td><td>保持される</td><td>すべてリセットされる</td></tr><tr><td>処理の続行</td><td>F5で続行可能</td><td>不可（最初からやり直し）</td></tr><tr><td>ステップ実行</td><td>F8で1行ずつ実行可能</td><td>不可</td></tr><tr><td>用途</td><td>デバッグ・途中確認</td><td>完全に停止したいとき</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">「とにかく止めたい」ならリセットボタンを押しましょう。「原因を調べたい」ならBreak Modeのまま、<a href="https://mashukabu.com/excel-vbe-immediate-window-explanation/">イミディエイトウィンドウの使い方</a>で変数の値を確認するのがおすすめです。暴走の原因を特定するには<a href="https://mashukabu.com/excel-vba-debug-breakpoint-step-execution/">VBAデバッグ方法｜ブレークポイントから変数確認まで</a>が役立ちます。</p>



<h3 class="wp-block-heading"><span id="toc8">ステップ2: 応答なしダイアログから終了する</span></h3>



<p class="wp-block-paragraph">キーボードで止まらない場合、Excelが「応答なし」になることがあります。</p>



<p class="wp-block-paragraph">このとき、固まったExcelの画面をクリックしてみてください。Windowsが警告メッセージを表示することがあります。<strong>「プログラムを終了します」を選択</strong>すれば、Excelごと終了できます。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p><strong>WARNING</strong></p><p>アプリケーション自体を終了させるため、<strong>保存していないデータは消えます</strong>。マクロ実行前にファイルを保存しておく習慣をつけましょう。</p></blockquote>



<p class="wp-block-paragraph">ただし、「応答なし」に見えても実際には処理中のケースがあります。VBAの <code>Application.ScreenUpdating = False</code> で画面更新を止めているだけかもしれません。</p>



<p class="wp-block-paragraph"><strong>見分け方</strong>: ステータスバー（Excel画面の左下）を確認してください。処理状況が表示されていれば、マクロはまだ動いています。しばらく待ってみるのも手です。</p>



<h3 class="wp-block-heading"><span id="toc9">ステップ3: タスクマネージャー／アクティビティモニタで強制終了する</span></h3>



<p class="wp-block-paragraph">ここまでの方法で止まらなければ、OSからアプリごと終了させます。これが最終手段です。</p>



<h4 class="wp-block-heading">Windowsの場合（タスクマネージャー）</h4>



<ol class="wp-block-list"><li><strong>Ctrl + Shift + Esc</strong> でタスクマネージャーを起動する</li><li>「プロセス」タブで <strong>Microsoft Excel</strong> を探す</li><li>選択して <strong>[タスクの終了]</strong> をクリックする</li></ol>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p><strong>NOTE</strong></p><p>Ctrl + Shift + Escで開かない場合は、<strong>Ctrl + Alt + Delete</strong>からタスクマネージャーを選択してください。</p></blockquote>



<h4 class="wp-block-heading">Macの場合（アプリケーションの強制終了）</h4>



<ol class="wp-block-list"><li><strong>Command + Option + Esc</strong> で強制終了画面を開く</li><li><strong>Microsoft Excel</strong> を選択する</li><li><strong>[強制終了]</strong> をクリックする</li></ol>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p><strong>WARNING</strong></p><p>ステップ2・3ではExcel自体を終了させます。<strong>保存前のデータはすべて失われます</strong>。重要なファイルを扱うときは、マクロ実行前の保存を徹底してください。</p></blockquote>



<h2 class="wp-block-heading"><span id="toc10">マクロが止まらなくなる原因を知っておこう</span></h2>



<p class="wp-block-paragraph">そもそも、なぜマクロが止まらなくなるのでしょうか？原因を知っておけば、同じトラブルを防げます。</p>



<h3 class="wp-block-heading"><span id="toc11">無限ループ（Do Loop / For文の終了条件ミス）</span></h3>



<p class="wp-block-paragraph">最も多い原因がこれです。<a href="https://mashukabu.com/how-to-use-do-loop/">Do&#8230;Loop文の使い方</a>や<a href="https://mashukabu.com/excel-vba-howto-use-for/">For〜Next文の使い方</a>で、終了条件が正しく設定されていないと無限に繰り返されます。</p>



<pre class="wp-block-code"><code>'--- 無限ループの例（カウンターが更新されない） ---
Sub InfiniteLoopExample()
    Dim i As Long 'カウンター変数
    i = 1
    Do While i &lt;= 10
        Cells(i, 1).Value = i
        '--- i = i + 1 を書き忘れると無限ループ ---
    Loop
End Sub</code></pre>



<p class="wp-block-paragraph">上のコードでは <code>i = i + 1</code> を書き忘れています。<code>i</code> がずっと1のままなので、<code>Do While i <= 10</code> が永遠にTrueです。セルA1に1を書き込み続けてしまいます。</p>



<h3 class="wp-block-heading"><span id="toc12">イベントプロシージャ（Worksheet_Change）が引き起こす無限ループ</span></h3>



<p class="wp-block-paragraph">通常のDo/Forループ以外にも、よくある原因があります。<strong>イベントプロシージャ</strong>によって引き起こされる無限ループです。</p>



<p class="wp-block-paragraph"><code>Worksheet_Change</code> は、シート上のセルが変更されたときに自動で呼び出されるプロシージャです。問題は、このプロシージャの中でセルを書き換えると、<strong>自分自身が再び呼び出される</strong>ことにあります。これが繰り返されると、ループの終了条件がないのと同じ状態になります。</p>



<pre class="wp-block-code"><code>'--- Worksheet_Changeが自分を呼び続ける例 ---
Private Sub Worksheet_Change(ByVal Target As Range)
    '変更されたセルの隣に「済」と書く
    Target.Offset(0, 1).Value = &quot;済&quot;
    '↑このセルへの書き込みが再びWorksheet_Changeを呼び出す
End Sub</code></pre>



<p class="wp-block-paragraph"><code>Target.Offset(0, 1).Value = "済"</code> の書き込みが新たな変更イベントとして検出され、また <code>Worksheet_Change</code> が動く――この連鎖が止まりません。</p>



<p class="wp-block-paragraph"><strong>対処法はイベント発火を一時停止する</strong>ことです。<code>Application.EnableEvents = False</code> を最初に書いて、処理後に必ず <code>True</code> へ戻します。<code>On Error GoTo</code> と組み合わせてエラーが出ても必ず戻すようにしましょう。</p>



<pre class="wp-block-code"><code>'--- EnableEventsで再帰呼び出しを防ぐ正しい書き方 ---
Private Sub Worksheet_Change(ByVal Target As Range)
    On Error GoTo Cleanup

    Application.EnableEvents = False  '← これで再帰呼び出しを止める

    Target.Offset(0, 1).Value = &quot;済&quot;

Cleanup:
    Application.EnableEvents = True   '← 必ず元に戻す
End Sub</code></pre>



<p class="wp-block-paragraph">ひとつ注意点があります。強制終了した場合、<code>Application.EnableEvents</code> が <code>False</code> のまま残ることがあります。この状態ではExcelを閉じるまでの間、すべてのイベント（保存・変更・セレクション移動など）が一切発火しません。強制終了後にExcelの動作がおかしいと感じたら、VBEのイミディエイトウィンドウで次のコードを実行して確認してください。</p>



<pre class="wp-block-code"><code>'--- イミディエイトウィンドウで実行してリセットする ---
Application.EnableEvents = True</code></pre>



<p class="wp-block-paragraph"><a href="https://mashukabu.com/excel-vbe-immediate-window-explanation/">イミディエイトウィンドウの使い方</a>では、このような緊急リセット操作の手順も解説しています。</p>



<h3 class="wp-block-heading"><span id="toc13">大量データ処理による長時間実行</span></h3>



<p class="wp-block-paragraph">無限ループではなく、データ量が多すぎるケースです。たとえば10万行のデータを1セルずつ処理すると、数分〜数十分かかることがあります。</p>



<p class="wp-block-paragraph">この場合、強制終了せず完了を待つのが正解かもしれません。ステータスバーで進捗を確認しましょう。</p>



<h3 class="wp-block-heading"><span id="toc14">ScreenUpdating=Falseによる見た目フリーズ</span></h3>



<p class="wp-block-paragraph">VBAで高速化のために <code>Application.ScreenUpdating = False</code> を使うと、処理中は画面が更新されません。見た目は完全にフリーズしたように見えます。でも裏では正常に処理が進んでいることがあります。</p>



<p class="wp-block-paragraph"><code>ScreenUpdating</code> はマクロが正常終了しても自動でTrueに戻りません。強制終了した場合はなおさらです。コードの最後に必ず <code>Application.ScreenUpdating = True</code> を書いておきましょう。</p>



<h2 class="wp-block-heading"><span id="toc15">再発防止策：VBAマクロの暴走を防ぐ3つのコード</span></h2>



<p class="wp-block-paragraph">強制終了の方法を知っておくのも大事です。でも、そもそも暴走しないようにするのがベストですよね。ここでは実務で使える予防策を3つ紹介します。</p>



<h3 class="wp-block-heading"><span id="toc16">実行前にファイルを自動保存する</span></h3>



<p class="wp-block-paragraph">最もシンプルで最も大切な対策です。マクロ実行前に<strong>ファイルを上書き保存</strong>しておきましょう。</p>



<p class="wp-block-paragraph">強制終了すると保存前のデータは消えます。でも直前に保存しておけば、その時点に戻れます。VBAコードに自動保存を組み込むのがおすすめです。</p>



<pre class="wp-block-code"><code>'--- マクロ実行前に自動保存するコード ---
Sub SaveBeforeRun()
    ThisWorkbook.Save '現在のブックを上書き保存
    MsgBox &quot;保存が完了しました。処理を開始します。&quot;
    '--- ここから実際の処理を記述 ---
End Sub</code></pre>



<h3 class="wp-block-heading"><span id="toc17">ループにカウンター上限を設定する（If文活用）</span></h3>



<p class="wp-block-paragraph"><a href="https://mashukabu.com/how-to-use-do-loop/">Do...Loop文の使い方</a>を使うときは、カウンター上限を設定すると安心です。終了条件にバグがあっても、上限で止まります。</p>



<pre class="wp-block-code"><code>'--- カウンター上限付きのDo Loopコード ---
Sub SafeLoopExample()
    Dim i As Long       'カウンター変数
    Dim maxCount As Long '上限回数
    maxCount = 100000
    i = 1

    Do While i &lt;= 10
        Cells(i, 1).Value = i
        i = i + 1

        '--- 安全装置: 上限を超えたら強制終了 ---
        If i &gt; maxCount Then
            MsgBox &quot;処理回数が上限(&quot; &amp; maxCount &amp; _
                   &quot;回)を超えました。処理を中断します。&quot;
            Exit Do
        End If
    Loop
End Sub</code></pre>



<p class="wp-block-paragraph"><a href="https://mashukabu.com/excel-vba-conditional-branch-explanation/">If文（条件分岐）の使い方</a>で上限チェックを入れるのがポイントです。無限ループが起きても自動的に止まります。<code>maxCount</code> の値は処理内容に応じて調整してください。</p>



<h3 class="wp-block-heading"><span id="toc18">コードで意図的に止める：End / Stop / Exit Sub の違い</span></h3>



<p class="wp-block-paragraph">「暴走するかもしれない」と思ったとき、コードの中にあらかじめ「止まる命令」を書いておく方法があります。VBAには似た役割を持つ命令が3つあり、挙動が大きく異なります。</p>



<figure class="wp-block-table"><table><thead><tr><th>ステートメント</th><th>止まる範囲</th><th>変数の状態</th><th>主な用途</th></tr></thead><tbody><tr><td><code>Exit Sub</code> / <code>Exit Function</code></td><td>現在のプロシージャのみ終了</td><td>呼び出し元に戻るので保持</td><td>条件を満たしたら処理を抜ける</td></tr><tr><td><code>Stop</code></td><td>Break Modeに入る（一時停止）</td><td>すべて保持</td><td>デバッグ中の確認ポイント</td></tr><tr><td><code>End</code></td><td>VBA全体を即時強制終了</td><td>すべてリセット</td><td>（通常は使わない）</td></tr></tbody></table></figure>



<p class="wp-block-paragraph"><strong><code>Exit Sub</code> が最も安全</strong>です。現在動いているプロシージャだけを終了し、呼び出し元のマクロへ制御を返します。上限チェックやエラー判定と組み合わせて使うのが基本パターンです。</p>



<p class="wp-block-paragraph"><strong><code>Stop</code> はデバッグ専用</strong>です。コードにブレークポイントを埋め込む感覚で使います。Break Modeに入るので変数の値を確認できます。ただし本番コードに <code>Stop</code> を残してはいけません。ユーザーが実行したときにVBEが突然開いて混乱します。</p>



<p class="wp-block-paragraph"><strong><code>End</code> はできるだけ使わないでください。</strong> <code>End</code> を実行すると呼び出し元のマクロも含めてVBA全体が即座に止まります。開いているユーザーフォームも閉じられ、<code>Unload</code> イベントすら呼ばれません。<code>On Error GoTo</code> で設定した後始末コードも実行されないため、ファイルが中途半端な状態になる可能性があります。</p>



<p class="wp-block-paragraph">実務で「強制的に止めたい」場面では、<code>Exit Sub</code> か先ほど紹介したカウンター上限のパターンで対応するのが適切です。</p>



<h3 class="wp-block-heading"><span id="toc19">DoEventsでEscキーを受け付けるようにする</span></h3>



<p class="wp-block-paragraph"><code>DoEvents</code> は、VBAの処理中にOSへ制御を戻す関数です。これをループに入れておくと、処理中でもEscキーを受け付けてくれます。</p>



<pre class="wp-block-code"><code>'--- DoEventsを使ったEsc受付コード ---
Sub DoEventsExample()
    Dim i As Long 'カウンター変数

    For i = 1 To 100000
        Cells(i, 1).Value = i

        '--- 100回ごとにOSへ制御を戻す ---
        If i Mod 100 = 0 Then
            DoEvents
        End If
    Next i
End Sub</code></pre>



<p class="wp-block-paragraph"><code>DoEvents</code> を毎回呼ぶと処理速度が落ちます。上の例のように <code>If i Mod 100 = 0</code> で<strong>100回に1回だけ実行</strong>するのがコツです。</p>



<p class="wp-block-paragraph">これを入れておけば、「Escが効かない」というトラブルを大幅に減らせますよ。</p>



<h2 class="wp-block-heading"><span id="toc20">よくあるトラブルと対処法Q&A</span></h2>



<p class="wp-block-paragraph">[faq q="EscキーもCtrl+Breakも効かない場合はどうすればいいですか？" a="まずEscキーを連打してみてください。それでも効かない場合はCtrl+Break（Windowsのみ）を試します。それでもダメならタスクマネージャー（Ctrl+Shift+Esc）でExcelを強制終了してください。"]<br>[faq q="タスクマネージャーすら開けない場合はどうすればいいですか？" a="しばらく（1〜2分）待ってからCtrl+Alt+Deleteを押してください。それでも操作できない場合は、PCの電源ボタン長押しで強制終了しますが、未保存のデータは失われます。"]<br>[faq q="マクロを強制終了したらExcelファイルが破損しました。復元できますか？" a="Excelの自動回復（AutoRecover）機能で復元できる場合があります。Excelを再起動すると「ドキュメントの回復」パネルが表示されるので、最新バージョンを選択してください。設定はファイル→オプション→保存で確認できます。"]</p>



<h3 class="wp-block-heading"><span id="toc21">EscもCtrl+Breakも効かない場合</span></h3>



<p class="wp-block-paragraph">処理が重すぎてキー入力を受け付けていない可能性があります。以下を順番に試してみてください。</p>



<ol class="wp-block-list"><li><strong>Escキーを連打</strong>する（1回では反応しないことが多い）</li><li>Windowsの場合は <strong>Ctrl + Break</strong> を試す</li><li>それでもダメなら<strong>タスクマネージャー</strong>で強制終了する</li></ol>



<p class="wp-block-paragraph">次回からはVBAコードに <code>DoEvents</code> を入れましょう。Escキーが効きやすくなります。</p>



<h3 class="wp-block-heading"><span id="toc22">タスクマネージャーすら開かない場合</span></h3>



<p class="wp-block-paragraph">Excelの処理がPCのリソースを使い切っている可能性があります。</p>



<ol class="wp-block-list"><li>しばらく待ってみる（1〜2分程度）</li><li><strong>Ctrl + Alt + Delete</strong> 画面を開く（優先度が高い）</li><li>最終手段として<strong>PCの電源ボタンを長押し</strong>する</li></ol>



<p class="wp-block-paragraph">電源ボタン長押しはすべてのデータが失われます。本当の最終手段として考えてください。</p>



<h3 class="wp-block-heading"><span id="toc23">強制終了後にファイルが破損していた場合</span></h3>



<p class="wp-block-paragraph">Excelには自動回復（AutoRecover）機能があります。強制終了後にExcelを再度開くと、「ドキュメントの回復」パネルが表示されることがあります。最新のバージョンを選択して復元しましょう。</p>



<p class="wp-block-paragraph">自動回復の設定は<strong>ファイル → オプション → 保存</strong>で確認できます。デフォルトでは10分間隔です。VBA作業が多い方は<strong>5分間隔</strong>に短縮しておくのがおすすめですよ。</p>



<p class="wp-block-paragraph">Break Modeで停止できた場合は、<a href="https://mashukabu.com/excel-vbe-immediate-window-explanation/">イミディエイトウィンドウの使い方</a>を使って変数の状態を確認しましょう。原因の特定に役立ちます。</p>



<h2 class="wp-block-heading"><span id="toc24">Escキーの効き方を変える：Application.EnableCancelKey</span></h2>



<p class="wp-block-paragraph">ここまで「Escキーで止める」方法を紹介してきました。でも、なかにはEscを押しても反応しないマクロがあります。その原因が、<code>Application.EnableCancelKey</code> というプロパティにあるかもしれません。</p>



<p class="wp-block-paragraph">このプロパティは、<strong>マクロ実行中にEscキー（Ctrl+Break）を受け付けるかどうか</strong>を制御します。コードで明示的に設定していなければ既定の動作になりますが、設定されていると挙動が変わります。</p>



<h3 class="wp-block-heading"><span id="toc25">3種類の設定値と動作の違い</span></h3>



<p class="wp-block-paragraph"><code>EnableCancelKey</code> には次の3つの値を指定できます。</p>



<figure class="wp-block-table"><table><thead><tr><th>設定値</th><th>Escキーを押したときの動作</th></tr></thead><tbody><tr><td><code>xlInterrupt</code>（既定）</td><td>マクロを中断してBreak Modeに入る</td></tr><tr><td><code>xlErrorHandler</code></td><td>エラーコード18として捕捉される（<code>On Error GoTo</code>で処理可能）</td></tr><tr><td><code>xlDisabled</code></td><td>Escキーを完全に無効化する（中断できなくなる）</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">既定値は <code>xlInterrupt</code> です。何も設定していなければ、Escキーで正しく止まる状態になっています。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p><strong>NOTE</strong></p><p><code>EnableCancelKey</code> の設定は、そのマクロが終了すると<strong>自動的に <code>xlInterrupt</code> に戻ります</strong>。次にマクロを実行するとき、前回の設定が残る心配はありません。</p></blockquote>



<h3 class="wp-block-heading"><span id="toc26">xlErrorHandlerで「中断」を「エラー処理」に変える</span></h3>



<p class="wp-block-paragraph"><code>xlErrorHandler</code> を指定すると、ユーザーがEscを押したとき、マクロを止めるのではなく<strong>エラーとして捕まえて任意の処理を実行</strong>できます。たとえば「中断する前に必ずファイルを保存する」といった仕組みが作れます。</p>



<pre class="wp-block-code"><code>'--- Escキー押下をエラーとして処理する ---
Sub CancelWithSave()
    Dim i As Long 'カウンター変数

    Application.EnableCancelKey = xlErrorHandler
    On Error GoTo Canceled

    For i = 1 To 1000000
        Cells(i Mod 100 + 1, 1).Value = i
    Next i

    Exit Sub

Canceled:
    '--- エラーコード18ならEscが押された ---
    If Err.Number = 18 Then
        ThisWorkbook.Save '中断前に保存
        MsgBox &quot;処理を中断しました。データは保存済みです。&quot;
    End If
End Sub</code></pre>



<p class="wp-block-paragraph">Escが押されると <code>Err.Number</code> が18になります。それを <code>If</code> で判定し、保存などの後始末を行ってから終了する流れです。エラー処理の書き方は<a href="https://mashukabu.com/vba-error-handling-complete-guide/">VBAのエラーハンドリング完全ガイド</a>で詳しく解説しています。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p><strong>WARNING</strong></p><p><code>xlDisabled</code> はEscキーを完全に無効化するため、Microsoftも公式に注意を促しています。<strong>無限ループにハマると止める手段がなくなり、タスクマネージャーでExcelごと終了するしかなくなります</strong>。よほどの理由がない限り使わないでください。</p></blockquote>



<p class="wp-block-paragraph">「なぜかEscが効かない」と感じたら、まずコードのなかに <code>Application.EnableCancelKey = xlDisabled</code> が紛れていないか確認してみましょう。</p>



<h2 class="wp-block-heading"><span id="toc27">一定時間で自動停止させる：Timer関数でタイムアウト</span></h2>



<p class="wp-block-paragraph">「気づいたらマクロが何分も動きっぱなしだった」という経験はありませんか。そんなときに便利なのが、<strong>指定した時間が過ぎたら自動で処理を止める</strong>仕組みです。VBAの <code>Timer</code> 関数を使えば簡単に実装できます。</p>



<p class="wp-block-paragraph"><code>Timer</code> 関数は、<strong>深夜0時からの経過秒数</strong>をSingle型で返します。処理の開始時刻を記録しておき、現在の <code>Timer</code> 値との差を見れば、何秒経過したかがわかります。</p>



<h3 class="wp-block-heading"><span id="toc28">60秒で自動停止するコード</span></h3>



<pre class="wp-block-code"><code>'--- 60秒経過したら自動でループを抜ける ---
Sub TimeoutExample()
    Dim startTime As Single '開始時刻
    Dim i As Long           'カウンター変数

    startTime = Timer '開始時刻を記録
    i = 1

    Do While i &lt;= 1000000
        Cells(i Mod 100 + 1, 1).Value = i
        i = i + 1

        '--- 60秒を超えたら中断 ---
        If Timer - startTime &gt; 60 Then
            MsgBox &quot;タイムアウトしました。処理を中断します。&quot;
            Exit Do
        End If

        DoEvents '画面更新とキー入力を受け付ける
    Loop
End Sub</code></pre>



<p class="wp-block-paragraph"><code>Timer - startTime</code> で経過秒数を計算しています。これが60を超えたら <code>Exit Do</code> でループを抜けるシンプルな仕組みです。タイムアウトの秒数は処理内容に合わせて調整してください。</p>



<p class="wp-block-paragraph"><code>DoEvents</code> を組み合わせているのもポイントです。タイムアウトを待つあいだも、Escキーなどの入力を受け付けます。<code>DoEvents</code> の役割は<a href="https://mashukabu.com/how-to-use-do-loop/">Do...Loop文の使い方</a>もあわせて読むと理解が深まります。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p><strong>TIP</strong></p><p><code>Timer</code> には1つだけ落とし穴があります。<strong>深夜0時をまたぐとTimer値が0にリセットされる</strong>ため、<code>Timer - startTime</code> が負の値になってしまいます。数時間におよぶ長時間処理を想定する場合は、日付と時刻を扱える <code>Now()</code> 関数を使って経過時間を計算しましょう。日付をまたいでも正しく動作します。</p></blockquote>



<p class="wp-block-paragraph">カウンター上限とタイムアウトを併用すれば、「回数」と「時間」の両面から暴走を防げます。安全装置は多いほど安心です。</p>



<h2 class="wp-block-heading"><span id="toc29">Excel for the web（Office Scripts）の場合</span></h2>



<p class="wp-block-paragraph">ここまではデスクトップ版ExcelのVBAを前提に解説してきました。最後に、ブラウザで使う<strong>Excel for the web</strong>のケースにも触れておきます。</p>



<p class="wp-block-paragraph">Excel for the webでは、VBAではなく<strong>Office Scripts</strong>という別の仕組みでマクロを動かします。TypeScriptをベースにした言語で、VBAとは文法も実行環境も異なります。そのため、Escキーや <code>DoEvents</code> といった対処法はそのままでは使えません。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p><strong>NOTE</strong></p><p>Office ScriptsをPower Automate（自動化フロー）経由で実行する場合、<strong>120秒のタイムアウト制限</strong>があります。これを超える処理は途中で打ち切られる仕様です。重い処理を組むときは、この上限を意識して設計しましょう。</p></blockquote>



<p class="wp-block-paragraph">もしOffice Scriptsの実行中にブラウザの画面が固まってしまったら、<strong>ページの再読み込み（リロード）が実質的な対処法</strong>になります。ブラウザのタブを更新すれば、走っていたスクリプトは中断されます。デスクトップ版のタスクマネージャーとは発想が異なるので、頭に入れておきましょう。</p>



<h2 class="wp-block-heading"><span id="toc30">Break Modeを活用してループ箇所を特定する</span></h2>



<p class="wp-block-paragraph">マクロが止まらない状況を脱した後、「どこで止まっていたのか」を把握しておくと次回の予防に役立ちます。VBEのBreak Modeとデバッグツールを使った原因特定の方法を紹介します。</p>



<h3 class="wp-block-heading"><span id="toc31">F8キーで1行ずつ実行する（ステップ実行）</span></h3>



<p class="wp-block-paragraph">VBEでマクロを開き、<code>F8</code> を押すと1行ずつ実行できます。現在実行している行が黄色くハイライトされるので、どこでループが続いているかを目で確認できます。</p>



<p class="wp-block-paragraph"><strong>手順</strong></p>



<ol class="wp-block-list"><li><code>Alt + F11</code> でVBEを開く</li><li>実行したいマクロが書かれているモジュールを開く</li><li><code>F8</code> キーを押すと先頭行からステップ実行が始まる</li><li><code>F8</code> を押すたびに1行進む</li><li>ループが終わらない場合は、ループ変数の値を確認する</li></ol>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p><strong>TIP</strong></p><p>ループの中で <code>F8</code> を何度も押すのが大変な場合は、ループの外の行にカーソルを置いて <code>Ctrl + F8</code>（カーソル行まで実行）を使うと効率的です。</p></blockquote>



<h3 class="wp-block-heading"><span id="toc32">ローカルウィンドウでループ変数を監視する</span></h3>



<p class="wp-block-paragraph">ステップ実行中に変数の値を確認するには、ローカルウィンドウが便利です。</p>



<ol class="wp-block-list"><li>VBEのメニュー [表示] → [ローカルウィンドウ] を開く</li><li>ステップ実行を進めると、変数の現在値がリアルタイムで表示される</li><li>カウンター変数（<code>i</code> など）が想定通りに変化しているか確認する</li></ol>



<p class="wp-block-paragraph">カウンター変数が変化しないままループが続いていれば、そこが無限ループの原因です。</p>



<p class="wp-block-paragraph"><a href="https://mashukabu.com/excel-vbe-local-window-explanation/">VBEローカルウィンドウの使い方</a>では、変数の監視と値の書き換え方法を詳しく解説しています。</p>



<h3 class="wp-block-heading"><span id="toc33">ウォッチウィンドウで条件式を監視する</span></h3>



<p class="wp-block-paragraph">「条件が変化したら止める」という使い方ができるウォッチウィンドウも有効です。</p>



<ol class="wp-block-list"><li>VBEのメニュー [デバッグ] → [ウォッチ式の追加] を選ぶ</li><li>監視したい変数や式を入力する（例: <code>i >= 10000</code>）</li><li>[種類] で「式が真のときブレーク」を選ぶ</li><li>マクロを実行すると、条件を満たした瞬間に自動でBreak Modeになる</li></ol>



<p class="wp-block-paragraph">想定外の条件が成立したタイミングを自動でキャッチできるため、再現しにくいバグの特定に役立ちます。<a href="https://mashukabu.com/excel-vbe-watch-window-explanation/">VBEウォッチウィンドウの使い方</a>も参考にしてください。</p>



<h2 class="wp-block-heading"><span id="toc34">Breakキーがないキーボードでの代替ショートカット</span></h2>



<p class="wp-block-paragraph">ステップ1で紹介した <code>Ctrl+Break</code> は、ノートPCではBreakキー自体が見当たらないことがあります。「Fn + B」「Fn + Ctrl + B」と書きましたが、メーカーや機種によって組み合わせが異なります。お使いのPCの取扱説明書、またはメーカーのサポートページで「Pause」「Break」「ScrLk」のキー割り当てを確認してください。</p>



<p class="wp-block-paragraph">代替キーが見つからない場合は、Escキーの連打に戻るか、VBEのリセットボタン（ステップ1.5）を使うのが現実的です。またはコードに <code>DoEvents</code> を入れておくことで、そもそもEscキーで止まりやすい設計にしておくのが根本的な対策です。</p>



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



<p class="wp-block-paragraph">この記事では、Excelマクロを強制終了する方法を4ステップで解説しました。</p>



<figure class="wp-block-table"><table><thead><tr><th>ステップ</th><th>方法</th><th>Windows</th><th>Mac</th></tr></thead><tbody><tr><td>1</td><td>キーボードで停止</td><td>Esc / Ctrl+Break</td><td>Command+. / Esc</td></tr><tr><td>1.5</td><td>VBEリセットボタン</td><td>リセットボタン（■）</td><td>同左</td></tr><tr><td>2</td><td>ダイアログから終了</td><td>応答なし→終了</td><td>—</td></tr><tr><td>3</td><td>OSから強制終了</td><td>Ctrl+Shift+Esc</td><td>Command+Option+Esc</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">まずステップ1のキーボード操作を試しましょう。ダメなら段階的にステップ2、3へ進むのがポイントです。</p>



<p class="wp-block-paragraph">そして何より大切なのは<strong>マクロ実行前の保存</strong>です。ループにカウンター上限を設定したり、<code>DoEvents</code> を入れておくと暴走を未然に防げます。</p>



<p class="wp-block-paragraph">トラブルを根本から減らすにはVBAの基本構文の理解が近道です。<a href="https://mashukabu.com/excel-vba-learning-roadmap/">VBA学習のロードマップ</a>を参考にしてみてください。まだマクロを触り始めたばかりの方は、<a href="https://mashukabu.com/howto-macro-recording/">マクロの記録の使い方</a>から始めるのもおすすめですよ。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://mashukabu.com/how-to-stop-macro/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>VBA Do Loopの使い方｜4パターンの選び方と無限ループ対策</title>
		<link>https://mashukabu.com/how-to-use-do-loop/</link>
					<comments>https://mashukabu.com/how-to-use-do-loop/#respond</comments>
		
		<dc:creator><![CDATA[まっしゅ]]></dc:creator>
		<pubDate>Sun, 12 Dec 2021 13:57:42 +0000</pubDate>
				<category><![CDATA[VBA・マクロ]]></category>
		<category><![CDATA[Do Loop]]></category>
		<category><![CDATA[Do Until]]></category>
		<category><![CDATA[Do While]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[マクロ]]></category>
		<category><![CDATA[無限ループ]]></category>
		<category><![CDATA[繰り返し処理]]></category>
		<guid isPermaLink="false">https://mashukabu.com/?p=549</guid>

					<description><![CDATA[VBA Do Loopの使い方を、For文との使い分けから実務コードまで解説します。Do WhileとDo Untilの違い、前判定・後判定の4パターンをフローチャートで選べるように整理。無限ループの止め方とExit Doでの抜け方、「Loopがありません」などのエラー対処もまとめました。コピペ可能なコード付き。]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">「このデータ、何行あるか毎回変わるんだよな……」</p>



<p class="wp-block-paragraph">Excel VBA で繰り返し処理を書いていると、必ずこの壁にぶつかりますよね。For文は「1から10まで」のように回数を先に決める書き方。行数が日によって変わるデータだと、終了値に書く数字が決められません。</p>



<p class="wp-block-paragraph">かといって毎回シートを開いて行数を数え、マクロの数字を書き換えるのは面倒ですよね。データが増えるたびに手直しが必要なマクロは、そのうち誰も使わなくなってしまうもの。</p>



<p class="wp-block-paragraph">そこで出番になるのが <strong>VBA の Do Loop</strong> です。「A列が空になるまで」「累計が100万円を超えるまで」といった書き方ができます。<strong>終わりを回数ではなく条件で決められる</strong>のが、このステートメント最大の強み。</p>



<p class="wp-block-paragraph">この記事では、次の4つをコピペで動くコードとセットで解説していきます。</p>



<ul class="wp-block-list"><li>For文・For Each との使い分け（結論から先にお伝えします）</li><li>4パターン（While / Until × 前判定 / 後判定）の選び方</li><li>実務でそのまま使えるコード4本</li><li>無限ループの止め方・防ぎ方・抜け方</li></ul>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p><strong>対応バージョン</strong>: Do Loop は Excel 2010 以降のデスクトップ版 Excel で共通に使えます。バージョンによる挙動差もありません。ただし <strong>Excel for the web（ブラウザ版）は VBA 非対応</strong>です。ブラウザ版ではマクロそのものを実行できない点にご注意ください。</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">Do LoopとFor文の使い分け（結論先出し）</a><ol><li><a href="#toc2" tabindex="0">Do Loopは「終わる回数が決まっていない繰り返し」に使う</a></li><li><a href="#toc3" tabindex="0">For~Next / For Each / Do Loop の違いを比較表で整理</a></li></ol></li><li><a href="#toc4" tabindex="0">Do Loopの4パターンを動かして理解する</a><ol><li><a href="#toc5" tabindex="0">Do While &#8230; Loop（前判定・満たす間）</a></li><li><a href="#toc6" tabindex="0">Do ... Loop While（後判定・満たす間）</a></li><li><a href="#toc7" tabindex="0">Do Until ... Loop（前判定・満たすまで）</a></li><li><a href="#toc8" tabindex="0">Do ... Loop Until（後判定・満たすまで）</a></li><li><a href="#toc9" tabindex="0">4パターン早見表と選択フローチャート</a></li></ol></li><li><a href="#toc10" tabindex="0">実務でよく使うDo Loopのコード4選</a><ol><li><a href="#toc11" tabindex="0">空白セルが出るまで下に読む（最終行が変動するデータ）</a></li><li><a href="#toc12" tabindex="0">目標金額に達するまで加算して行を特定する</a></li><li><a href="#toc13" tabindex="0">「終了」と入力されるまで受け付ける（後判定の出番）</a></li><li><a href="#toc14" tabindex="0">条件に合うセルを上から順に検索する</a></li></ol></li><li><a href="#toc15" tabindex="0">無限ループを止める・防ぐ・抜ける</a><ol><li><a href="#toc16" tabindex="0">いま固まっている人へ：Esc → Ctrl + Break → 強制終了</a></li><li><a href="#toc17" tabindex="0">Exit Doで途中脱出する（If との組み合わせ・ネスト時の挙動）</a></li><li><a href="#toc18" tabindex="0">そもそも起こさない書き方3つ（上限カウンター / DoEvents / 更新忘れ点検）</a></li></ol></li><li><a href="#toc19" tabindex="0">よくある質問</a><ol><li><a href="#toc20" tabindex="0">While と Until はどちらを使えばいいですか？</a></li><li><a href="#toc21" tabindex="0">Do Loop の途中で次の周回に飛ばせますか？（VBAにContinueはない）</a></li><li><a href="#toc22" tabindex="0">Do Loop は For~Next より遅いですか？</a></li><li><a href="#toc23" tabindex="0">Do Loop は入れ子（ネスト）にできますか？</a></li><li><a href="#toc24" tabindex="0">「Loopがありません」「オーバーフロー」が出るのはなぜ？</a></li></ol></li><li><a href="#toc25" tabindex="0">まとめ</a><ol><li><a href="#toc26" tabindex="0">関連記事</a></li></ol></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">Do LoopとFor文の使い分け（結論先出し）</span></h2>



<h3 class="wp-block-heading"><span id="toc2">Do Loopは「終わる回数が決まっていない繰り返し」に使う</span></h3>



<p class="wp-block-paragraph">Excel VBA の繰り返しステートメントは3種類あります。まずは結論から言ってしまいますね。</p>



<p class="wp-block-paragraph"><strong>繰り返す回数が事前に分からないなら Do Loop。分かっているなら For系。</strong> 判断基準はこれだけ。</p>



<p class="wp-block-paragraph">Do Loop は回数ではなく条件でループの継続と終了を決めます。1周ごとに条件式が True か False かをチェックし、その結果で「もう一周するか」を判断する仕組み。だから終了タイミングがセルの中身やユーザー操作に左右される処理でも書けるわけです。</p>



<p class="wp-block-paragraph">たとえば次のような処理は、For文では素直に書けません。</p>



<ul class="wp-block-list"><li>A列を上から読んで、空白セルに当たったら止めたい</li><li>売上を順に足して、累計が目標額を超えた行を知りたい</li><li>InputBox で「終了」と入力されるまで受け付け続けたい</li><li>フォルダ内のファイルを、なくなるまで1つずつ処理したい</li></ul>



<p class="wp-block-paragraph">どれも「何回繰り返すか」が実行してみるまで確定しないケース。回数が先に決まっていないので、For文の終了値に書く数字がそもそも存在しないんですね。</p>



<p class="wp-block-paragraph">逆に「1行目から10行目まで」のように回数が確定しているなら、無理に Do Loop を使う必要はありません。カウンターが自動で進む For文のほうが安全ですし、コードも短く済みます。</p>



<h3 class="wp-block-heading"><span id="toc3">For~Next / For Each / Do Loop の違いを比較表で整理</span></h3>



<p class="wp-block-paragraph">3つのステートメントの違いを1枚の表にまとめました。</p>



<figure class="wp-block-table"><table><thead><tr><th>比較項目</th><th>For ~ Next</th><th>For Each ~ Next</th><th>Do Loop</th></tr></thead><tbody><tr><td>繰り返しの基準</td><td>回数（開始値〜終了値）</td><td>コレクションの全要素</td><td>条件（True / False）</td></tr><tr><td>回数は事前に分かるか</td><td>分かる</td><td>実行時に自動で決まる</td><td>分からないことが多い</td></tr><tr><td>カウンター変数</td><td>必須（自動で進む）</td><td>不要</td><td>自分で用意して自分で進める</td></tr><tr><td>典型的な用途</td><td>2〜11行目の処理、連番の生成</td><td>全シート、選択範囲の全セル</td><td>空白まで、目標値まで、入力終了まで</td></tr><tr><td>途中で抜ける命令</td><td><code>Exit For</code></td><td><code>Exit For</code></td><td><code>Exit Do</code></td></tr><tr><td>無限ループの危険</td><td>ほぼなし</td><td>ほぼなし</td><td><strong>あり</strong>（条件・カウンター次第）</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">表に出てくる「コレクション」とは、同じ種類のオブジェクトをまとめて扱う入れ物のこと。ワークシートの集まりやセル範囲がその代表例です。全シートを順番に処理したいなら、この形が一番短く書けますよ。</p>



<p class="wp-block-paragraph">使い分けの目安は次の3行に集約できます。</p>



<ul class="wp-block-list"><li>回数が決まっている → <a href="https://mashukabu.com/excel-vba-howto-use-for/">For~Next文</a></li><li>全シート・全セルなど集合をまるごと → <a href="https://mashukabu.com/vba-howto-use-for-each-next/">For Each~Next文</a></li><li>条件で終わりが決まる → <strong>Do Loop</strong></li></ul>



<p class="wp-block-paragraph">注目してほしいのが表の最終行。無限ループの危険が「あり」なのは Do Loop だけなんです。For系はカウンターが自動で進むので、必ず終わりが来ます。</p>



<p class="wp-block-paragraph">一方の Do Loop は、カウンターを進めるのも条件を変化させるのも書き手の責任。ここが後半のテーマにつながります。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p><strong>NOTE</strong></p><p>コードを書く場所は VBE（Visual Basic Editor）です。Excel の画面で <code>Alt</code> + <code>F11</code> を押すと起動します。次に「挿入」→「標準モジュール」を選び、右側の白い領域にコードを貼り付けてください。実行は <code>F5</code> キーです。</p><p>書いたマクロを残すには、ファイルを <strong>マクロ有効ブック（.xlsm）</strong> で保存する必要があります。画面の見方に自信がない方は、<a href="https://mashukabu.com/excel-vba-vbe-menu-explanation/">VBE画面の見方</a>を先に確認しておくと安心ですよ。</p></blockquote>



<h2 class="wp-block-heading"><span id="toc4">Do Loopの4パターンを動かして理解する</span></h2>



<p class="wp-block-paragraph">Do Loop には <strong>While</strong> と <strong>Until</strong> という2つのキーワードがあります。さらに条件判定をループの<strong>先頭</strong>に置くか<strong>末尾</strong>に置くかで、合計4パターンの書き方になります。</p>



<p class="wp-block-paragraph">先に用語を整理しておきましょう。判定をループの先頭に置く形を<strong>前判定</strong>と呼びます。ループに入る前に条件をチェックする形ですね。</p>



<p class="wp-block-paragraph">判定を末尾に置く形が<strong>後判定</strong>。中身を1回実行してから条件をチェックします。</p>



<p class="wp-block-paragraph">この違いが「最低何回実行されるか」を左右します。ここが4パターンの肝なので、実際に動かしながら確認していきましょう。</p>



<h3 class="wp-block-heading"><span id="toc5">Do While &#8230; Loop（前判定・満たす間）</span></h3>



<p class="wp-block-paragraph">条件を<strong>満たしている間</strong>、処理を繰り返す形です。判定するのはループに入る前。</p>



<pre class="wp-block-code"><code>Do While 条件式
    '--- 繰り返す処理 ---
Loop</code></pre>



<p class="wp-block-paragraph">1から3まで数える最小コードで動きを見てみましょう。</p>



<pre class="wp-block-code"><code>Sub DoWhileLoop_Basic()
    Dim i As Long 'カウンター
    i = 1

    Do While i &lt;= 3
        Debug.Print i &amp; &quot;回目の処理&quot;
        i = i + 1
    Loop

    Debug.Print &quot;ループ終了（i は &quot; &amp; i &amp; &quot;）&quot;
End Sub</code></pre>



<p class="wp-block-paragraph">実行結果はイミディエイトウィンドウに出力されます。VBE で <code>Ctrl</code> + <code>G</code> を押すと開く、結果確認用のウィンドウのこと。出力は次のとおりです。</p>



<pre class="wp-block-code"><code>1回目の処理
2回目の処理
3回目の処理
ループ終了（i は 4）</code></pre>



<p class="wp-block-paragraph"><code>i</code> が4になった瞬間に <code>i <= 3</code> が False となり、ループを抜けます。ポイントは <code>i = i + 1</code> の行。これを書き忘れると <code>i</code> が永遠に1のままになり、無限ループへ一直線です。</p>



<p class="wp-block-paragraph">そして前判定の最大の特徴がこれ。<strong>条件が最初から False なら、中身は1回も実行されません。</strong> 上のコードで <code>i = 10</code> から始めれば、出力は「ループ終了（i は 10）」の1行だけになります。</p>



<h3 class="wp-block-heading"><span id="toc6">Do ... Loop While（後判定・満たす間）</span></h3>



<p class="wp-block-paragraph">処理を<strong>1回実行したあと</strong>に条件を判定する形です。条件を満たしている間は繰り返します。</p>



<pre class="wp-block-code"><code>Do
    '--- 繰り返す処理 ---
Loop While 条件式</code></pre>



<p class="wp-block-paragraph">先ほどと同じ「1から3まで」を後判定で書いてみます。</p>



<pre class="wp-block-code"><code>Sub DoLoopWhile_Basic()
    Dim i As Long 'カウンター
    i = 1

    Do
        Debug.Print i &amp; &quot;回目の処理&quot;
        i = i + 1
    Loop While i &lt;= 3

    Debug.Print &quot;ループ終了（i は &quot; &amp; i &amp; &quot;）&quot;
End Sub</code></pre>



<p class="wp-block-paragraph">出力は前判定版とまったく同じ4行になります。<code>i = 1</code> からスタートする限り、両者に差は出ません。</p>



<p class="wp-block-paragraph">違いが表に出るのは、<strong>条件を最初から満たしていない</strong>ときです。<code>i = 10</code> から始めると、後判定版は「10回目の処理」を1回だけ出力します。判定より先に中身を実行してしまうからですね。</p>



<p class="wp-block-paragraph">必ず1回は実行したい処理には、この形がぴったりです。たとえば「入力ダイアログを最低1回は出す」といった場面ですね。</p>



<h3 class="wp-block-heading"><span id="toc7">Do Until ... Loop（前判定・満たすまで）</span></h3>



<p class="wp-block-paragraph">条件を<strong>満たすまで</strong>処理を繰り返す形です。判定の位置は前判定と同じで、意味だけが反転します。</p>



<pre class="wp-block-code"><code>Do Until 条件式
    '--- 繰り返す処理 ---
Loop</code></pre>



<p class="wp-block-paragraph">While との対応関係を押さえておきましょう。「<code>i <= 3</code> である<strong>間</strong>」と「<code>i > 3</code> に<strong>なるまで</strong>」は、まったく同じ振る舞いになります。</p>



<pre class="wp-block-code"><code>Sub DoUntilLoop_Basic()
    Dim i As Long 'カウンター
    i = 1

    Do Until i &gt; 3
        Debug.Print i &amp; &quot;回目の処理&quot;
        i = i + 1
    Loop

    Debug.Print &quot;ループ終了（i は &quot; &amp; i &amp; &quot;）&quot;
End Sub</code></pre>



<p class="wp-block-paragraph">出力は Do While 版と同一の4行です。条件式を否定形にひっくり返しただけ、というわけ。</p>



<p class="wp-block-paragraph">While と Until のどちらを選ぶかは、<strong>条件式が自然に読めるほう</strong>で決めて構いません。</p>



<p class="wp-block-paragraph">「空白でない間」なら <code>Do While Cells(i, 1).Value <> ""</code>。「空白になるまで」なら <code>Do Until Cells(i, 1).Value = ""</code>。読みやすいほうを選んでみてください。</p>



<h3 class="wp-block-heading"><span id="toc8">Do ... Loop Until（後判定・満たすまで）</span></h3>



<p class="wp-block-paragraph">処理を<strong>1回実行したあと</strong>に「条件を満たしたか」を判定する形です。4パターンの最後の1つ。</p>



<pre class="wp-block-code"><code>Do
    '--- 繰り返す処理 ---
Loop Until 条件式</code></pre>



<pre class="wp-block-code"><code>Sub DoLoopUntil_Basic()
    Dim i As Long 'カウンター
    i = 1

    Do
        Debug.Print i &amp; &quot;回目の処理&quot;
        i = i + 1
    Loop Until i &gt; 3

    Debug.Print &quot;ループ終了（i は &quot; &amp; i &amp; &quot;）&quot;
End Sub</code></pre>



<p class="wp-block-paragraph">こちらも <code>i = 1</code> スタートなら出力は同じ4行になります。後判定なので、条件を満たしていても中身が必ず1回は実行される点が特徴。</p>



<p class="wp-block-paragraph">実務では「『終了』と入力されるまで InputBox を出し続ける」処理がこの形の定番です。後ほど実務コードとして紹介しますね。</p>



<h3 class="wp-block-heading"><span id="toc9">4パターン早見表と選択フローチャート</span></h3>



<p class="wp-block-paragraph">まずは4パターンを1枚の表で見比べてみましょう。</p>



<figure class="wp-block-table"><table><thead><tr><th>書き方</th><th>判定の位置</th><th>繰り返しが続く条件</th><th>最低実行回数</th><th>よく使う場面</th></tr></thead><tbody><tr><td><code>Do While 条件 ... Loop</code></td><td>前判定</td><td>条件が True の間</td><td><strong>0回</strong></td><td>最終行まで読む（データ0件でも安全）</td></tr><tr><td><code>Do ... Loop While 条件</code></td><td>後判定</td><td>条件が True の間</td><td><strong>1回</strong></td><td>1回処理してから継続を判断したいとき</td></tr><tr><td><code>Do Until 条件 ... Loop</code></td><td>前判定</td><td>条件が False の間</td><td><strong>0回</strong></td><td>目標値に達するまで加算する</td></tr><tr><td><code>Do ... Loop Until 条件</code></td><td>後判定</td><td>条件が False の間</td><td><strong>1回</strong></td><td>入力を最低1回は必ず求める</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">表を眺めても迷うときは、次の3つの質問に順番に答えてみてください。1問ずつたどれば必ず1パターンに絞れます。</p>



<ul class="wp-block-list"><li><strong>質問1</strong>: 条件を満たしている「<strong>間</strong>」回したいですか。それとも条件を満たす「<strong>まで</strong>」回したいですか。<ul><li>「間」→ <strong>While</strong> を使う</li><li>「まで」→ <strong>Until</strong> を使う</li></ul></li><li><strong>質問2</strong>: 条件の判定結果に関係なく、最低1回は必ず実行したいですか。<ul><li>いいえ（0回でもよい）→ 判定を<strong>前</strong>に置く（<code>Do While 条件</code> / <code>Do Until 条件</code>）</li><li>はい（必ず1回）→ 判定を<strong>後</strong>に置く（<code>Loop While 条件</code> / <code>Loop Until 条件</code>）</li></ul></li><li><strong>質問3</strong>: 途中で強制的に抜ける可能性がありますか。<ul><li>はい → ループ内に <code>If 条件 Then Exit Do</code> を追加する（4パターン共通で使えます）</li></ul></li></ul>



<p class="wp-block-paragraph">質問1と質問2の組み合わせで、4パターンのどれか1つに確定します。質問3は上乗せのオプションなので、どのパターンにも足せますよ。</p>



<h4 class="wp-block-heading">同じ条件で4パターンを回すとこうなる</h4>



<p class="wp-block-paragraph">言葉の説明より、実行結果を見たほうが早いかもしれません。初期値は4パターンとも <code>i = 10</code> で統一します。条件式も <code>i <= 3</code>（Until 側は <code>i > 3</code>）でそろえ、続けて動かしてみますね。</p>



<pre class="wp-block-code"><code>Sub CompareFourPatterns()
    Dim i As Long 'カウンター

    '--- 1: Do While ... Loop（前判定・満たす間） ---
    i = 10
    Debug.Print &quot;【1】Do While ... Loop&quot;
    Do While i &lt;= 3
        Debug.Print &quot;  実行: i = &quot; &amp; i
        i = i + 1
    Loop

    '--- 2: Do ... Loop While（後判定・満たす間） ---
    i = 10
    Debug.Print &quot;【2】Do ... Loop While&quot;
    Do
        Debug.Print &quot;  実行: i = &quot; &amp; i
        i = i + 1
    Loop While i &lt;= 3

    '--- 3: Do Until ... Loop（前判定・満たすまで） ---
    i = 10
    Debug.Print &quot;【3】Do Until ... Loop&quot;
    Do Until i &gt; 3
        Debug.Print &quot;  実行: i = &quot; &amp; i
        i = i + 1
    Loop

    '--- 4: Do ... Loop Until（後判定・満たすまで） ---
    i = 10
    Debug.Print &quot;【4】Do ... Loop Until&quot;
    Do
        Debug.Print &quot;  実行: i = &quot; &amp; i
        i = i + 1
    Loop Until i &gt; 3
End Sub</code></pre>



<p class="wp-block-paragraph">イミディエイトウィンドウの出力はこうなります。</p>



<pre class="wp-block-code"><code>【1】Do While ... Loop
【2】Do ... Loop While
  実行: i = 10
【3】Do Until ... Loop
【4】Do ... Loop Until
  実行: i = 10</code></pre>



<p class="wp-block-paragraph">結果を表に整理してみましょう。</p>



<figure class="wp-block-table"><table><thead><tr><th>パターン</th><th>実行回数</th><th>出力された行</th></tr></thead><tbody><tr><td><code>Do While i <= 3 ... Loop</code></td><td>0回</td><td>（なし）</td></tr><tr><td><code>Do ... Loop While i <= 3</code></td><td>1回</td><td><code>実行: i = 10</code></td></tr><tr><td><code>Do Until i > 3 ... Loop</code></td><td>0回</td><td>（なし）</td></tr><tr><td><code>Do ... Loop Until i > 3</code></td><td>1回</td><td><code>実行: i = 10</code></td></tr></tbody></table></figure>



<p class="wp-block-paragraph">前判定の2つは1行も出力しません。条件を満たしていないので、中身に入る前に終了するからです。対する後判定の2つは、それぞれ1回ずつ「実行: i = 10」を出力しました。</p>



<p class="wp-block-paragraph">この非対称性が実務でどう効くかというと、<strong>データが0件のとき</strong>に差が出ます。前判定なら空のシートに対して何もせず終了。後判定だと、データが無くても先頭の1行を処理してしまいます。空セルを計算に使ってエラーになりかねません。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p><strong>TIP</strong></p><p>迷ったら <strong>Do While ... Loop（前判定・While）</strong> を選んでおけば大きく外しません。最もよく使われる形ですし、条件を先にチェックするぶん安全側に倒れます。「必ず1回は実行したい」とはっきり言える場面だけ、後判定に切り替えましょう。</p></blockquote>



<h2 class="wp-block-heading"><span id="toc10">実務でよく使うDo Loopのコード4選</span></h2>



<p class="wp-block-paragraph">ここからは、業務でそのまま使えるコードを4本紹介します。どれも <code>Cells(行, 列)</code> でセルを指定しているのがポイント。行番号を変数で動かせるので、Do Loop とは相性が抜群なんです。</p>



<p class="wp-block-paragraph">指定方法の違いが気になる方は<a href="https://mashukabu.com/excel-vba-range-cells/">RangeとCellsの使い分け</a>ものぞいてみてください。</p>



<p class="wp-block-paragraph">各コードの冒頭には「<strong>なぜ For ではなく Do Loop なのか</strong>」を1行で添えました。ここが理解できると、自分のデータに当てはめるときの判断が速くなりますよ。</p>



<h3 class="wp-block-heading"><span id="toc11">空白セルが出るまで下に読む（最終行が変動するデータ）</span></h3>



<p class="wp-block-paragraph"><strong>なぜ Do Loop か</strong>: データが何行あるかを、事前に数えなくていいから。</p>



<p class="wp-block-paragraph">A列に商品名、B列に金額が並んだシートを想定します。空白セルに当たるまで下へ読み進め、B列の合計と件数を出すコードです。</p>



<figure class="wp-block-table"><table><thead><tr><th>行</th><th>A列（商品名）</th><th>B列（金額）</th></tr></thead><tbody><tr><td>1</td><td>商品名</td><td>金額</td></tr><tr><td>2</td><td>りんご</td><td>1200</td></tr><tr><td>3</td><td>みかん</td><td>800</td></tr><tr><td>4</td><td>ぶどう</td><td>2500</td></tr><tr><td>5</td><td>（空白）</td><td>（空白）</td></tr></tbody></table></figure>



<pre class="wp-block-code"><code>Sub SumUntilBlank()
    Dim ws As Worksheet '対象シート
    Dim i As Long '行カウンター
    Dim total As Double '合計金額

    Set ws = ActiveSheet
    i = 2 '1行目はヘッダーなので2行目から開始
    total = 0

    Do While ws.Cells(i, 1).Value &lt;&gt; &quot;&quot;
        total = total + ws.Cells(i, 2).Value
        i = i + 1
    Loop

    MsgBox &quot;合計: &quot; &amp; Format(total, &quot;#,##0&quot;) &amp; &quot;円&quot; &amp; vbCrLf &amp; _
           &quot;件数: &quot; &amp; (i - 2) &amp; &quot;件&quot;
End Sub</code></pre>



<p class="wp-block-paragraph">上のサンプルデータで実行すると、A5が空白なのでループは3周で終わります。合計は 1200 + 800 + 2500 = 4500。ループを抜けた時点で <code>i</code> は5なので、件数は <code>5 - 2 = 3</code> 件です。</p>



<p class="wp-block-paragraph">表示されるメッセージはこうなります。</p>



<pre class="wp-block-code"><code>合計: 4,500円
件数: 3件</code></pre>



<p class="wp-block-paragraph">データが10行に増えても100行に増えても、コードは1文字も変えなくて大丈夫。ここが Do Loop のありがたさです。</p>



<p class="wp-block-paragraph">なお、同じことは「先に最終行を確定させて For文で回す」やり方でも実現できます。詳しくは<a href="https://mashukabu.com/excel-vba-howto-get-lastrow/">VBA最終行の取得方法</a>をご覧ください。途中に空白行が混ざるデータでは、そちらのほうが安全なケースもありますよ。</p>



<h3 class="wp-block-heading"><span id="toc12">目標金額に達するまで加算して行を特定する</span></h3>



<p class="wp-block-paragraph"><strong>なぜ Do Loop か</strong>: 何行目で目標に届くかは、実際に足してみるまで分からないから。</p>



<p class="wp-block-paragraph">日別の売上を上から加算し、累計が100万円に達した行を特定するコードです。「〜まで」なので Until が自然に読めますね。</p>



<figure class="wp-block-table"><table><thead><tr><th>行</th><th>A列（日付）</th><th>B列（売上）</th></tr></thead><tbody><tr><td>1</td><td>日付</td><td>売上</td></tr><tr><td>2</td><td>4/1</td><td>320000</td></tr><tr><td>3</td><td>4/2</td><td>280000</td></tr><tr><td>4</td><td>4/3</td><td>410000</td></tr><tr><td>5</td><td>4/4</td><td>250000</td></tr></tbody></table></figure>



<pre class="wp-block-code"><code>Sub FindTargetRow()
    Dim ws As Worksheet '対象シート
    Dim i As Long '行カウンター
    Dim cumulative As Double '累計金額
    Dim target As Double '目標金額

    Set ws = ActiveSheet
    i = 2 '1行目はヘッダーなので2行目から開始
    cumulative = 0
    target = 1000000 '目標は100万円

    Do Until cumulative &gt;= target
        If ws.Cells(i, 1).Value = &quot;&quot; Then
            MsgBox &quot;データが尽きました。累計 &quot; &amp; _
                   Format(cumulative, &quot;#,##0&quot;) &amp; &quot;円で目標未達です&quot;
            Exit Sub
        End If
        cumulative = cumulative + ws.Cells(i, 2).Value
        i = i + 1
    Loop

    MsgBox &quot;目標達成&quot; &amp; vbCrLf &amp; _
           (i - 1) &amp; &quot;行目で累計 &quot; &amp; Format(cumulative, &quot;#,##0&quot;) &amp; &quot;円&quot;
End Sub</code></pre>



<p class="wp-block-paragraph">累計の動きを追ってみましょう。</p>



<ul class="wp-block-list"><li>2行目を足して 320,000円 → まだ目標未達</li><li>3行目を足して 600,000円 → まだ目標未達</li><li>4行目を足して 1,010,000円 → ここで <code>cumulative >= target</code> が True になる</li></ul>



<p class="wp-block-paragraph">このときループを抜けた <code>i</code> は5です。実際に目標へ到達させたのは1つ前の4行目なので、<code>i - 1</code> を表示しています。</p>



<pre class="wp-block-code"><code>目標達成
4行目で累計 1,010,000円</code></pre>



<p class="wp-block-paragraph">このコードの安全弁が <code>If ws.Cells(i, 1).Value = "" Then</code> の分岐。データが尽きても目標に届かない場合、この分岐がないと空白行を延々と読み続けてしまいます。</p>



<h3 class="wp-block-heading"><span id="toc13">「終了」と入力されるまで受け付ける（後判定の出番）</span></h3>



<p class="wp-block-paragraph"><strong>なぜ Do Loop か</strong>: 何件入力されるかはユーザー次第で、事前に回数を決められないから。</p>



<p class="wp-block-paragraph">入力ダイアログは「まず1回は必ず表示したい」もの。だから後判定の <code>Loop Until</code> がぴったりハマります。</p>



<pre class="wp-block-code"><code>Sub InputItemsLoop()
    Dim userInput As String '入力された文字列
    Dim itemList As String '登録した品名の一覧
    Dim itemCount As Long '登録件数

    itemList = &quot;&quot;
    itemCount = 0

    Do
        userInput = InputBox(&quot;品名を入力してください&quot; &amp; vbCrLf &amp; _
                             &quot;（「終了」と入力すると登録を終えます）&quot;, &quot;品名登録&quot;)

        If userInput = &quot;&quot; Then Exit Do 'キャンセル・空入力なら中断
        If userInput &lt;&gt; &quot;終了&quot; Then
            itemList = itemList &amp; userInput &amp; vbCrLf
            itemCount = itemCount + 1
        End If
    Loop Until userInput = &quot;終了&quot;

    If itemCount &gt; 0 Then
        MsgBox itemCount &amp; &quot;件を登録しました&quot; &amp; vbCrLf &amp; itemList
    Else
        MsgBox &quot;登録された品名はありません&quot;
    End If
End Sub</code></pre>



<p class="wp-block-paragraph">「ノート」「ペン」「終了」の順に入力した場合を追ってみましょう。</p>



<ul class="wp-block-list"><li>1周目: 「ノート」を登録（件数1）</li><li>2周目: 「ペン」を登録（件数2）</li><li>3周目: 「終了」が入力され、追加せずにループ終了</li></ul>



<p class="wp-block-paragraph">最終的に表示されるメッセージがこちらです。</p>



<pre class="wp-block-code"><code>2件を登録しました
ノート
ペン</code></pre>



<p class="wp-block-paragraph">見落としやすいのが <code>If userInput = "" Then Exit Do</code> の1行。InputBox のキャンセルボタンは空文字を返します。この分岐がないと「キャンセルしても終われない」状態になってしまうんです。</p>



<p class="wp-block-paragraph">ユーザー入力を扱うループでは、<strong>キャンセルの脱出口を必ず用意する</strong>と覚えておきましょう。</p>



<h3 class="wp-block-heading"><span id="toc14">条件に合うセルを上から順に検索する</span></h3>



<p class="wp-block-paragraph"><strong>なぜ Do Loop か</strong>: 「見つかったかどうか」を条件式にそのまま書けて、意図が読み取りやすいから。</p>



<p class="wp-block-paragraph">A列を上から照合し、一致した行を選択するコードです。最終行は <code>End(xlUp)</code> で先に取得しておきます。</p>



<pre class="wp-block-code"><code>Sub SearchValueDownward()
    Dim ws As Worksheet '対象シート
    Dim i As Long '行カウンター
    Dim lastRow As Long '最終行
    Dim searchWord As String '検索する値
    Dim isFound As Boolean '見つかったかどうか

    Set ws = ActiveSheet
    searchWord = InputBox(&quot;検索する値を入力してください&quot;)
    If searchWord = &quot;&quot; Then Exit Sub 'キャンセル時は何もしない

    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
    i = 2
    isFound = False

    Do While i &lt;= lastRow And Not isFound
        If ws.Cells(i, 1).Value = searchWord Then
            isFound = True
        Else
            i = i + 1
        End If
    Loop

    If isFound Then
        ws.Cells(i, 1).Select
        MsgBox searchWord &amp; &quot; は &quot; &amp; i &amp; &quot;行目に見つかりました&quot;
    Else
        MsgBox searchWord &amp; &quot; は見つかりませんでした&quot;
    End If
End Sub</code></pre>



<p class="wp-block-paragraph">A2からA5に「りんご」「みかん」「ぶどう」「もも」が入っているとしましょう。「ぶどう」で検索すると、2行目と3行目は不一致で <code>i</code> が進みます。</p>



<p class="wp-block-paragraph">4行目で <code>isFound</code> が True に変わります。次の判定で <code>Not isFound</code> が False になり、ループ終了。</p>



<p class="wp-block-paragraph">条件式の <code>And Not isFound</code> が効いていて、見つかった瞬間に止まる作りです。見つからなかった場合は <code>i</code> が <code>lastRow</code> を超えて終了するので、無限ループにはなりません。</p>



<p class="wp-block-paragraph"><code>Find</code> メソッドを使えば1行で書ける処理ではあります。それでも Do Loop で書く価値があるのは、<strong>照合しながら途中に別の処理を挟める</strong>からなんですね。</p>



<h4 class="wp-block-heading">おまけ：フォルダ内のファイルを順に処理する（Dir関数）</h4>



<p class="wp-block-paragraph">最後に、セル以外の定番パターンも1つ紹介しておきますね。</p>



<p class="wp-block-paragraph"><code>Dir</code> 関数は、最初に <code>Dir("パス*.xlsx")</code> のようにパスを指定して呼び出します。2回目以降は引数なしの <code>Dir()</code> を呼ぶと、次のファイル名が返ってくる仕組み。該当ファイルが尽きると長さ0の文字列が返るので、それが終了の合図になります。</p>



<pre class="wp-block-code"><code>Sub ListFilesInFolder()
    Dim folderPath As String 'フォルダのパス
    Dim fileName As String 'ファイル名

    folderPath = &quot;C:Sample&quot;
    fileName = Dir(folderPath &amp; &quot;*.xlsx&quot;)

    Do While fileName &lt;&gt; &quot;&quot;
        Debug.Print fileName
        fileName = Dir() '引数なしで次のファイル名を取得
    Loop
End Sub</code></pre>



<p class="wp-block-paragraph">何件あるか分からないファイル群を順に処理する。まさに Do Loop の独壇場です。</p>



<h2 class="wp-block-heading"><span id="toc15">無限ループを止める・防ぐ・抜ける</span></h2>



<p class="wp-block-paragraph">Do Loop で唯一こわいのが<strong>無限ループ</strong>です。条件が永遠に True のままだと、Excel が応答しなくなってしまいます。</p>



<p class="wp-block-paragraph">このセクションは3段構えでお届けします。</p>



<ul class="wp-block-list"><li>まず「いま固まっている人」向けの止め方</li><li>次に途中脱出の <code>Exit Do</code></li><li>最後に、そもそも起こさないための書き方</li></ul>



<h3 class="wp-block-heading"><span id="toc16">いま固まっている人へ：Esc → Ctrl + Break → 強制終了</span></h3>



<p class="wp-block-paragraph">急いでいる方のために、対処を段階表にまとめました。上から順に試してみてください。</p>



<figure class="wp-block-table"><table><thead><tr><th>段階</th><th>症状</th><th>やること</th><th>補足</th></tr></thead><tbody><tr><td>1</td><td>画面はまだ動く。ステータスバーに変化がある</td><td><code>Esc</code> キーを押す</td><td>Excel 上での中断キー。まずはこれ</td></tr><tr><td>2</td><td>画面が白い。タイトルバーに「応答なし」</td><td><code>Ctrl</code> + <code>Break</code> を押す</td><td>Windows 全般で有効な中断キー</td></tr><tr><td>3</td><td>どのキーも反応しない</td><td>タスクマネージャーから Excel を終了</td><td>未保存の変更は失われます</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Mac をお使いの場合は <code>Command</code> + ピリオドが中断キーになります。</p>



<p class="wp-block-paragraph">段階1と2で中断できると、ダイアログが表示されます。ボタンは「デバッグ」「続行」「終了」の3つ。ここで <strong>「デバッグ」を選ぶのが正解</strong>です。</p>



<p class="wp-block-paragraph">「デバッグ」を押すと、いま実行中の行が黄色くハイライトされます。そこが無限ループの現場。ハイライトされた <code>Do</code> と <code>Loop</code> の間を見て、次の2点を確認してみてください。</p>



<ul class="wp-block-list"><li>カウンター変数を進める行（<code>i = i + 1</code> など）が抜けていないか</li><li>条件式が、いつか必ず False（Until なら True）になる作りか</li></ul>



<p class="wp-block-paragraph">VBE 側から止めることもできます。VBE のメニューで「実行」→「中断」を選ぶか、同じく <code>Ctrl</code> + <code>Break</code> を押す方法です。</p>



<p class="wp-block-paragraph">中断したあとは <code>F8</code> キーで1行ずつ実行し、変数の値がどう変わるかを追えます。この1行ずつ実行する操作こそ<strong>ステップ実行</strong>。詳しい手順は<a href="https://mashukabu.com/excel-vba-debug-breakpoint-step-execution/">VBAデバッグの方法</a>で解説しています。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p><strong>NOTE</strong></p><p>ノートPCによっては <code>Break</code> キーが独立して用意されていません。その場合の代替操作は機種によって異なるため、お使いの端末のサポート情報を確認してください。</p><p>強制終了の詳しい手順は<a href="https://mashukabu.com/how-to-stop-macro/">Excelマクロが止まらない時の強制終了4ステップ</a>にまとめてあります。この記事では「Do Loop のどこを直すか」に絞ってお伝えしますね。</p></blockquote>



<h3 class="wp-block-heading"><span id="toc17">Exit Doで途中脱出する（If との組み合わせ・ネスト時の挙動）</span></h3>



<p class="wp-block-paragraph"><code>Exit Do</code> は、Do Loop を途中で抜けるためのステートメントです。ループ内の好きな場所に、いくつでも置けます。</p>



<p class="wp-block-paragraph">単独で書くと必ず1周目で抜けてしまうので、実際には <code>If</code> とセットで使うのが基本形。</p>



<pre class="wp-block-code"><code>Do While 条件式
    If 異常を検知する条件 Then Exit Do  '安全弁
    '--- 通常の処理 ---
Loop</code></pre>



<p class="wp-block-paragraph">「想定外のデータが来たら抜ける」「上限回数に達したら抜ける」といった安全弁として働きます。条件分岐の書き方に不安があれば、<a href="https://mashukabu.com/excel-vba-conditional-branch-explanation/">VBA If文の使い方</a>を先に押さえておくと理解が早いですよ。</p>



<p class="wp-block-paragraph">ここで1つ、間違えやすい仕様があります。ループを入れ子にした場合の挙動です。入れ子（<strong>ネスト</strong>）とは、ループの中にさらに別のループを書く構造のこと。</p>



<p class="wp-block-paragraph"><strong><code>Exit Do</code> が抜けるのは、それが書かれている一番内側のループだけ。</strong> 外側のループは止まらず、そのまま続きます。</p>



<pre class="wp-block-code"><code>Sub ExitDoInNestedLoop()
    Dim outerNo As Long '外側のカウンター
    Dim innerNo As Long '内側のカウンター

    outerNo = 1
    Do While outerNo &lt;= 2
        innerNo = 1
        Do While innerNo &lt;= 3
            If innerNo = 2 Then Exit Do '内側だけを抜ける
            Debug.Print &quot;outer=&quot; &amp; outerNo &amp; &quot; / inner=&quot; &amp; innerNo
            innerNo = innerNo + 1
        Loop
        Debug.Print &quot;→ 外側は継続中（outer=&quot; &amp; outerNo &amp; &quot;）&quot;
        outerNo = outerNo + 1
    Loop
End Sub</code></pre>



<p class="wp-block-paragraph">出力を見ると、外側が止まっていないことがはっきり分かります。</p>



<pre class="wp-block-code"><code>outer=1 / inner=1
→ 外側は継続中（outer=1）
outer=2 / inner=1
→ 外側は継続中（outer=2）</code></pre>



<p class="wp-block-paragraph">内側のループは <code>innerNo</code> が2になった時点で毎回抜けています。それでも外側は2周しました。<code>Exit Do</code> の直後にある「→ 外側は継続中」の行も、きちんと実行されていますね。</p>



<p class="wp-block-paragraph">外側まで含めて一気に終わらせたいなら、<code>Exit Sub</code> を使います。こちらはプロシージャそのものを終了し、呼び出し元へ制御を返す命令。「ループを1つ抜けるのが <code>Exit Do</code>、処理全体を終えるのが <code>Exit Sub</code>」と整理しておきましょう。</p>



<h3 class="wp-block-heading"><span id="toc18">そもそも起こさない書き方3つ（上限カウンター / DoEvents / 更新忘れ点検）</span></h3>



<p class="wp-block-paragraph">止め方を知っていても、止めずに済むのが一番ですよね。予防策を3つ紹介します。</p>



<h4 class="wp-block-heading">1. 上限カウンターで安全弁をつける</h4>



<p class="wp-block-paragraph">ループが回った回数を数え、想定を超えたら強制的に抜ける方法です。条件式にバグがあっても、確実に終わりが来ます。</p>



<pre class="wp-block-code"><code>Sub SafeLoopWithLimit()
    Dim i As Long '行カウンター
    Dim guard As Long '安全弁カウンター
    Const MAX_LOOP As Long = 10000 '許容する最大周回数

    i = 2
    guard = 0

    Do While Cells(i, 1).Value &lt;&gt; &quot;&quot;
        guard = guard + 1
        If guard &gt; MAX_LOOP Then
            MsgBox &quot;ループが&quot; &amp; MAX_LOOP &amp; &quot;回を超えました。条件式を見直してください&quot;
            Exit Do
        End If

        '--- ここに1行ごとの処理を書く ---
        i = i + 1
    Loop
End Sub</code></pre>



<p class="wp-block-paragraph">上限値は扱うデータ量に合わせて決めてください。数千行のデータなら10,000回もあれば十分です。書き慣れないうちは、この安全弁を必ず入れる習慣にしておくと安心。</p>



<h4 class="wp-block-heading">2. DoEvents で中断を受け付けやすくする</h4>



<p class="wp-block-paragraph"><code>DoEvents</code> は、OS にイベント処理を渡す関数です。引数は不要で、ループ内に1行書くだけ。</p>



<pre class="wp-block-code"><code>Sub LoopWithDoEvents()
    Dim i As Long '行カウンター

    i = 2
    Do While Cells(i, 1).Value &lt;&gt; &quot;&quot;
        DoEvents 'OSにイベント処理を渡す
        Cells(i, 3).Value = Cells(i, 2).Value * 1.1
        i = i + 1
    Loop
End Sub</code></pre>



<p class="wp-block-paragraph">これを入れておくと、<code>Esc</code> や <code>Ctrl</code> + <code>Break</code> が効きやすくなることがあります。長時間かかるループには入れておく価値がありますね。</p>



<p class="wp-block-paragraph">ただし万能ではありません。OS 側の処理をはさむぶん、ループ全体の速度は落ちます。件数が多い処理では体感できるレベルで遅くなるため、必要な場面に絞って使いましょう。</p>



<h4 class="wp-block-heading">3. カウンター更新忘れを自己点検する</h4>



<p class="wp-block-paragraph">無限ループの原因で圧倒的に多いのが、カウンター変数の更新忘れです。書き終えたら、次の3点をセルフチェックしてみてください。</p>



<ul class="wp-block-list"><li>カウンターを進める行（<code>i = i + 1</code> など）が <code>Do</code> と <code>Loop</code> の間にあるか</li><li>その行が <code>If</code> の中に入っていないか</li><li>条件式が、いつか必ず終了側に転ぶ作りになっているか</li></ul>



<p class="wp-block-paragraph">2番目が特に落とし穴。次のコードは一見それらしく見えますが、確実に無限ループします。</p>



<pre class="wp-block-code"><code>' NG例: カウンターの更新が If の中に入っている
Sub BadLoop_CounterInsideIf()
    Dim i As Long '行カウンター
    i = 2

    Do While Cells(i, 1).Value &lt;&gt; &quot;&quot;
        If Cells(i, 2).Value &gt; 0 Then
            i = i + 1  'B列が0以下の行に当たると、ここを通らない
        End If
    Loop
End Sub</code></pre>



<p class="wp-block-paragraph">B列に0や空白の行が1つでもあると、その行で <code>i</code> が止まったまま同じセルを見続けます。正しくは、次のようにカウンターを <code>If</code> の外へ出しましょう。</p>



<pre class="wp-block-code"><code>' OK例: スキップする行でもカウンターは必ず進む
Sub GoodLoop_CounterOutsideIf()
    Dim i As Long '行カウンター
    i = 2

    Do While Cells(i, 1).Value &lt;&gt; &quot;&quot;
        If Cells(i, 2).Value &gt; 0 Then
            '--- 条件を満たす行だけの処理 ---
        End If
        i = i + 1  'どの行でも必ず進む
    Loop
End Sub</code></pre>



<p class="wp-block-paragraph"><strong>カウンターの更新は <code>If</code> の外</strong>。この一点を守るだけで、無限ループの大半は防げます。</p>



<h2 class="wp-block-heading"><span id="toc19">よくある質問</span></h2>



<p class="wp-block-paragraph">質問に入る前に、Do Loop 特有のエラーを早見表にまとめておきます。エラーメッセージから逆引きしてみてください。</p>



<figure class="wp-block-table"><table><thead><tr><th>エラー表示</th><th>出るタイミング</th><th>原因</th><th>直し方</th></tr></thead><tbody><tr><td>コンパイルエラー: 「Loop がありません」</td><td>実行前</td><td><code>Do</code> に対応する <code>Loop</code> が欠けている</td><td><code>Do</code> と <code>Loop</code> の対応をインデントで確認する</td></tr><tr><td>コンパイルエラー: 「Do がありません」</td><td>実行前</td><td><code>Loop</code> に対応する <code>Do</code> が欠けている</td><td>余分な <code>Loop</code> を削るか、<code>Do</code> を補う</td></tr><tr><td>実行時エラー '6': オーバーフロー</td><td>実行中</td><td>カウンターが <code>Integer</code> の上限32,767を超えた</td><td><code>Dim i As Long</code> に変更する</td></tr><tr><td>実行時エラー '91': オブジェクト変数または With ブロック変数が設定されていません</td><td>実行中</td><td><code>Set</code> していないオブジェクト変数を参照した</td><td>ループ前に <code>Set ws = ActiveSheet</code> などで初期化する</td></tr><tr><td>応答なし（フリーズ）</td><td>実行中</td><td>条件が永遠に True／カウンターの更新忘れ</td><td><code>Esc</code> か <code>Ctrl</code> + <code>Break</code> で中断して原因行を確認</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">ここに載っていないエラー番号に遭遇したら、<a href="https://mashukabu.com/vba-error-guide/">VBAマクロのエラー解決ガイド</a>で番号から探せます。ブックマークしておくと便利ですよ。</p>



<h3 class="wp-block-heading"><span id="toc20">While と Until はどちらを使えばいいですか？</span></h3>



<p class="wp-block-paragraph"><strong>動作は同じにできるので、条件式が自然に読めるほうを選んで大丈夫です。</strong></p>



<p class="wp-block-paragraph"><code>Do While i <= 3</code> と <code>Do Until i > 3</code> は、まったく同じ回数だけ回ります。While 側は条件を満たす「間」、Until 側は条件を満たす「まで」。同じ処理を書くなら、条件式を否定形にひっくり返すだけです。</p>



<p class="wp-block-paragraph">読みやすさで選ぶなら、こんな基準が使えます。</p>



<ul class="wp-block-list"><li>「〜でない間は続ける」と言いたい → <strong>While</strong>（例: <code>Do While Cells(i, 1).Value <> ""</code>）</li><li>「〜になったら終わり」と言いたい → <strong>Until</strong>（例: <code>Do Until Cells(i, 1).Value = ""</code>）</li></ul>



<p class="wp-block-paragraph">日本語で読み上げてしっくりくるほうが、あとから読み返したときのバグも減ります。チームで共有するマクロならなおさら。</p>



<h3 class="wp-block-heading"><span id="toc21">Do Loop の途中で次の周回に飛ばせますか？（VBAにContinueはない）</span></h3>



<p class="wp-block-paragraph"><strong>VBA には他言語の <code>Continue</code> にあたるステートメントがありません。</strong> 用意されているのは <code>Exit Do</code> や <code>Exit For</code> など、ループそのものを抜ける命令だけです。</p>



<p class="wp-block-paragraph">代わりに使うのが <code>If</code> によるスキップ。「処理したい条件」で本体を囲み、カウンターの更新はその外に置きます。</p>



<pre class="wp-block-code"><code>Sub SkipBlankRows()
    Dim i As Long '行カウンター

    i = 2
    Do While Cells(i, 1).Value &lt;&gt; &quot;&quot;
        If Cells(i, 2).Value &lt;&gt; &quot;&quot; Then
            '--- B列に値がある行だけ処理する ---
            Cells(i, 3).Value = Cells(i, 2).Value * 1.1
        End If
        i = i + 1 'スキップした行でも必ず進める
    Loop
End Sub</code></pre>



<p class="wp-block-paragraph"><code>GoTo</code> とラベルでスキップを実装する方法もあります。ただし処理の流れが追いづらくなるため、まずは上の <code>If</code> で囲む書き方をおすすめします。</p>



<h3 class="wp-block-heading"><span id="toc22">Do Loop は For~Next より遅いですか？</span></h3>



<p class="wp-block-paragraph"><strong>ループの種類による速度差を気にする必要は、ほとんどありません。</strong></p>



<p class="wp-block-paragraph">公式に「Do Loop のほうが遅い」といった規定はありません。実務で体感できるほどの差も出にくいものです。速度に効いてくるのは、ループの形式ではなく<strong>ループの中で何をしているか</strong>。</p>



<p class="wp-block-paragraph">処理を速くしたいなら、次のような点を見直すほうが効果的ですよ。</p>



<ul class="wp-block-list"><li>1周ごとにセルへ読み書きする回数を減らす（配列にまとめて処理する）</li><li>画面の再描画を止める（<code>Application.ScreenUpdating = False</code>）</li><li>不要な <code>DoEvents</code> を外す</li></ul>



<p class="wp-block-paragraph">ループ形式の選択は、速度ではなく<strong>書きやすさと安全性</strong>で決めてくださいね。</p>



<h3 class="wp-block-heading"><span id="toc23">Do Loop は入れ子（ネスト）にできますか？</span></h3>



<p class="wp-block-paragraph"><strong>できます。</strong> 行と列の両方向に走査したいときの定番パターンです。</p>



<pre class="wp-block-code"><code>Sub NestedDoLoop()
    Dim r As Long '行カウンター
    Dim c As Long '列カウンター

    r = 2
    Do While Cells(r, 1).Value &lt;&gt; &quot;&quot;
        c = 2 '外側の1周ごとに必ず初期化する
        Do While Cells(1, c).Value &lt;&gt; &quot;&quot;
            Cells(r, c).Value = Cells(r, c).Value * 1.1
            c = c + 1
        Loop
        r = r + 1
    Loop
End Sub</code></pre>



<p class="wp-block-paragraph">ネストで必ず守るべきルールは2つあります。まず、内側と外側で<strong>別々のカウンター変数</strong>を使うこと。同じ変数を使い回すと、互いの周回数が壊れてしまいます。</p>



<p class="wp-block-paragraph">もう1つが、<strong>内側のカウンターを外側の1周ごとに初期化する</strong>こと。上のコードで <code>c = 2</code> を内側ループの直前に書いているのはこのためです。初期化を忘れると、2周目以降は <code>c</code> が最終列を超えたままなので、内側が1回も回りません。</p>



<p class="wp-block-paragraph">なお、内側のループに書いた <code>Exit Do</code> が抜けるのは内側だけ。外側は継続します。この挙動は前のセクションで、実際の出力とともに確認しましたね。</p>



<h3 class="wp-block-heading"><span id="toc24">「Loopがありません」「オーバーフロー」が出るのはなぜ？</span></h3>



<p class="wp-block-paragraph"><strong>「Loop がありません」は、<code>Do</code> に対応する <code>Loop</code> が見つからないときのコンパイルエラーです。</strong> コンパイルエラーとは、実行する前の構文チェックで見つかる文法上の誤りのこと。</p>



<p class="wp-block-paragraph">ネストが深いと発生しやすいエラーです。<code>Do</code> と <code>Loop</code> を同じインデント位置に揃えて書く習慣をつけましょう。逆に <code>Loop</code> が多すぎる場合は「Do がありません」と表示されます。</p>



<p class="wp-block-paragraph"><strong>オーバーフロー（実行時エラー '6'）は、変数に入りきらない値を入れようとしたときのエラーです。</strong> <code>Integer</code> 型が扱えるのは -32,768 〜 32,767 の範囲だけ。</p>



<p class="wp-block-paragraph">Excel の行数は最大1,048,576行あります。行カウンターに <code>Integer</code> を使うと、途中で必ず破綻してしまうんですね。</p>



<p class="wp-block-paragraph">対処はシンプルで、<code>Long</code> 型に変更するだけ。<code>Long</code> なら -2,147,483,648 〜 2,147,483,647（約21億）まで扱えます。<strong>ループのカウンターは常に <code>Long</code></strong> と決めてしまうのが安全です。</p>



<p class="wp-block-paragraph">もう1つ、見落としやすいパターンがあります。計算の途中結果がオーバーフローするケースです。</p>



<pre class="wp-block-code"><code>Dim total As Long

total = 2000 * 365       'オーバーフローになる
total = CLng(2000) * 365 'OK（先に Long へ変換する）</code></pre>



<p class="wp-block-paragraph">原因は右辺にあります。代入先が <code>Long</code> でも、整数どうしの計算は一時的に <code>Integer</code> として扱われるんです。<code>CLng</code> で明示的に変換すれば回避できますよ。</p>



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



<p class="wp-block-paragraph">Do Loop は「<strong>回数ではなく条件で終わりを決める</strong>」ためのステートメントです。最後に要点を振り返っておきましょう。</p>



<ul class="wp-block-list"><li><strong>使い分け</strong>: 回数が決まっていない繰り返しは Do Loop。決まっているなら For~Next、集合をまるごとなら For Each</li><li><strong>While と Until</strong>: While は条件を満たす「間」、Until は条件を満たす「まで」。条件式を否定形にすれば置き換え可能</li><li><strong>前判定と後判定</strong>: 前判定（<code>Do While</code> / <code>Do Until</code>）は0回実行もあり得る。後判定（<code>Loop While</code> / <code>Loop Until</code>）は必ず1回実行される</li><li><strong>迷ったら</strong>: <code>Do While ... Loop</code> を選べば大きく外さない</li><li><strong>無限ループ対策</strong>: 止めるのは <code>Esc</code> → <code>Ctrl</code> + <code>Break</code>。防ぐのは上限カウンター・<code>Exit Do</code>・カウンター更新の点検</li><li><strong>カウンターは <code>Long</code></strong>: <code>Integer</code> は32,767でオーバーフローする</li></ul>



<p class="wp-block-paragraph">一番のつまずきポイントは、やはりカウンターの更新忘れです。<code>Do</code> と <code>Loop</code> の間を見て「この変数、ちゃんと進んでる？」と自問する癖をつけましょう。それだけで無限ループはぐっと減らせます。</p>



<p class="wp-block-paragraph">条件付きの繰り返しが書けるようになると、VBA でできることの幅が一気に広がりますよ。まずは4パターンの最小コードを VBE に貼り付けて、イミディエイトウィンドウの出力を眺めてみてください。動きが目で見えると、前判定と後判定の違いもすっと腹落ちするはずです。</p>



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



<ul class="wp-block-list"><li><a href="https://mashukabu.com/excel-vba-howto-use-for/">VBA For~Next文の使い方｜繰り返し処理の基本から実務パターンまで解説</a></li><li><a href="https://mashukabu.com/vba-howto-use-for-each-next/">VBA For Eachの使い方｜セル・シート・配列を1行でループ処理</a></li><li><a href="https://mashukabu.com/excel-vba-conditional-branch-explanation/">VBA If文の使い方｜条件分岐を基本から実務コードまで解説</a></li><li><a href="https://mashukabu.com/how-to-stop-macro/">Excelマクロが止まらない時の強制終了4ステップ</a></li><li><a href="https://mashukabu.com/vba-error-guide/">VBAマクロのエラー解決ガイド｜頻出エラー別の直し方</a></li><li><a href="https://mashukabu.com/excel-vba-learning-roadmap/">VBA学習ロードマップ｜学習ステップを順番に整理</a></li></ul>
]]></content:encoded>
					
					<wfw:commentRss>https://mashukabu.com/how-to-use-do-loop/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
