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

【VBAスタンダード対策】プロシージャを強制終了する「Exit Sub」の制御構造を攻略!

プログラムを実行中、エラーや特定の条件が発生した時点で、それ以降の処理をスキップしてプロシージャを終了させたい場合があります。その際に使用する Exit Sub の仕組みと、処理の流れる構造を正しく理解しましょう。

1. 問題:Exit Sub 実行時の処理の流れ

【 問題 】 下記のコードを実行して Main プロシージャを呼び出した際、メッセージボックスに表示される文字列はどれでしょうか?

Sub Main()
    Call CheckValue(10)
    MsgBox "完了"
End Sub

Sub CheckValue(num As Integer)
    If num > 5 Then
        Exit Sub
    End If
    MsgBox "チェック通過"
End Sub

① 「チェック通過」が表示された後、「完了」が表示される
② 「完了」だけが表示される
③ 「チェック通過」だけが表示される
④ 何も表示されずにマクロ全体が終了する

2. 正解:Exit Sub の制御フローに関する正解

正解: ② 「完了」だけが表示される

3. 解説:呼び出し元へ処理を戻す構造

Exit Sub の最も重要な構造的特徴は、「マクロ全体を終了させるわけではなく、呼び出されたプロシージャだけを終了して、呼び出し元に制御を戻す」という点にあります。

[ 処理のコントロール構造図 ]

Sub Main()
│ Call CheckValue(10) ───┐ 処理を移す
│ │
│ (戻ってきた!) ↓
MsgBox "完了" Sub CheckValue(num)
End Sub │ If 10 > 5 Then
Exit Sub ── 途中で脱出!
│ End If
MsgBox "チェック通過" (実行されない)
End Sub

1. ここが試験に出る!: スタンダード試験では、マクロ全体を終了させる End ステートメントと、そのプロシージャだけを抜ける Exit Sub の違いを突いてきます。今回のケースでは、CheckValue は途中で終了しますが、呼び出し元である Main の次の行(MsgBox "完了")に処理が戻る構造をしっかりと見極める必要があります。
2. エンジニアの視点: Java 17などの言語における `return;`(戻り値なしの即時復帰)と全く同じ構造です。実務において、不適切なデータ(事前条件の不一致)をプロシージャの最初でチェックして弾く手法を「ガード節(Guard Clause)」と呼びます。深くネスト(インデント)されたIf文を作らないための、理系NEOなスマートな設計パターンですね。


4. まとめ

「Exit Subは、その部屋(Sub)から出るだけで、元いた場所(Main)には戻る」。この構造を知っておけば、複雑なプロシージャ連携のデバッグも怖くありません。適切な脱出処理を組み込んで、無駄のない洗練された制御フローを構築しましょう。


PR

【VBAスタンダード対策】文字列連結演算子「&」と「+」の構造的違いを攻略!

VBAで文字列を結合する際、&(アンパサンド)と +(プラス)のどちらでも繋げられるように見えます。しかし、この2つは内部の処理構造が全く異なります。データの型が混ざったときに起きるVBA特有の挙動を解き明かしましょう。

1. 問題:型が混在する場合の連結演算子の挙動

【 問題 】 下記のコードを実行した際、メッセージボックスに表示される結果の組み合わせとして正しいものはどれでしょうか?

Sub OperatorTest()
    Dim val1 As String
    Dim val2 As Integer
    
    val1 = "100"
    val2 = 200
    
    ' --- (1) & 演算子で結合 ---
    Dim result1 As String
    result1 = val1 & val2
    
    ' --- (2) + 演算子で結合 ---
    Dim result2 As String
    result2 = val1 + val2
    
    MsgBox result1 & " / " & result2
End Sub

① result1: "100200" / result2: "100200"
② result1: "100200" / result2: 型違いによるエラー(または 300)
③ result1: 300 / result2: "100200"
④ result1: 型違いによるエラー / result2: 300

2. 正解:演算子の優先順位と型変換に関する正解

正解: ② result1: "100200" / result2: 型違いによるエラー(または 300)

3. 解説:強制結合の「&」と、足し算優先の「+」

VBAにおいて、この2つの演算子は「何を目的として作られたか」という根本的な構造の設計が異なります。

[ 演算子の構造的特徴 ]

■ & 演算子(文字列結合の専門職)
右と左のデータが何であれ、「すべて文字列に強制変換してくっつける」という構造を持っています。文字列の "100" と 数値の 200 なら、200を文字に変えて "100200" にします。エラーが起きにくく安全です。

■ + 演算子(本来は足し算の専門職)
片方が「数値型」である場合、VBAは構造的に「これは足し算(算術演算)だな」と解釈しようとします。そのため、もう片方の "100" も数値の 100 に自動変換して「100 + 200 = 300」として計算しようとします。

★ ここがトラップ!:
もし、val1 = "VBA" のように数値に変換できない文字だった場合、"VBA" + 200 は足し算が不可能なため、「型が一致しません(Runtime Error 13)」というエラーではじかれます。

