外部のExcelファイルをVBAから開く際に使う Workbooks.Open メソッド。試験では、開いたブックを変数に格納して操作する際の「Set ステートメントの要否」や「括弧 ( ) をつける・つけないの記述ルール」が非常に頻出します。
1. 問題:Workbooks.Open メソッドによるブック変数の取得
【 問題 】 下記のコードは、C:\Data\Sales.xlsx を開き、開いたブックの1番目のシート名をメッセージボックスに表示しようとしています。空欄 ( A ) に入る記述として正しいものはどれでしょうか?
Sub OpenWorkbookTest()
Dim wb As Workbook
Dim filePath As String
filePath = "C:\Data\Sales.xlsx"
( A )
MsgBox wb.Worksheets(1).Name
End Sub
① wb = Workbooks.Open(filePath)
② Set wb = Workbooks.Open(filePath)
③ Set wb = Workbooks.Open filePath
④ Workbooks.Open(filePath) As wb
2. 正解:Open メソッドの構文に関する正解
正解: ② Set wb = Workbooks.Open(filePath)
3. 解説:メソッドの戻り値取得と括弧 ( ) の記述ルール
Workbooks.Open メソッドは、指定したファイルを開くと同時に、開いたそのファイル自体を表す Workbook オブジェクトを呼び出し元に返します(戻り値)。
[ 記述の構造とルールのポイント ]
1. オブジェクト変数への代入は Set が必須!
変数 wb は Workbook という「オブジェクト(参照型データ)」です。VBAにおいてオブジェクトを変数に代入する際は、必ず頭に Set キーワードをつけなければなりません(①のように Set を省くと「オブジェクト変数または With ブロック変数が設定されていません」というエラーになります)。
2. 戻り値を受け取る場合は引数をカッコ ( ) で囲む!
VBAでは、メソッドの戻り値を変数に代入して受け取る場合、引数をカッコで囲む必須ルールがあります(③のように Set を使ってもカッコがないとコンパイルエラーになります)。
★ 正解の Set wb = Workbooks.Open(filePath) は、「Setによるオブジェクト代入」と「戻り値取得のためのカッコ囲み」の両方のルールを満たしています。
ここが試験に出る!: スタンダード試験では、戻り値を受け取らない呼び出し(例:Workbooks.Open filePath)と、変数で受け取る呼び出し(例:Set wb = Workbooks.Open(filePath))のカッコや Set の有無を混ぜ合わせた誤答選択肢が頻出します。「Set で受けるならカッコが必要」というペアの構造を丸ごと暗記しておきましょう。
4. まとめ
「開いたブックを変数 wb に保持して操作するなら Set wb = Workbooks.Open(...) 」。この構文を押さえておけば、別ブックを開いてデータを転記し、保存して閉じる(wb.Close SaveChanges:=True)という一連の外部ファイル自動処理も完璧に制御できます。
PR
If 文で複数の条件を組み合わせる際に使用する And(かつ)と Or(または)。1つの If 条件式の中に両方が混在している場合、どちらが優先して評価されるかという「論理演算子の優先順位構造」を正しく把握しておく必要があります。
1. 問題:And と Or が混在する条件式の評価
【 問題 】 下記のコードを実行して CheckLogic プロシージャを呼び出した際、メッセージボックス(MsgBox)に表示される文字列として正しいものはどれでしょうか?
Sub CheckLogic()
Dim age As Integer
Dim member As Boolean
Dim coupon As Boolean
age = 25
member = False
coupon = True
If age >= 60 Or member = True And coupon = True Then
MsgBox "割引適用"
Else
MsgBox "通常料金"
End If
End Sub
① 割引適用
② 通常料金
③ 条件式の構文エラー(コンパイルエラー)が発生する
④ 実行時エラーが発生する
2. 正解:And と Or の評価順序に関する正解
3. 解説:「And 優先」で評価される論理演算の構造
VBAの仕様上、かっこ ( ) を使っていない場合、「And は Or よりも優先して先に計算される」という明確な優先順位ルールが存在します。
[ 条件式の評価構造ステップ ]
元の条件式:age >= 60 Or member = True And coupon = True
1. 優先度の高い And を先に結合・評価:
(member = True And coupon = True) の部分が先に判定されます。
・member は False
・coupon は True
⇒ False And True の結果は False となります。
2. 残った Or を評価:
age >= 60 Or [ステップ1の結果(False)] を判定します。
・age >= 60 (25 >= 60) は False
⇒ False Or False の結果は最終的に False となります。
★ したがって、If ブロックは実行されず、Else 側の "通常料金" が出力されます。
ここが試験に出る!: スタンダード試験では、「左から順番に Or から計算してしまう」という勘違いを誘う問題が頻出します。もし「(60歳以上または会員)であり、かつクーポンを持っている」という条件にしたい場合は、(age >= 60 Or member = True) And coupon = True のようにカッコで囲んで意図的に優先順位を変える必要があります。
4. まとめ
「And は掛け算(優先度高)、Or は足し算(優先度低)と同じ感覚で評価される」。この演算子の優先順位構造を頭に入れておけば、実務で複雑な顧客条件分岐やエラー判定ロジックを組む際にも、予期せぬ判定ミスを回避できます。
VBAの条件分岐の基本である If ... Then ... Else ... End If。複数の条件を評価する ElseIf や分岐の入れ子(ネスト)構造において、プログラムがどのような順番で条件を評価し、どの処理を通過するかを正しく読み解きましょう。
1. 問題:If ... Then ... ElseIf の評価順序と実行結果
【 問題 】 下記のコードを実行して EvaluateScore プロシージャを呼び出した際、メッセージボックス(MsgBox)に表示される文字列として正しいものはどれでしょうか?
Sub EvaluateScore()
Dim score As Integer
score = 85
If score >= 70 Then
MsgBox "合格"
ElseIf score >= 80 Then
MsgBox "優秀"
Else
MsgBox "不合格"
End If
End Sub
① 合格
② 優秀
③ 合格 と 優秀 の両方が表示される
④ 構文エラー(コンパイルエラー)が発生する
2. 正解:If文の分岐評価に関する正解
3. 解説:条件が「上から順番に評価される」構造の罠
If ... ElseIf 構造では、条件式が上から順番に判定され、最初に条件を満たした(Trueになった)ブロックの処理だけが実行されるという厳格なルールがあります。
[ If 分岐の実行フロー構造 ]
変数:score = 85
1. 1つ目の条件判定(If score >= 70):
85 >= 70 は 成立(True!)
⇒ MsgBox "合格" が実行される!
2. 2つ目以降の判定(ElseIf score >= 80):
すでに最初の条件で True になったため、2つ目以降の条件式は判定すらされずにスキップされ、End If の直後へ抜けます。
★ score = 85 は「80以上(優秀)」の条件も満たしていますが、先に「70以上(合格)」にヒットしてしまうため、「優秀」が表示されることはありません。
ここが試験に出る!: スタンダード試験では、このように「条件の記述順序ミス(評価の逆転)」を突く問題が非常によく出題されます。「優秀(80以上)」を正しく判定させたい場合は、If score >= 80 Then を一番上に書かなければならないという判定ロジックの構造を押さえておきましょう。
4. まとめ
「If文は最初につかまった条件で終了し、以降のElseIfは無視される」。この評価順序の仕組みを理解しておけば、実務で多段階の成績判定や金額の割引率計算を実装する際にも、条件の並べ順ミスによるロジックバグを完璧に防げるようになります。
For Each ... Next はワークシートやセル範囲だけでなく、「配列」の全要素を一括処理する際にも頻繁に使用されます。配列を走査する際の変数宣言(データ型)のルールをマスターしましょう。
1. 問題:配列に対する For Each の要素変数の型
【 問題 】 下記の ArrayLoopTest プロシージャを実行し、配列の要素を1つずつメッセージボックスに表示したい。空欄 ( A ) に入る要素変数のデータ型として、文法上**正しいもの**はどれでしょうか?
Sub ArrayLoopTest()
Dim arr As Variant
Dim item As ( A )
arr = Array("Tokyo", "Osaka", "Nagoya")
For Each item In arr
MsgBox item
Next item
End Sub
① String
② Variant
③ Object
④ Array
2. 正解:配列に対する要素変数の型に関する正解
3. 解説:配列を For Each で回す際の厳格な構文ルール
For Each ... Next を配列(Array)に対して使用する場合、VBAには言語仕様上の明確な制約が存在します。
[ 配列×For Each の構文ルール ]
・要素変数(item)は必ず Variant 型にする必要がある
たとえ配列の中身がすべて文字列(String型)であっても、For Each item In arr の要素変数 item は Variant 型(または型指定なしの標準Variant)で宣言しなければなりません。
・なぜ String 型(①)ではエラーになるのか?
VBAの仕様上、配列を For Each で受ける変数には Variant 型または Object 型しか認められていません。Dim item As String と記述すると、実行時に「変数の型が一致しません(コンパイルエラー)」が発生します。
ここが試験に出る!: スタンダード試験では、「中身が文字列だから As String で受けられる」という勘違いを狙うトラップ問題が非常に多く出題されます。「コレクション(WorksheetsやRange)なら特定の型(WorksheetやRange)が使えるが、配列のFor Eachは Variant型 が必須」という構造の違いを必ず暗記しておきましょう。
4. まとめ
「配列を For Each で受ける変数は Variant 一択」。このルールさえ覚えておけば、実務で `Array` 関数で作ったリストや動的配列の全要素チェックを行う際にも、コンパイルエラーを起こさずにスムーズなループ処理が実装できます。
データ入力チェックや未入力セルのカウントなどで頻出するのが、For Each ... Next を使ってセル範囲内の空白セルを1つずつ判定する処理です。空白の判定構文と集計のフローをマスターしましょう。
1. 問題:空白セルの判定とカウント処理
【 問題 】 下記の図のように、Excelシートの A1:B3 のセルに値(一部は空欄)が入力されています。この状態で以下の CountBlankCells プロシージャを実行した際、メッセージボックス(MsgBox)に表示される数値として正しいものはどれでしょうか?
| A | B |
| 1 |
100 |
(空白) |
| 2 |
(空白) |
200 |
| 3 |
300 |
(空白) |
Sub CountBlankCells()
Dim rng As Range
Dim c As Range
Dim blankCount As Long
Set rng = Range("A1:B3")
blankCount = 0
For Each c In rng
If c.Value = "" Then
blankCount = blankCount + 1
End If
Next c
MsgBox blankCount
End Sub
① 2
② 3
③ 6
④ 構文エラー(コンパイルエラー)が発生する
2. 正解:実行結果
3. 解説:空白セルの判定構造とトレース
Range("A1:B3") の全6セルを For Each で1セルずつ巡回し、値が空文字("")であるかを判定していきます。
【各セルの処理ステップ(左から右、上から下への順)】
初期値: blankCount = 0
1. セル A1(値: 100) : 100 = "" は False → 加算しない
2. セル B1(値: 空白): "" = "" は True → blankCount = 0 + 1 = 1
3. セル A2(値: 空白): "" = "" は True → blankCount = 1 + 1 = 2
4. セル B2(値: 200) : 200 = "" は False → 加算しない
5. セル A3(値: 300) : 300 = "" は False → 加算しない
6. セル B3(値: 空白): "" = "" は True → blankCount = 2 + 1 = 3
★ 合計3つの空白セルが検出され、メッセージボックスには 3 が表示されます。
ここが試験に出る!: スタンダード試験では、空白セルの判定として If c.Value = "" Then のほかに、If IsEmpty(c.Value) Then や If Len(c.Value) = 0 Then などの構文もよく出題されます。いずれの書き方でも「値が入っていないセル」を判定する仕組みをしっかり整理しておきましょう。
4. まとめ
「セル範囲をFor Eachで巡回し、c.Value = "" でカウントする」。この基本パターンを押さえておけば、実務での未入力チェックや、入力漏れのあるセルへの警告メッセージ表示などを簡単に作成できるようになります。
| A | B |
| 1 |
100 |
(空白) |
| 2 |
(空白) |
200 |
| 3 |
300 |
(空白) |
Sub CountBlankCells()
Dim rng As Range
Dim c As Range
Dim blankCount As Long
Set rng = Range("A1:B3")
blankCount = 0
For Each c In rng
If c.Value = "" Then
blankCount = blankCount + 1
End If
Next c
MsgBox blankCount
End Sub
① 2
② 3
③ 6
④ 構文エラー(コンパイルエラー)が発生する
2. 正解:実行結果
3. 解説:空白セルの判定構造とトレース
Range("A1:B3") の全6セルを For Each で1セルずつ巡回し、値が空文字("")であるかを判定していきます。
【各セルの処理ステップ(左から右、上から下への順)】
初期値: blankCount = 0
1. セル A1(値: 100) : 100 = "" は False → 加算しない
2. セル B1(値: 空白): "" = "" は True → blankCount = 0 + 1 = 1
3. セル A2(値: 空白): "" = "" は True → blankCount = 1 + 1 = 2
4. セル B2(値: 200) : 200 = "" は False → 加算しない
5. セル A3(値: 300) : 300 = "" は False → 加算しない
6. セル B3(値: 空白): "" = "" は True → blankCount = 2 + 1 = 3
★ 合計3つの空白セルが検出され、メッセージボックスには 3 が表示されます。
ここが試験に出る!: スタンダード試験では、空白セルの判定として If c.Value = "" Then のほかに、If IsEmpty(c.Value) Then や If Len(c.Value) = 0 Then などの構文もよく出題されます。いずれの書き方でも「値が入っていないセル」を判定する仕組みをしっかり整理しておきましょう。
4. まとめ
「セル範囲をFor Eachで巡回し、c.Value = "" でカウントする」。この基本パターンを押さえておけば、実務での未入力チェックや、入力漏れのあるセルへの警告メッセージ表示などを簡単に作成できるようになります。
"
dc:identifier="http://rikeineo.blog.shinobi.jp/Entry/2170/" />
-->