ここでは 実務でよく使う「別分野」 をテーマにして、
すべて ByRef(参照渡し)を積極活用した実例 をまとめて提示します。
実務の別分野:ByRef 具体例セット(全 6 種)
- フォルダ一括処理(ByRefでファイル名・進捗カウントを返す)
- CSV 読み込み(ByRefで配列を返す高速版)
- CSV 書き込み(ByRefでエラーメッセージを返す)
- Outlook メール送信(ByRefでメール内容を加工して送信)
- Web API 的な処理(ByRefでパラメータ加工 → 結果反映)
- Dictionary / 配列でのデータ加工(ByRefで値を変更)
① フォルダ一括処理(ByRef:ファイル名・カウンタを更新)
Sub ProcessFolderFiles()
Dim folder As String
Dim cnt As Long
Dim lastFile As String
folder = "C:\temp\in"
Call RunBatch(ByRef folder, ByRef cnt, ByRef lastFile)
MsgBox "処理件数:" & cnt & vbCrLf & "最終ファイル:" & lastFile
End Sub
'-------------------------------------------
' フォルダ内のファイルを一括処理(ByRef多用)
'-------------------------------------------
Sub RunBatch(ByRef folder As String, ByRef cnt As Long, ByRef lastFile As String)
Dim f As String
cnt = 0
f = Dir(folder & "\*.csv")
Do While f <> ""
cnt = cnt + 1
lastFile = f
' 実際の業務処理はここ
Debug.Print "Processing: " & f
f = Dir()
Loop
End Sub
VBポイント
- cnt を ByRef で渡し、プロシージャ内部でカウントして返す
- lastFile に最終ファイル名を返す
- 変数複数返却が必要なとき ByRef は極めて有効
② CSV 読み込み高速版(配列を ByRef で受け渡し)
Sub ReadCsvToArray()
Dim csvPath As String
Dim dataArr() As Variant
csvPath = "C:\temp\in\data.csv"
Call LoadCsvAsArray(ByRef csvPath, ByRef dataArr)
MsgBox "行数:" & UBound(dataArr, 1)
End Sub
'-------------------------------------------
' CSV → 配列(超高速)ByRefで配列返却
'-------------------------------------------
Sub LoadCsvAsArray(ByRef filePath As String, ByRef resultArr() As Variant)
Dim lines As String
Dim txt As String
Dim i As Long, rows As Variant
txt = CreateObject("Scripting.FileSystemObject") _
.OpenTextFile(filePath).ReadAll
rows = Split(txt, vbCrLf)
ReDim resultArr(LBound(rows) To UBound(rows), 0)
For i = LBound(rows) To UBound(rows)
resultArr(i, 0) = rows(i)
Next i
End Sub
VBポイント
- 配列を ByRef で渡す → 中で再構築 → 呼び出し元に反映
- 表データ CSV を配列化する高速パターン(業務向け)
③ CSV 書き込み(ByRefでエラー内容を返す)
Sub SaveCsv()
Dim data As String
Dim errMsg As String
data = "A,B,C" & vbCrLf & "1,2,3"
Call WriteCsv(ByRef data, ByRef errMsg)
If errMsg <> "" Then
MsgBox "エラー:" & errMsg, vbCritical
Else
MsgBox "保存完了"
End If
End Sub
'-------------------------------------------
' CSV 保存(ByRefでエラーメッセージを返却)
'-------------------------------------------
Sub WriteCsv(ByRef textData As String, ByRef errMsg As String)
On Error GoTo ERR_HANDLE
Dim path As String
path = "C:\temp\out\result.csv"
With CreateObject("Scripting.FileSystemObject")
.CreateTextFile(path, True).Write textData
End With
errMsg = ""
Exit Sub
ERR_HANDLE:
errMsg = Err.Description
End Sub
VBポイント
- 成功/失敗を戻り値にするより、
ByRefでエラー内容を返す方が業務では便利
④ Outlook メール送信(ByRefで本文を加工 → 送信)
Sub SendMail()
Dim toAddr As String
Dim subject As String
Dim body As String
toAddr = "sample@example.com"
subject = "日報"
body = "本日の報告です。"
Call BuildMailBody(ByRef body) ' 本文編集
Call SendOutlookMail(ByRef toAddr, ByRef subject, ByRef body)
MsgBox "メール送信完了"
End Sub
'-------------------------------------------
' 本文を加工(ByRefで書き換える)
'-------------------------------------------
Sub BuildMailBody(ByRef body As String)
body = body & vbCrLf & "送信日時:" & Now
End Sub
'-------------------------------------------
' Outlook メール送信(ByRefでパラメータ受け渡し)
'-------------------------------------------
Sub SendOutlookMail(ByRef toAddr As String, ByRef subject As String, ByRef body As String)
Dim ol As Object, mail As Object
Set ol = CreateObject("Outlook.Application")
Set mail = ol.CreateItem(0)
With mail
.To = toAddr
.Subject = subject
.Body = body
.Send
End With
End Sub
VBポイント
- 本文加工等を別プロシージャに切り分ける時、ByRefが自然
- 本番の業務マクロで多用されるパターン
⑤ Web API 風処理(ByRefでパラメータを加工)
これは外部 API ではなく、Excel 内の簡易 API 風パターンです。
Sub CallApi()
Dim url As String
Dim params As String
Dim result As String
url = "https://example.com/api"
params = "id=123"
Call BuildApiParams(ByRef params)
Call FakeApiRequest(ByRef url, ByRef params, ByRef result)
MsgBox "結果:" & result
End Sub
Sub BuildApiParams(ByRef params As String)
params = params & "&token=XYZ"
End Sub
Sub FakeApiRequest(ByRef url As String, ByRef params As String, ByRef result As String)
result = "URL=" & url & vbCrLf & "PARAMS=" & params
End Sub
VBポイント
- API-like な処理でも ByRef は汎用的に使える
⑥ Dictionary & 複数データ加工(ByRefで書き換え)
Sub DictProcess()
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
dict("A") = 10
dict("B") = 20
Call MultiplyValues(ByRef dict, 2)
MsgBox dict("A") & ", " & dict("B")
End Sub
'-------------------------------------------
' Dictionary の値を ByRef で書き換える
'-------------------------------------------
Sub MultiplyValues(ByRef dic As Object, ByVal rate As Double)
Dim k As Variant
For Each k In dic.Keys
dic(k) = dic(k) * rate
Next k
End Sub
VBポイント
- Dictionary や Collection もオブジェクトなので ByRef で直接加工
まとめ − ByRef を使うべき「実務パターン」
| 分野 | ByRef の使いどころ |
|---|---|
| フォルダ一括処理 | カウンタ・最後のファイル名など複数返却 |
| CSV 読み込み | 配列を加工して返却 |
| CSV 書き込み | エラーメッセージ返却 |
| メール送信 | 本文・件名の加工 |
| Web API 風 | パラメータ組み立て |
| Dictionary | データ加工 |