1. ここが試験に出る!: スタンダード試験では、「文字列結合は & を使う」というのが大原則として問われます。+ を使ったコードを提示し、データ型が混ざったときに計算されてしまう挙動や、エラーになる危険性を指摘させる問題が定番です。
2. エンジニアの視点: Java 17などの現代的な言語では `+` 演算子が文字列結合として安全にオーバーロード(多重定義)されていますが、VBAは古い仕様を引き継いでいるため、四則演算のプラスと明確に区別する「理系NEO」な厳密さが必要です。実務でバグを生まないためにも、文字列の結合には **100% `&` を使う** のがプロの暗黙の了解です。


4. まとめ

「文字を繋ぐなら四の五の言わずに『&』」。この構造ルールを徹底するだけで、データの型に振り回されるバグは一掃できます。演算子ひとつにも明確な役割を与えること。それが、美しく堅牢なマクロの設計図を描くための基本です。


【VBAスタンダード対策】オブジェクトのクリア「Nothing」と状態判定の構造!

オブジェクト変数に格納された「実体への参照(リモコン)」は、使い終わったら明示的にクリアすることが推奨されます。また、変数が空っぽ(未設定)の状態であるかどうかを正確に判定する構造をマスターしましょう。

1. 問題:Nothingによるクリアと状態判定の文法

【 問題 】 オブジェクト変数 myWB に割り当てられたワークブックの参照をクリアし、その後、正しくクリアされたかどうか(Nothingであるか)を条件分岐で確認したい。空欄 ( A )( B ) に入る正しいキーワードの組み合わせはどれでしょうか?

Sub ClearTest()
    Dim myWB As Workbook
    Set myWB = Workbooks.Open("C:\Test.xlsx")
    
    ' --- (1) 参照をクリアする ---
    Set myWB = ( A )
    
    ' --- (2) クリアされたか判定する ---
    If myWB ( B ) Nothing Then
        MsgBox "変数はクリアされています。"
    End If
End Sub

① (A) Empty (B) =
② (A) Nothing (B) =
③ (A) Empty (B) Is
④ (A) Nothing (B) Is

2. 正解:オブジェクトのクリアと判定に関する正解

正解: ④ (A) Nothing (B) Is

3. 解説:Nothingという概念と「Is」演算子

オブジェクト変数を「何も指していない状態」にするキーワードと、その状態を比較する演算子には、VBA独自の構造ルールがあります。

[ Nothingの構造的メカニズム ]

1. クリアは「Set 変数 = Nothing」
Nothing は「どこも指していない無の状態」を表す特殊なキーワードです。通常の変数でいう 0 や空文字("")のような役割ですが、オブジェクト変数なので代入時には必ず Set が必要です。これによりメモリ上の参照(紐付け)が完全に切断されます。

2. 判定には「=」ではなく「Is」を使う
【超重要】 オブジェクトが Nothing かどうかを判定するとき、If myWB = Nothing と書くと実行時エラーになります。値の比較ではなく「同じ対象を指しているか(参照の比較)」を行うため、構造的に Is 演算子 を使用しなければなりません。

1. ここが試験に出る!: スタンダード試験では、あえて If myWB = Nothing という誤ったコードを提示し、エラーになる原因を答えさせる問題が頻出します。オブジェクトの比較は必ず Is(または否定の IsNot ではなく Not ... Is Nothing)を使うという構造を叩き込んでください。
2. エンジニアの視点: Java 17などでは `if (myWB == null)` のように共通の比較演算子を使いますが、VBAは「値の比較(=)」と「参照の比較(Is)」を厳密に区別する理系NEOな設計になっています。大規模なマクロでメモリリーク(メモリが解放されずに重くなる現象)を防ぐためにも、プロシージャの最後で `Set 変数 = Nothing` を明示する癖をつけるのがプロの構造化プログラミングです。


4. まとめ

「オブジェクトを消すならSet = Nothing、確かめるならIs Nothing」。このセットを完璧に理解していれば、オブジェクト変数の制御で迷うことはありません。メモリ空間を綺麗に保ち、エラーのないスマートなマクロを構築しましょう。


【VBAスタンダード対策】オブジェクト変数の代入と「Set」の構造を攻略!

オブジェクト変数とは、単なる「値」ではなく、ワークシートやセル範囲といった「モノ(オブジェクト)」を操作するために、その場所を記憶しておくための変数です。通常の変数とは代入のルールが根本的に異なります。

1. 問題:オブジェクト変数への正しい代入方法

【 問題 】 変数 mySheet に「Sheet1」というワークシートを割り当てて、そのシートの名前を表示させたい。空欄 ( A ) に入る正しい記述はどれでしょうか?

Sub ObjectTest()
    Dim mySheet As Worksheet

    ( A ) Worksheets("Sheet1")

    MsgBox mySheet.Name
