では 12問すべて の模範解答コードを 1問ずつ、コード + 丁寧な解説(なぜそう書くか・注意点・テスト方法)付きでまとめます。
長いので見やすく分割してあります。実際に試すときは各コードを 新しいモジュール/クラスモジュール に貼ってください(クラスは必ず「挿入 → クラスモジュール」で作り、ファイル名を指示どおりにしてください)。
- 1. クラスモジュール:Employee(社員オブジェクト)
- 2. クラス:Product(小計・税込を返す)
- 3. クラス:CSV を読み込んで LineItem を返す
- 4. Dictionary:社員名→部署マップ
- 5. Dictionary に Product オブジェクトを格納(商品ID→Product)
- 6. JSON:Dictionary → JSON(変換)
- 7. JSON:JSON文字列 → パースして名前一覧を表示
- 8. Web API:HTTP GET(WinHttp)
- 9. Web API:HTTP POST(JSON送信)
- 10. ADO:Access (.accdb) から社員一覧を取得
- 11. ADO:INSERT でデータを追加
- 12. 標準モジュール設計:CSV→フィルタ→JSON→API を責務分離して実装
- 最後に — 実行時のチェックポイント & トラブルシューティング
1. クラスモジュール:Employee(社員オブジェクト)
目的:クラス(オブジェクト)にプロパティとメソッドを持たせ、標準モジュール側で使う。
Employee クラス(クラスモジュール名を Employee に)
' クラスモジュール: Employee
Private pName As String
Private pAge As Long
Private pDepartment As String
Public Property Get Name() As String
Name = pName
End Property
Public Property Let Name(val As String)
pName = val
End Property
Public Property Get Age() As Long
Age = pAge
End Property
Public Property Let Age(val As Long)
pAge = val
End Property
Public Property Get Department() As String
Department = pDepartment
End Property
Public Property Let Department(val As String)
pDepartment = val
End Property
Public Function GetInfo() As String
GetInfo = pName & " / " & pAge & " / " & pDepartment
End Function
VB呼び出し例(標準モジュール)
Sub TestEmployee()
Dim e1 As Employee, e2 As Employee, e3 As Employee
Set e1 = New Employee
Set e2 = New Employee
Set e3 = New Employee
e1.Name = "田中": e1.Age = 30: e1.Department = "総務"
e2.Name = "佐藤": e2.Age = 25: e2.Department = "営業"
e3.Name = "鈴木": e3.Age = 40: e3.Department = "開発"
Debug.Print e1.GetInfo
Debug.Print e2.GetInfo
Debug.Print e3.GetInfo
End Sub
VB解説・ポイント
- カプセル化のため
Privateなフィールドを持ちProperty Get/Letで公開する。こうすると将来の変更に強くなる(例:入力検証を追加できる)。 GetInfoはクラス内のデータをフォーマットして返す簡単なメソッド。- テストは
Debug.Printで Immediate ウィンドウに出力するかMsgBoxでも可。
2. クラス:Product(小計・税込を返す)
目的:商品クラスに数量・単価を持たせ、小計と税込(税率可)を返す。
Product クラス(クラスモジュール名 Product)
' クラスモジュール: Product
Private pUnitPrice As Double
Private pQty As Long
Private Const TAX_RATE As Double = 0.1 ' 10%
Public Property Get UnitPrice() As Double
UnitPrice = pUnitPrice
End Property
Public Property Let UnitPrice(val As Double)
pUnitPrice = val
End Property
Public Property Get Qty() As Long
Qty = pQty
End Property
Public Property Let Qty(val As Long)
pQty = val
End Property
Public Function Subtotal() As Double
Subtotal = pUnitPrice * pQty
End Function
Public Function TaxIncluded() As Double
TaxIncluded = Subtotal() * (1 + TAX_RATE)
End Function
VB呼び出し例
Sub TestProduct()
Dim p As Product
Set p = New Product
p.UnitPrice = 120
p.Qty = 3
Debug.Print "小計=" & p.Subtotal ' 360
Debug.Print "税込=" & p.TaxIncluded ' 396 (360 * 1.1)
End Sub
VB解説・注意点
- 税率を定数にしておくとメンテナンスしやすい。国や取引で可変なら Property にする。
- 金額計算は Double を使うが、金融アプリなら丸め方(Decimal 等)に注意。
3. クラス:CSV を読み込んで LineItem を返す
目的:CSVを読み込み、1行を1オブジェクト(LineItem)にしてコレクションで返す。
LineItem クラス(クラスモジュール名 LineItem)
' クラスモジュール: LineItem
Private pColumns As Variant
Public Property Get Columns() As Variant
Columns = pColumns
End Property
Public Property Let Columns(val As Variant)
pColumns = val
End Property
Public Function GetColumn(idx As Long) As String
If idx >= LBound(pColumns) And idx <= UBound(pColumns) Then
GetColumn = pColumns(idx)
Else
GetColumn = ""
End If
End Function
VBCSVReader クラス(クラスモジュール名 CSVReader)
' クラスモジュール: CSVReader
Public Function Load(path As String) As Collection
Dim col As New Collection
Dim fnum As Integer: fnum = FreeFile
Dim line As String
Open path For Input As #fnum
Do While Not EOF(fnum)
Line Input #fnum, line
Dim item As LineItem
Set item = New LineItem
item.Columns = Split(line, ",")
col.Add item
Loop
Close #fnum
Set Load = col
End Function
VB呼び出し例(標準モジュール)
Sub TestCSVReader()
Dim reader As New CSVReader
Dim rows As Collection
Set rows = reader.Load("C:\Test\sample.csv") ' フルパスに置き換え
Dim item As LineItem
Dim i As Long
For i = 1 To rows.Count
Set item = rows(i)
Debug.Print "行 " & i & " 列2=" & item.GetColumn(1) ' 0ベース
Next i
End Sub
VB解説・注意点
Splitで簡易CSVを分割している。カンマを含む要素・引用符付きCSVには対応しない(実務では専用パーサーが必要)。LineItem.Columnsは 0ベースの配列になる点に注意(Splitの仕様)。- ファイルパスの存在チェックやエラーハンドリング(
On Error)を本番では追加。
4. Dictionary:社員名→部署マップ
目的:Scripting.Dictionary の基本操作(追加・取得・削除・列挙)を練習。
サンプルコード(標準モジュール)
Sub TestDictionary()
Dim dic As Object
Set dic = CreateObject("Scripting.Dictionary") ' late binding
' 追加
dic.Add "佐藤", "開発"
dic.Add "田中", "総務"
dic("鈴木") = "営業" ' 既存キーは代入、未登録は追加
' 検索
If dic.Exists("田中") Then
Debug.Print "田中 の部署は " & dic("田中")
End If
' 一覧表示
Dim key As Variant
For Each key In dic.Keys
Debug.Print key & " -> " & dic(key)
Next key
' 削除
dic.Remove "田中"
' 全削除
dic.RemoveAll
End Sub
VB解説・ポイント
CreateObject("Scripting.Dictionary")は late binding。早期バインドにしたい場合は「参照設定 → Microsoft Scripting Runtime」を使いDim dic As Scripting.Dictionaryと書ける。Existsで存在確認をする習慣をつけるとエラー回避になる。
5. Dictionary に Product オブジェクトを格納(商品ID→Product)
目的:オブジェクトを Dictionary に格納するパターン。
前提:Product クラスは問題2と同じものを利用
サンプルコード(標準モジュール)
Sub TestProductDictionary()
Dim dic As Object
Set dic = CreateObject("Scripting.Dictionary")
Dim p As Product
Set p = New Product
p.UnitPrice = 100
p.Qty = 2
dic.Add "A001", p
Set p = New Product
p.UnitPrice = 250
p.Qty = 1
dic.Add "A002", p
' ID A001 の税込価格を表示
If dic.Exists("A001") Then
Debug.Print "A001税込=" & dic("A001").TaxIncluded
End If
End Sub
VB解説
- Dictionary の値にオブジェクトを入れると、後でそのオブジェクトのメソッドやプロパティを直接呼べる(
dic("A001").TaxIncluded)。 - 破棄(Set obj = Nothing)は明示的には必要ないが、長時間動くアプリではリソース管理に注意。
6. JSON:Dictionary → JSON(変換)
目的:VBAで辞書をJSONに変換する(VBA-JSON 等を利用)。
前提:
JsonConverter.bas(VBA-JSON)がプロジェクトにインポートされ、JsonConverterモジュールが利用できること。
(VBA-JSON は外部ライブラリなので、入手・インポートしてから実行してください)
サンプル(標準モジュール)
Sub TestDictToJson()
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
dict("Name") = "山田"
dict("Age") = 40
Dim skills As Variant
skills = Array("Excel", "VBA", "SQL")
dict("Skills") = skills
Dim json As String
json = JsonConverter.ConvertToJson(dict, Whitespace:=2) ' 整形出力
Debug.Print json
End Sub
VB解説・注意点
ConvertToJsonはDictionaryと配列をJSONに変換する。Whitespaceオプションで見やすく整形できる。- JsonConverter がない場合は別途ダウンロード(Github等)して読み込む必要がある(これは実行環境依存)。
7. JSON:JSON文字列 → パースして名前一覧を表示
目的:JSON をパースして VBA の配列や Dictionary として使う。
サンプル(標準モジュール)
Sub TestJsonParse()
Dim json As String
json = "[{""Name"": ""田中"", ""Score"": 80},{""Name"": ""鈴木"", ""Score"": 90}]"
Dim parsed As Object
Set parsed = JsonConverter.ParseJson(json) ' parsed は Collection (配列相当)
Dim item As Variant
For Each item In parsed
Debug.Print item("Name") ' Dictionaryとして扱える
Next item
End Sub
VB解説
ParseJsonは JSON 配列をCollection(順序付き)で返し、各要素はDictionary(キーで参照)となる。- 型は late-binding の Object/Variant で扱うのが一般的。
8. Web API:HTTP GET(WinHttp)
目的:外部の REST API へ GET リクエストを送り JSON を受け取り解析する。
サンプル(標準モジュール)
Sub TestHttpGet()
Dim url As String
url = "https://jsonplaceholder.typicode.com/posts/1"
Dim http As Object
Set http = CreateObject("WinHttp.WinHttpRequest.5.1")
http.Open "GET", url, False
http.SetRequestHeader "Accept", "application/json"
http.Send
If http.Status = 200 Then
Dim body As String
body = http.ResponseText
Debug.Print body
' JSON をパースして title を取得 (JsonConverter 前提)
Dim obj As Object
Set obj = JsonConverter.ParseJson(body)
Debug.Print "title = " & obj("title")
Else
Debug.Print "HTTP Error: " & http.Status
End If
End Sub
VB解説・注意点
WinHttpRequestは比較的使いやすく、同期(False)での呼び出し例。- HTTPS を使う API はプロキシや証明書の設定によって追加処理が必要になることがある(企業ネットワーク)。
- CORS はブラウザ側の概念なので、VBA側は影響を受けない(ただしサーバーが認証を要求する場合はヘッダ追加が必要)。
9. Web API:HTTP POST(JSON送信)
目的:JSON を POST してレスポンスを受け取る。
サンプル(標準モジュール)
Sub TestHttpPost()
Dim url As String
url = "https://jsonplaceholder.typicode.com/posts" ' テスト用のPOSTエンドポイント
Dim payload As String
payload = "{""name"":""Taro"",""age"":20}"
Dim http As Object
Set http = CreateObject("WinHttp.WinHttpRequest.5.1")
http.Open "POST", url, False
http.SetRequestHeader "Content-Type", "application/json"
http.Send payload
Debug.Print "Status=" & http.Status
Debug.Print http.ResponseText
End Sub
VB解説
Content-Typeを正しくセットすることが重要。- 実運用のAPIは認証(APIキー、Bearerトークン等)が必要なことが多い。
SetRequestHeader "Authorization", "Bearer xxxxx"のように設定する。 - テスト環境では
jsonplaceholder.typicode.comのようなダミーサービスで試すと安全。
10. ADO:Access (.accdb) から社員一覧を取得
目的:ADO を使った DB 接続とデータ取得。
サンプル(標準モジュール)
Sub TestAdoSelect()
Dim cn As Object, rs As Object
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
Dim dbPath As String
dbPath = "C:\Test\test.accdb" ' 実際のパスに変更
Dim connStr As String
connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbPath & ";Persist Security Info=False;"
On Error GoTo ErrHandler
cn.Open connStr
Set rs = cn.Execute("SELECT Name FROM Employees")
Do While Not rs.EOF
Debug.Print rs.Fields("Name").Value
rs.MoveNext
Loop
Cleanup:
On Error Resume Next
If Not rs Is Nothing Then
If rs.State = 1 Then rs.Close
End If
If Not cn Is Nothing Then
If cn.State = 1 Then cn.Close
End If
Set rs = Nothing
Set cn = Nothing
Exit Sub
ErrHandler:
Debug.Print "Error: " & Err.Number & " - " & Err.Description
Resume Cleanup
End Sub
VB解説・注意点
Microsoft.ACE.OLEDB.12.0は 64bit/32bit Excel とドライバの整合性に注意。環境によりMicrosoft.Jet.OLEDB.4.0(古い)や別の接続文字列が必要になる。- Accessファイルのパスや権限(読み取り権)が必要。
- SQLはSQLインジェクションに注意(ユーザー入力を組み込む場合はパラメータ化を検討)。
11. ADO:INSERT でデータを追加
目的:テーブルへデータを追加する方法。
サンプル(標準モジュール)
Sub TestAdoInsert()
Dim cn As Object
Set cn = CreateObject("ADODB.Connection")
Dim dbPath As String
dbPath = "C:\Test\test.accdb"
Dim connStr As String
connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbPath & ";Persist Security Info=False;"
On Error GoTo ErrHandler
cn.Open connStr
Dim name As String: name = "Suzuki"
Dim age As Long: age = 28
Dim dept As String: dept = "Sales"
Dim sql As String
sql = "INSERT INTO Employees ([Name], Age, Department) VALUES ('" & Replace(name, "'", "''") & "', " & age & ", '" & Replace(dept, "'", "''") & "')"
cn.Execute sql
MsgBox "INSERT 完了"
Cleanup:
On Error Resume Next
If Not cn Is Nothing Then
If cn.State = 1 Then cn.Close
End If
Set cn = Nothing
Exit Sub
ErrHandler:
Debug.Print "Error: " & Err.Number & " - " & Err.Description
Resume Cleanup
End Sub
VB解説・注意点
- SQL内に文字列を直挿入する場合は
'を''に置き換えてエスケープする(Replace(name,"'","''"))。 - 本番ではパラメータ化(Command オブジェクト)を使うべき(セキュリティと型の安全)。
- テーブル構造(列名・型)を事前に確認。
12. 標準モジュール設計:CSV→フィルタ→JSON→API を責務分離して実装
目的:モジュールを責務ごとに分け、テストしやすくする。ここでは実装サンプルを簡略化して示す。
モジュール構成(ファイル名)
CsvReader.bas(CSV読み込み機能)ScoreFilter.bas(抽出ロジック)JsonWriter.bas(JSON 変換)ApiClient.bas(POST)Main.bas(ワークフロー制御)
CsvReader.bas
' CsvReader.bas
Option Explicit
Public Function ReadCsv(path As String) As Collection
Dim col As New Collection
Dim fnum As Integer: fnum = FreeFile
Dim line As String
Open path For Input As #fnum
Do While Not EOF(fnum)
Line Input #fnum, line
col.Add line
Loop
Close #fnum
Set ReadCsv = col
End Function
VBScoreFilter.bas
' ScoreFilter.bas
Option Explicit
' 各行 "Name,Score" を受け、Score>=threshold のものを Dictionary として返す
Public Function FilterScores(lines As Collection, threshold As Long) As Collection
Dim out As New Collection
Dim i As Long
For i = 1 To lines.Count
Dim parts As Variant
parts = Split(lines(i), ",")
If UBound(parts) >= 1 Then
Dim name As String: name = Trim(parts(0))
Dim score As Long: score = CLng(Trim(parts(1)))
If score >= threshold Then
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
dict("Name") = name
dict("Score") = score
out.Add dict
End If
End If
Next i
Set FilterScores = out
End Function
VBJsonWriter.bas
' JsonWriter.bas
Option Explicit
Public Function ToJson(items As Collection) As String
' JsonConverter が前提
Dim arr() As Variant
ReDim arr(0 To items.Count - 1)
Dim i As Long
For i = 1 To items.Count
arr(i - 1) = items(i) ' items(i) は Dictionary
Next i
ToJson = JsonConverter.ConvertToJson(arr, Whitespace:=2)
End Function
VBApiClient.bas
' ApiClient.bas
Option Explicit
Public Function PostJson(url As String, json As String) As String
Dim http As Object
Set http = CreateObject("WinHttp.WinHttpRequest.5.1")
http.Open "POST", url, False
http.SetRequestHeader "Content-Type", "application/json"
http.Send json
PostJson = http.ResponseText
End Function
VBMain.bas
' Main.bas
Option Explicit
Public Sub RunPipeline()
Dim lines As Collection
Set lines = ReadCsv("C:\Test\scores.csv") ' CSV を用意
Dim filtered As Collection
Set filtered = FilterScores(lines, 80)
Dim json As String
json = ToJson(filtered)
Debug.Print json
Dim response As String
response = PostJson("https://example.com/api/receive", json)
Debug.Print "API Response: " & response
End Sub
VB解説・設計意図
- 責務分離:CSV読み込み・抽出ロジック・JSON生成・API送信を明確に分けると、ユニットテストや差し替えが簡単になる(例:APIが変わったら
ApiClientだけ書き換え)。 - テストしやすさ:
FilterScoresはCollectionを受けてCollectionを返すため、テスト用のダミーデータを渡して動作検証できる。 - 拡張性:JSON化のルールを変えたい場合は
JsonWriterを変更すれば他に影響を与えない。 - 注意:実行時に
JsonConverterとWinHttpが使えること、CSVパス・APIエンドポイントが正しいことを確認してから実行する。
最後に — 実行時のチェックポイント & トラブルシューティング
- 参照設定
JsonConverter(VBA-JSON)を使う場合はそのモジュールをプロジェクトにインポートしてください。参照設定は不要(late binding)ですが、コードを読む・編集する上でモジュールは必須です。- ADO を早期バインドしたい場合は「参照設定 → Microsoft ActiveX Data Objects x.x Library」を追加できます(ただし late binding を使えば不要)。
- 権限・ネットワーク
- ファイル/DB のパスと読み書き権限を確認。
- Web API は社内プロキシやファイアウォールでブロックされていることがある(会社PCでエラーが出る場合はネットワーク管理者へ確認)。
- 64bit/32bit の差
- Windows API 宣言や一部の外部参照は 64bit/32bit で違う場合がある(今回のサンプルでは回避しているが ADO ドライバ等は注意)。
- デバッグのコツ
Debug.Printを多用して途中経過を確認。- エラー処理は最小限(今回のサンプルでは簡潔化)→ 実運用では
On Errorを適切に配置する。

