忍者ブログ
バイオインフォマティックス技術者試験、情報処理試験など、IT系の試験を基礎から勉強します。また、Javaなどプログラミングを勉強します。

【VBAスタンダード対策】処理を中断する「Exit Sub」の構造を攻略!

Subプロシージャは通常、上から下へと順番に実行されますが、エラー発生時や特定の条件を満たした際に「それ以降の処理を行わずに呼び出し元へ戻る」という制御が必要になります。この「途中で終わる」ための正確な記述を確認しましょう。

1. 問題:プロシージャの中途終了

【 問題 】 以下のコードにおいて、変数 ans が 0 の場合に、メッセージを表示せずにプロシージャを途中で終了させたい。空欄 ( A ) に入る正確な記述はどれでしょうか?

Sub CheckValue(ans As Integer)
    If ans = 0 Then
        ( A )
    End If

    MsgBox "結果は " & ans & " です"
End Sub

① End   ② Exit Sub   ③ Stop   ④ Return Sub

2. 正解:中途終了の構文に関する正解

正解: ② Exit Sub

3. 解説:なぜ「Exit Sub」でなければならないのか?

プロシージャを物理的な終端(End Sub)まで実行させずに、その場で呼び出し元に制御を戻す命令が Exit Sub です。これは「出口を無理やり作る」ような構造的役割を果たします。

[ プロシージャ脱出の構造図 ]

Sub Main()              Sub CheckValue(ans)
  |                        +-------------------+
  +--[ 呼出 ]-----------> | If ans = 0 Then  |
  |                       |   Exit Sub ------|---(即座に復帰)
  +<-[ 復帰 ]------------- | End If           |
  |                       |  [以降の処理]      |
  |                       | End Sub          |
  |                       +-------------------+

[ 注意すべきキーワードの違い ]
Exit Sub:現在のプロシージャのみを終了し、呼び出し元へ戻ります。
End:プログラム全体の実行を完全に停止し、すべての変数をリセットします。影響範囲が大きすぎるため、中途終了には通常使いません。

1. ここが試験に出る!: 試験では「このコードを実行した際、MsgBoxが表示されるか否か」を問う形式で出題されます。If 文の条件が成立し、Exit Sub を踏んだ時点で、その下のコードは一行も実行されないという構造的遮断を正しく読み解く必要があります。
2. エンジニアの視点: Java 17などの return; ステートメントに相当します。異常な値を最初にはじく「ガード句」として Exit Sub を活用することで、後続のメインロジックをシンプルに保つことができ、保守性の高い「いけいけ」なコード構造が実現します。


4. まとめ

「異常があれば Exit Sub で即脱出」。この中途終了の構造を使いこなすことで、予期せぬエラーや不要な処理の実行を防ぐことができます。減数分裂が特定のチェックポイントで制御されるように、VBAも Exit Sub という関門を設けることで、確実かつ安全なプログラム制御が可能になるのです。



PR

【VBAスタンダード対策】処理を繋ぐ「プロシージャ呼び出し」を攻略!

一つの大きな処理(Main)から、特定の役割を持つ別の処理(Sub)を実行することを「呼び出し」と言います。VBAでは、Callキーワードを使う方法と、省略する方法の2通りがありますが、それぞれ記述の「構造」が異なります。

1. 問題:他のSubプロシージャを呼び出す正確な記述

【 問題 】 引数 val を受け取るSubプロシージャ Update を呼び出す際、VBAの構文(フォーマット)として不適切なものはどれでしょうか?

Sub Main()
    Dim val As Integer : val = 100
    ' --- ここで Update を呼び出す ---
End Sub

Sub Update(n As Integer)
    MsgBox n
End Sub

① Call Update(val)
② Update val
③ Call Update val
④ Update(val) (※引数が1つの場合、動作はするが非推奨の構造)

2. 正解:呼び出しの構造(Callとカッコの有無)に関する正解

正解: ③ Call Update val

3. 解説:呼び出しによって「制御」が移る構造

VBAでは、別のSubを呼ぶ際に「Callを使うならカッコで囲む」「Callを使わないならスペースで繋ぐ」という鉄則があります。どちらの方法でも正しく呼び出せますが、記述を混ぜることはできません。

[ プロシージャ呼び出しの構造図 ]

Mainプロシージャ              Updateプロシージャ
+-------------------+          +-------------------+
| Sub Main()        |          | Sub Update(n)    |
|  [処理1]          |          |                  |
|  Call Update(v) --|---(呼出)--->  [引数nの処理]    |
|  [処理2] <--------|---(復帰)---  End Sub          |
| End Sub           |          +-------------------+
+-------------------+

