Excel VBA | ByRef(参照渡し)を積極活用した実例

Excel VBA VBA
スポンサーリンク

ここでは 実務でよく使う「別分野」 をテーマにして、
すべて ByRef(参照渡し)を積極活用した実例 をまとめて提示します。


実務の別分野:ByRef 具体例セット(全 6 種)

  1. フォルダ一括処理(ByRefでファイル名・進捗カウントを返す)
  2. CSV 読み込み(ByRefで配列を返す高速版)
  3. CSV 書き込み(ByRefでエラーメッセージを返す)
  4. Outlook メール送信(ByRefでメール内容を加工して送信)
  5. Web API 的な処理(ByRefでパラメータ加工 → 結果反映)
  6. 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データ加工
VBA
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました