ExcelのマクロでのExit Subの役割とは

このQ&Aのポイント
  • Excelのマクロで使用されるExit Subの役割について、詳しく説明してください。
  • マクロ内でのExit Subの使用によって、セルA1に表示される値が制御される仕組みについて教えてください。
  • マクロ内でのExit Subの挙動について、理解が深まると助かります。
回答を見る
  • ベストアンサー

ExcelのマクロでのExit Subの役割とは

久しぶりに Excel のマクロについて 質問させていただきます。 実際に作ったマクロはとても長いのですが 問題となった部分を簡潔にまとめて記載します。 Sub test() Range("A1") = 0 入力 = Application.InputBox("入力") If 入力 = "a" Then Call test End If Call test2 End Sub Sub test2() Range("A1") = Range("A1") + 1 End Sub これにより 「a」を入力している限りは先へ進めず 「a」以外を入力したところで セルA1に「1」と表示させるつもりでした。 しかし実際には 「a」を入力した回数プラス1が セルA1に表示されてしまいます。 仕方がないので Call test の後に Exit Sub と入力したところ、希望通り セルA1には「1」と表示されました。 Exit Sub を入力しなくても 何度も test() に戻るだけで Range("A1") に影響するのは、最後の Call test2 による1回だけと思うのですが なぜこのような結果になるのでしょうか。 今回もマクロについては まだまだ素人だと痛感しているところです。 回答をよろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • oboroxx
  • ベストアンサー率40% (317/792)
回答No.1

>何度も test() に戻るだけで ではなく、test()から、test()を呼び出すと、コンピュータ上では、同じコードのtest()ではあるのですが、別のtest()ととして呼び出すのです。 これを再帰呼び出しといいます。 なので、なんどもtest2()が呼び出されてしまうのです。

niftynejp
質問者

お礼

早速のご回答 ありがとうございました。 大変分かりやすく 説明していただきました。 おかげさまで とてもすっきりしました。 「再帰呼び出し」という言葉 これからしっかり勉強したいと思います。 何かありましたら そのときはまた ぜひよろしくお願いいたします。

その他の回答 (1)

  • asciiz
  • ベストアンサー率70% (6638/9405)
回答No.2

すでにANo.1さんの「再帰呼び出しをしてしまっている」というので正解なんですが、別の説明をしてみます。 「『call test』と書けば、制御が先頭に移る」と考えたのでしょうけど、call文を使ってしまったために、副作用が生じています。 単に命令実行位置を変えたければ、GoTo文を使うべきだったでしょう。 サブルーチンの頭に「test_top:」とラベルを書いておき、「call test」ではなく「GoTo test_top」と書けば、お望みの動作になったかと思います。 -- ではサブルーチン呼び出しではなぜうまく行かないか? サブルーチンを呼び出すってことは、呼び出す元の位置に、サブルーチン内容を丸々コピペするのと同じですよね。 つまり、サブルーチンtest内で「call test」と書いたなら、そこにまたtestサブルーチン全体をコピペしたことになってしまいます。 callによって単に制御が頭にもどったのではありません、サブルーチン呼び出しが一段深くなった上で、新たにtestサブルーチンの先頭から実行しているんです。 停止条件が満たされない限り、何重にもtestが呼び出される、すなわちtestサブルーチンのコピペが行われる、プログラムになってしまっているのですね。 停止条件が成立すれば、test2を呼び出しサブルーチン呼び出しは一段階終了、元の呼び出しcall文の次から実行を再開します。 一度停止条件が成立すれば、これまで何重にもたまったcallが解消されていき、その度にtest2が呼び出されます。 なので、最終結果として、ご質問にかかれた動作をしてしまいました。 -- このように、サブルーチン内から自分自身を呼び出すことを「再帰呼び出し」といい、プログラミング手法のひとつです。 使える場面では便利な手法です。 例えば、HDDの全フォルダ、全段階に渡って特定ファイルを調べる、とか。 今回は使うべき場面ではなかったのではないでしょうか?

niftynejp
質問者

お礼

ご回答 ありがとうございました。 お礼コメントが大幅に遅れてしまって 申し訳ございません。 GoTo文の使い方を 大いに活用させていただきます。 何かありましたら またよろしくお願いいたします。