[ 2通りの正しいフォーマット ]
パターA(Callあり):Call Update(val)
パターB(Callなし):Update val
※ Callを使うと「今から別のSubを呼び出す」という意図が明確になり、構造が分かりやすくなります。

1. ここが試験に出る!: 試験では「Callを書かずにカッコを付ける」という誤用が狙われます。特に引数が2つ以上ある場合(例:Call Calc(a, b))において、Callを抜いて Calc(a, b) と書くと構文エラーになります。この「連動性」を正確に把握しましょう。
2. エンジニアの視点: Java 17などモダンな言語では常にカッコが必要ですが、VBAは「文(Statement)」として呼び出す形式を継承しています。大規模な開発では、後から見た人が「どこで外部Subへ飛んでいるか」を一目で判断できるよう、Callを明示的に付ける構造が推奨されることが多いです。


4. まとめ

「Callを使うならカッコ、使わないならスペース」。この呼び出し構造をマスターすることで、複雑に絡み合うマクロの動きを正確に制御できるようになります。減数分裂において情報がリレーされるように、VBAも正確な呼び出しによって、一つの大きな目的(業務自動化)を達成するのです。



【VBAスタンダード対策】マクロの絶対終端「End Sub」の構造を攻略!

VBAのプロシージャは、Sub 名前 で始まり、必ず End Sub で終わるという一対の構造(ペア)で成立します。この「終わり」を示す記述が正確でないと、プログラムの範囲が確定できず、構造エラーとなります。

1. 問題:プロシージャを完結させる正確な記述

【 問題 】 以下のSubプロシージャにおいて、プロシージャの範囲を適切に終了させ、一つの構造として完結させるために ( A ) に入る正確な記述はどれでしょうか?

Sub Sample()
    MsgBox "処理を実行します"
( A )

① EndSub   ② Exit Sub   ③ End Sub   ④ End

2. 正解:プロシージャの終端フォーマットに関する正解

正解: ③ End Sub

3. 解説:なぜ「End Sub」という構造が必要なのか?

VBAにおいて、Sub(開始)に対応する終端は、End(キーワード)+ 半角スペース + Sub(キーワード)という特定の単語の組み合わせでなければなりません。この物理的な「閉じ」があることで、初めて一つの独立したプログラムとして認識されます。

[ End Sub の構造的絶対ルール ]
一対の原則:Sub で開始したプロシージャは、必ず End Sub で閉じなければなりません。
スペースの重要性:EndSub のようにスペースを抜かすと、コンパイラは終端として認識できず、エラーになります。
メモリの解放:この行に到達した瞬間に、そのプロシージャ内だけで使われていた変数(ローカル変数)はすべて破棄されます。

[ 他の選択肢との構造的な違い ]
Exit Sub:途中で抜ける「動作」であり、プロシージャという建物の「壁(終端)」の役割は持っていません。
End:プログラム全体を強制停止する命令であり、プロシージャを閉じるための構文ではありません。

1. ここが試験に出る!: VBAスタンダード試験では、コードの穴埋め形式でこの「End Sub」を正確に記述させることがあります。特に、Function プロシージャ(End Function)との混同や、単語間のスペースの有無は、構文の正確性を問うスタンダードレベルでは非常に重要なチェックポイントです。
2. エンジニアの視点: VBAでは明示的に「End(終わり) Sub(サブプロシージャ)」と言葉で記述します。この「出口」を明確に定義することが、予期せぬ動作を防ぎ、論理的な構造を持った「いけいけ」なマクロを作成する大前提となります。


4. まとめ

「Sub 名前」で開けたら、最後は「End Sub」で締める。この一対のフォーマットを正確に守ることが、VBAにおける「構造」の正解です。減数分裂が細胞分裂のサイクルを正しく完遂するように、VBAも End Sub という終止符によって、一つの処理を安全に終わらせ、次のステップへと確実に繋いでいくのです。


【VBAスタンダード対策】状態を保持する「Static変数」の構造を攻略!

通常、Subプロシージャ内で宣言された変数は、End Sub に到達した瞬間にメモリから消滅します。しかし、Static キーワードを使って宣言された変数は、プロシージャが終了してもその値をメモリ上に維持し続けます。この「静的な保持」の仕組みを理解しましょう。

1. 問題:実行をまたぐ数値の変化

【 問題 】 以下のSubプロシージャ Accumulate を、他の場所から2回連続で呼び出したとします。2回目の実行時に、メッセージボックスに表示される数値はいくつでしょうか?

Sub Accumulate()
    Static total As Integer
    Dim subTotal As Integer

    total = total + 10
    subTotal = subTotal + 10

    MsgBox total
