Excel VBA | 「複数の引数」を渡す

VBA
スポンサーリンク

概要:「引数(ひきすう)」って何?

プロシージャ(SubFunction)に渡す値のことです。
引数を使うと、同じプロシージャを色んな値で再利用できます。
例えば「文字列」と「回数」を渡して、その文字列を何回か連結してセルに出す、などが典型例です。


1. 基本:複数の引数を渡す方法

呼び出し側(呼ぶ側):

Call MyProc("Hello", 3)
' または Call を省略して
MyProc "Hello", 3
VB

受け取り側(定義側):

Sub MyProc(ByVal text As String, ByVal count As Integer)
    ' ここで text と count を使って処理
End Sub
VB

ポイント:

  • 引数はカンマ , で区切る。
  • 受け取り側は引数名(変数名)と型(As String など)を宣言する。
  • 数が合わないとエラーになります。

2. 例題①:文字列を繰り返してセルに入れる(基本)

Sub Test1()
    Call RepeatToA1("こんにちは", 2)
End Sub

Sub RepeatToA1(ByVal msg As String, ByVal times As Integer)
    Dim i As Integer
    Dim result As String
    For i = 1 To times
        result = result & msg
    Next i
    Range("A1").Value = result   ' A1 に出力
End Sub
VB

実行結果:セル A1 に こんにちはこんにちは

解説:msgtimes という 2つの引数 を渡している。ByVal は値をコピーして渡す(後述)。


3. ByVal と ByRef の違い(超重要)

  • ByVal:呼び出し元の変数のコピーを渡す。プロシージャ内で変えても、呼び出し元は変わらない。
  • ByRef:呼び出し元の変数への参照を渡す。プロシージャ内で変えると、呼び出し元も変わる。

例で確認:

Sub TestByValRef()
    Dim x As Integer
    x = 5
    ModifyByVal x    ' x は呼び出し後も 5 のまま
    Debug.Print "After ByVal: " & x   ' -> 5

    ModifyByRef x    ' x は呼び出し後に変更される
    Debug.Print "After ByRef: " & x   ' -> 100
End Sub

Sub ModifyByVal(ByVal n As Integer)
    n = 99
End Sub

Sub ModifyByRef(ByRef n As Integer)
    n = 100
End Sub
VB

ポイント:意図せず元の値を変えたくないなら ByVal を使う。変えたい(更新したい)なら ByRef


4. Optional(オプション)引数:渡しても渡さなくてもOKにする

Sub TestOptional()
    Call Greet("太郎")      ' 第二引数を省略
    Call Greet("花子", "さん")
End Sub

Sub Greet(ByVal name As String, Optional ByVal suffix As String = "さん")
    MsgBox name & suffix
End Sub
VB
  • Optional を付けるとその引数は省略可能。省略された場合は = 値 に設定したデフォルト値が入る。
  • 注意:古い慣習で IsMissingVariant 型の Optional のみで使える、などの制約があります(今回は簡単に Optional ... = デフォルト を使えばOK)。

5. ParamArray:可変長引数(引数の数が変わる場合)

複数の値をまとめて渡したいときに便利(配列として受け取る)。

Sub TestParamArray()
    JoinAndShow "a", "b", "c"
    JoinAndShow "one", "two"
End Sub

Sub JoinAndShow(ParamArray items() As Variant)
    Dim i As Long, s As String
    For i = LBound(items) To UBound(items)
        s = s & items(i) & " "
    Next i
    MsgBox Trim(s)
End Sub
VB

呼び方は JoinAndShow "a", "b", "c" のように普通にカンマ区切りで渡すだけ。


6. 引数の不一致で起きるエラー

  • 呼び出し側が 2 個渡しているのに、受け取り側が 3 個を期待している → 実行時エラー。
  • データ型が合わない(文字列を数値で受ける等)と型変換の問題やエラーが起きることがある。