End Sub

① mySheet =
② Set mySheet =
③ Let mySheet =
④ mySheet :=

2. 正解:オブジェクト変数の代入に関する正解

正解: ② Set mySheet =

3. 解説:なぜ「Set」が必要なのか?

VBAの構造において、通常の変数とオブジェクト変数は、メモリへの格納方法が明確に区別されています。

[ 変数の構造的違い ]

■ 値の代入(Set不要)
Dim n As Integer
n = 100 ' 箱の中に直接「100」を入れる

■ オブジェクトの代入(Set必須)
Dim r As Range
Set r = Range("A1") ' 箱の中に「A1セルという実体への参照(リモコン)」を入れる

★ 理系NEOなポイント:
参照(ポインタ):オブジェクト変数は、実体そのものを箱に入れているわけではなく、実体を操作するための「リモコン」を箱に入れているような構造です。
Nothing:オブジェクト変数を宣言した直後の初期状態は 0 ではなく Nothing です。Nothingの状態(リモコンがどこも指していない状態)でプロパティを操作しようとすると「オブジェクト変数が設定されていません」というエラーになります。

1. ここが試験に出る!: スタンダード試験では「Setを書き忘れていないか」という点が非常に多く問われます。また、使い終わった後に Set mySheet = Nothing としてメモリを解放する構造も重要です。
2. エンジニアの視点: Java 17などのオブジェクト指向言語では `new` キーワードでインスタンス化しますが、VBAでは既存のExcel要素(シートなど)を扱う際、この `Set` が「これは単なる値のコピーではなく、実体へのリンクである」という宣言の役割を果たしています。


4. まとめ

「オブジェクトにはSet、使い終わったらNothing」。この代入構造をマスターすることで、複雑なExcel操作も変数一つでスマートに制御できるようになります。変数という「リモコン」を正しく対象に向け、正確なマクロを構築しましょう。

【VBAスタンダード対策】配列リバース(逆順入れ替え)の論理構造を攻略!

配列の要素を逆順に並べ替える処理は、アルゴリズムの基礎です。ReDim で確保した領域の中で、どのように値を入れ替えるのか。ループの範囲設定と、データ消失を防ぐための「一時変数」の役割を理解しましょう。

1. 問題:配列の要素を入れ替えるアルゴリズム

【 問題 】 5つの要素を持つ配列 myAry の中身を逆順(myAry(0)と(4)、myAry(1)と(3)を入れ替え)にしたい。空欄 ( A ) に入る最も適切なコードはどれでしょうか?

Sub ReverseArray()
    Dim myAry() As Variant
    Dim tmp As Variant
    Dim i As Long, n As Long

    myAry = Array("A", "B", "C", "D", "E") '要素数5(0 to 4)
    n = UBound(myAry)

    For i = 0 To ( A )
        tmp = myAry(i)
        myAry(i) = myAry(n - i)
        myAry(n - i) = tmp
    Next i
End Sub

① n
② n - 1
③ n \ 2
④ n / 2

2. 正解:ループ回数の決定に関する正解

正解: ③ n \ 2

3. 解説:入れ替え処理の「折り返し地点」

配列を逆順にする際、最も間違いやすいのが「ループを最後まで(nまで)回してしまう」ことです。構造的な仕組みを図解で確認しましょう。

[ 入れ替えの構造図 ]

対象:(0) (1) (2) (3) (4) ※n=4

1回目(i=0):(0) と (4-0=4) を入れ替え
2回目(i=1):(1) と (4-1=3) を入れ替え
ここで終了!

もし、さらに i=3 まで回すと、(3)と(1)を再び入れ替えてしまい、「元に戻ってしまう」 という現象が起きます。

★ 理系NEOなポイント:
n \ 2:整数除算演算子 \ を使い、中心で止めます(4 \ 2 = 2。i=0から2まで回る)。
一時変数 tmpmyAry(i) = myAry(n-i) とした瞬間に、元の myAry(i) は消えてしまいます。あらかじめ tmp に退避させておくのが、構造的なデータ保護の鉄則です。

1. ここが試験に出る!: 試験では「tmpを使わずに直接代入しようとしていないか」「ループ回数が多すぎて元に戻っていないか」という論理ミスを突いてきます。UBound \ 2 という「半分で止める」感覚を身につけましょう。
2. エンジニアの視点: Java 17などの `Collections.reverse()` を使えば一発ですが、VBAで自作する場合は「メモリ上の値をどう移動させるか」を意識します。この「端と端を順番に入れ替えていく」構造は、並べ替え(ソート)アルゴリズムにも通ずる非常に重要な考え方です。


4. まとめ

「リバースは半分で止める。上書き前に退避する」。この2点を守るだけで、配列操作の正確性は格段に向上します。データの位置を構造的に把握し、制御できるようになれば、VBAエキスパートへの道もぐっと近づきます。