End Sub

① 0   ② 10   ③ 20   ④ エラーになる

2. 正解:変数の初期化と保持に関する正解

正解: ③ 20

3. 解説:なぜ「20」になるのか?

通常の Dim で宣言された subTotal は、End Sub のたびにリセットされますが、Static で宣言された total は前回の値を引き継ぎます。1回目で10になり、2回目でさらに10が加算されるため、結果は20となります。

[ Static変数の生存構造図 ]

1回目実行:
[開始] total(0) -> [加算] total(10) -> [終了] 保持

2回目実行:
[開始] total(10) -> [加算] total(20) -> [終了] 保持

[ Dimとの構造的な違い ]
Dim 変数:End Subでメモリが解放され、次回はまた0(初期値)から始まる。
Static 変数:End Subを通ってもメモリが解放されず、ブックを閉じるまで値を維持する。

1. ここが試験に出る!: 試験では「変数の有効範囲(スコープ)」と「生存期間(ライフサイクル)」が混同しやすいポイントとして狙われます。Static変数は「そのSubの中でしか使えない(ローカルスコープ)」けれど、「値は消えない(モジュールレベル並みの寿命)」という特殊な構造を持っていることを押さえましょう。
2. エンジニアの視点: 仰る通り、実務では「誰がいつこの値を書き換えたか」が不透明になりやすく、バグの温床になりがちです。Java 17のクラス変数に近いですが、より影響範囲を限定した「状態を持つメソッド」を作りたい時に使われます。ただ、可読性を優先するなら、モジュールレベル変数にするか、引数で値を回す方が「理系NEO」な綺麗な設計と言えますね。


4. まとめ

「Static = End Subを越えて記憶する」。この構造を理解すれば、実行回数のカウントや累積計算など、フラグ管理が容易になります。減数分裂が特定の情報を次へ繋ぐように、VBAも Static を使うことで、プロシージャの枠を超えて「状態」を維持することができるのです。



【VBAスタンダード対策】値が生き続ける「モジュールレベル変数」を攻略!

プロシージャ(Sub)の中で宣言した変数は、End Sub に到達すると消滅してしまいます。しかし、プロシージャの外で宣言する「モジュールレベル変数」は、マクロが動いている間、その値を保持し続けるという特別な構造を持っています。

1. 問題:変数のスコープと実行結果

【 問題 】 同一の標準モジュールに記述された以下のコードを、Main → Main の順で2回連続して実行した際、2回目の実行時に表示される数値はいくつでしょうか?

Dim count As Integer ' --- (A) プロシージャの外で宣言 ---

Sub Main()
    count = count + 1
    ShowCount
End Sub

Sub ShowCount()
    MsgBox count
End Sub

① 0   ② 1   ③ 2   ④ エラーになる

2. 正解:変数の生存期間(寿命)に関する正解

正解: ③ 2

3. 解説:なぜ「End Sub」を越えて値が残るのか?

プロシージャの外(宣言セクション)で Dim を使って宣言された変数は、そのモジュール内のすべてのプロシージャで共有され、各プロシージャが終了しても値がリセットされません。

[ 変数の生存構造図 ]

標準モジュール
+------------------------------------------+
| Dim count (←ここで値が保持され続ける)   |
|                                         |
| Sub Main()                               |
|   count = count + 1  ←前回値を継承     |
| End Sub (←ここでは消えない!)           |
+------------------------------------------+

[ スコープによる構造の違い ]
ローカル変数:Subの中で宣言。End Sub でメモリから破棄される。
モジュールレベル変数:Subの外で宣言。ブックを閉じたり End ステートメントが実行されるまで値が残る。

1. ここが試験に出る!: 試験では「この変数はどこまで有効か?」という有効範囲(スコープ)と寿命の問題が頻出します。特に、今回の問題のように「2回実行した時の挙動」を問うことで、ローカル変数とモジュールレベル変数の構造的違いを区別できるかが試されます。
2. エンジニアの視点: Java 17などのクラス変数(静的フィールド)に近い挙動ですね。便利ですが、どこからでも書き換えられてしまうため、不必要な多用は避け、カプセル化(Private宣言)を意識した構造設計が、プロレベルの「いけいけ」なコードには求められます。


4. まとめ

「Subの外に書けば、End Subを越えて生き残る」。この生存戦略を理解することで、複数の処理をまたいだデータの集計や状態管理が可能になります。減数分裂において遺伝情報が次世代へ受け継がれるように、VBAも適切なスコープを選択することで、必要な情報を正しく未来へ繋いでいくのです。

        
  • 1
  • 2
  • 3