関連するQ&A

  • エクセルマクロでinputboxメソッドゼロ入力

    エクセル2007です。 以下のマクロで、inputboxメソッドで質問させると、キャンセルボタンを押すと、うまいぐあいに止まります。 しかし、0を押しても、止まってしまいます。本当は、C2にゼロと表示させたいのです。 Sub 練習() Dim myR myR = Application.InputBox(prompt:="数量を入力しなさい", Type:=1) If myR = False Then Exit Sub Range("C2").Value = myR End Sub

  • Excelのマクロで質問です

    セルに関数で文字が入った時にマクロを実行させる方法を教えて下さい。 今回行いたいのは、C9~C19セルにNGと表示された場合にメッセ―ジを表示したいです。 Private Sub Worksheet_Change(ByVal Target As Range) '変化のあったセルがA1セルか? If Intersect(Target, Range("C9:C19")) Is Nothing Then Exit Sub '条件判定:A1セルの値は 1 か? If Target.Value = "NG" Then MsgBox "NGです" End If End Sub このような場合C9~C19セルにNGと打ち込めばメッセ―ジが表示されるのですが あらかじめ、関数で =IF(M9="","",IF(Q9<M9,"OK","NG")) というような式がそれぞれのC9、C10、C11・・・・セルに入ってしまっています。 これだと、例えばC9セルにNGと表示されてもマクロは起動せず、メッセージが表示されません。 関数をマクロに盛り込むか、このままでもマクロが起動できるような書き方があるか 教えてください。 すみません。補足でQ9セルには =IF(I9="","",I9+"07:01")のような関数が 入力されています。

  • エクセル/マクロ Exit Subが実行されない

    エクセルマクロの質問です。エクセルのヴァージョンは2000です。 あるシートをコピーして新シートに任意の名前を付けるマクロを作っています。ユーザーフォームの中に一つのテキストボックス(新シートの名前入力用)と二つのコマンドボタンを設置し一つは実行ボタン、もう一つはキャンセルボタンとしました。 QNo.6367227でエラー処理に関する質問をさせていただきましたが、こちらは見事に解決していただきました。 今回の質問はExit Subに関する質問です。 If構文で、条件文1が真であればシートをコピーして名前を変更、フォームを閉じるという処理を目指しています。 If 条件 Then ~ 処理 Exit Sub という形を作って試してみたのですが、処理後にExit Subが実行されません。Exit Subの前にメッセージボックスを挿むとメッセージは表示されましたが、やはりExit Subにはたどり着けませんでした。 すごく初歩的な事で恥ずかしいのですが、Exit Subが実行されない理由と解決法をご教示いただけると助かります。よろしくお願いします。 Private Sub CommandButton1_Click() Dim NewSheetName As String NewSheetName = TextBox1.Value On Error Resume Next Sheets("Summary").Name = NewSheetName If Err.Number = 0 Then Sheets(NewSheetName).Copy before:=Sheets(NewSheetName) ActiveSheet.Name = "Summary" MsgBox ("Task Completed!") ExitSub Else MsgBox "Invalid name!" End If On Error GoTo 0 End Sub

  • エクセルのマクロ

    セルの値が変わったら動くマクロですが、2つ書くとエラーが出ます。 どのように直したらいいでしょうか? Private Sub Worksheet_Change(ByVal Target As Range) Select Case Target.Address If Intersect(Target, Range("EK22")) Is Nothing Then Exit Sub Else Range("EK24:EM28").Select Selection.ClearContents End If End Sub Private Sub Worksheet_Change(ByVal Target As Range) If Intersect(Target, Range("EK24")) Is Nothing Then Exit Sub Else Range("EK27:EM28").Select Selection.ClearContents End If End Sub

  • メッセージボックスを表示させるエクセルマクロ

    こんにちは。マクロ初心者です。 エクセル(Excel2003)でメッセージボックスを 表示させるマクロが思うようにいかず困っています。 B列に「○○会社」と入力されれば、 「取引先です。」 とメッセージボックスを表示させたいと思い、 次のとおりマクロを作成しました。 -------------------------------- Private Sub Worksheet_Change(ByVal Target As Range) If Target.Column = 2 And Target Like "*会社" Then MsgBox "取引先です。" End If End Sub -------------------------------- しかし、コピーなどで複数のセルを貼り付ける(入力)行為をすると、 「実行エラー'13': 型が一致しません」と出てしまいます。 Worksheet_Change(ByVal Target As Range)を使っているので、 -------------------------------- Private Sub Worksheet_Change(ByVal Target As Range) If Target.Count > 1 Then Exit Sub If Target.Column = 2 And Target Like "*会社" Then MsgBox "取引先です。" End If End Sub -------------------------------- と、「If Target.Count > 1 Then Exit Sub 」を入れれば、 メッセージは出なくなるのですが、 これだと、A列セルに、コピー&ペーストで複数セルを貼り付けた場合、 「○○会社」があっても、マクロが効いてきません。 複数セルの貼り付けにも対応させるには、 どのようにすればよろしいでしょうか? 基本的なところが理解できていないのだと自覚しておりますが、 どうかご教授願います。 長々とわかりづらい文章ですみません。よろしくお願いします。

  • マクロ inputbox ブランクで入力した時

    いつも回答して頂きありがとうございます。 InputBoxに何も入力せず、OKを押してしまった場合、マクロの処理を終了させたいのですが、どうしたらよろしいでしょうか?宜しくお願い致します。 Sub 名前を入力する() Dim a As Long a = Application.InputBox("班を数字で入力して下さい。", Type:=1) If a = 0 Then MsgBox "キャンセルされました。", vbOKOnly Exit Sub End If With ActiveSheet .Range("E4:F5").Value = Worksheets("名前一覧").Cells(2, a).Value End With End Sub

  • エクセルにてダブルクッリクしたときの動作

    エクセルにて特定のセルをダブルクリックをした時に日付を表示させたくて以下のマクロを組みました。 Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range,Cancel As Boolean) If intersect(Target, Range("A1")) Is Nothing Then Exit Sub If ActiveCell = "" Then ActiveCell = Format(date, "yyyy") Cancel = True End If End Sub この場合A1セルをダブルクリックした時のみ西暦が入力されるようになっていますが、他のセルで、例えばB1セルでは月、C1セルでは日にちをダブルクリックで入力させるにはどうしたら良いでしょうか? If intersect(Target, Range("A1")) Is Nothing Then Exit Sub のTarget, Rangeを書き換えて複数このマクロを書き込んだのですがうまく動作しなくて。 知恵を貸していただけると助かります。

  • エクセルのマクロコードについて

    エクセルのマクロコードに付いて教えて下さい。 下記のマクロコードがありますが、 Option Explicit ' Private Sub Worksheet_Change(ByVal Target As Range) '   Static Memo(1 To 3) As Long   Dim Cell As Range '   If Intersect([A1:C1], Target) Is Nothing Then     Exit Sub   End If '   For Each Cell In Target '     If Cell = "" Then       Memo(Cell.Column) = 0     End If   Next Cell   Set Cell = Target(1) '   If Not IsNumeric(Cell) Or Cell = "" Then     Exit Sub   End If '   Application.EnableEvents = False   Memo(Cell.Column) = Memo(Cell.Column) + Target   Target = Memo(Cell.Column)   Application.EnableEvents = True End Sub セル位置の指定を変更する場合は、どの様に書けば良いのですか? このコードですと、セルA1からc1の入力指定でなっていますが A1からAA1までとかにする場合やA1の結果を、A1ではなくA2に表示B1の結果をB2に表示する場合はどのように書くのでしょうか? マクロに付いて、殆ど知識が無いものですので 出来れば、分かり易い説明でお願いします。 宜しくお願いします。

  • エクセル イベントマクロ Changeイベントを複数作りたい

    Private Sub Worksheet_Change(ByVal Target As Range)   If Intersect(Target, Range("A1")) Is Nothing Then Exit Sub 以下マクロの内容 End Sub これでセルA1が変わるとイベントマクロが発生しますが セルB1が変わると別のマクロが発生し セルC1が変わるとまた別のマクロが発生し…とするには どうすればよいのですか 単純に並べて書いたらだめみたいだったんですけど

  • エクセル イベントマクロ

    マクロ初心者です。よろしくお願いします。 セル範囲(A1:F20)に何も入力されていなければ塗りつぶしされ、 何か(文字、数字などなんでも)入力されていれば、塗りつぶしがなくなる。 というマクロをあえて、条件付き書式を使わずに行いたいとやってみました。(以下) Private Sub Worksheet_Change(ByVal Target As Range) Dim a As Range For Each a In Range("A1:F20") If a.SpecialCells(xlCellTypeVisible) Then a.Interior.ColorIndex = xlNone Else a.Interior.ColorIndex = 7 End If Next a End Sub ところが、半角数字(0以外)では動作するのですが 文字を入力するとエラーとなり「型が一致しません」と表示されます。 どう直したらよいのでしょうか? 最近マクロをやってみようと始めたので、基本的なことがわかっていないのかも。 どなたか、具体的なご指導お願いします。

専門家に質問してみよう