対策:

  • 定義側と呼び出し側の引数の数/順番/型を合わせる。
  • 可能なら Option Explicit を使って変数ミスを防ぐ。

7. 実践例(ちょっと長め):合計を算出して返す Function

Function は値を返すので、引数を受け取って計算結果を返す場面で使う。

Sub TestSum()
    Dim s As Double
    s = SumRangeValues(Range("B1:B3"))   ' セル範囲を渡す
    MsgBox "合計は " & s
End Sub

Function SumRangeValues(rng As Range) As Double
    Dim cell As Range
    Dim total As Double
    total = 0
    For Each cell In rng
        If IsNumeric(cell.Value) Then
            total = total + cell.Value
        End If
    Next cell
    SumRangeValues = total    ' 関数の戻り値を設定
End Function
VB

ポイント:rng As Range のようにオブジェクト型の引数も渡せます(セルの範囲など)。


8. よくある質問(Q&A)

Q
CallCall を省略する書き方、どっちが良い?
A

Call はあってもなくても動きます。Call を使うと読みやすい場合もありますが、慣習的に省略して SubName arg1, arg2 と書くことも多いです。Function を呼んで戻り値を無視する場合に Call を使う人もいます。

Q
引数の順番は変えられる?
A

基本は定義した順。VBA は命名して渡す(キーワード渡し)もできますが、初心者は順番どおりに渡すのが安全です。


9. 練習問題

  1. HelloWorld を 3 回繰り返してセル B1 に入れる Sub を作って実行してみてください。
  2. ByRef を使って、呼び出し元の数を +1 する Sub を作り、呼び出し前後の値を Debug.Print で確認してください。
  3. Optional 引数を使って「挨拶メッセージ」を作る Sub を作る(省略時は “さん” を付ける)。
  4. ParamArray を使って複数の数値を受け取り、その合計を MsgBox で表示する Sub を作ってください。
  5. 範囲(Range)を引数に取り、その範囲内の数値セルだけを合計して返す Function を作って、セルに結果を表示する Sub を作ってください。

10. 練習問題の模範解答(コピペして試せます)

問題1(模範解答):

Sub Q1()
    RepeatToA1 "Hello", 3   ' 既出の RepeatToA1 を流用
End Sub
VB

問題2(模範解答):

Sub Q2()
    Dim n As Integer
    n = 10
    Debug.Print "Before: " & n
    IncrementByRef n
    Debug.Print "After: " & n
End Sub

Sub IncrementByRef(ByRef x As Integer)
    x = x + 1
End Sub
VB

問題3(模範解答):

Sub Q3()
    Greet "太郎"      ' "太郎さん"
    Greet "花子", "様" ' "花子様"
End Sub

Sub Greet(ByVal name As String, Optional ByVal suffix As String = "さん")
    MsgBox name & suffix
End Sub
VB

問題4(模範解答):

Sub Q4()
    SumParam 1, 2, 3, 4
End Sub

Sub SumParam(ParamArray nums() As Variant)
    Dim i As Long, total As Double
    For i = LBound(nums) To UBound(nums)
        total = total + nums(i)
    Next i
    MsgBox "合計は " & total
End Sub
VB

問題5(模範解答):

Sub Q5()
    Dim res As Double
    res = SumRangeValues(Range("C1:C5"))
    Range("D1").Value = res
End Sub

Function SumRangeValues(rng As Range) As Double
    Dim cell As Range, total As Double
    total = 0
    For Each cell In rng
        If IsNumeric(cell.Value) Then total = total + cell.Value
    Next cell
    SumRangeValues = total
End Function
VB

11. 最後に — 実務でのコツ

  • 引数が増えすぎたら「その処理は別のプロシージャに分ける」ことを検討する。読みやすさ優先。
  • 型宣言(As StringAs Integer)は必ず書く。バグを防げます。
  • Option Explicit をモジュールの先頭に書くと変数の未宣言ミスを防げます。

VBA
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました