概要:「引数(ひきすう)」って何?
プロシージャ(Sub や Function)に渡す値のことです。
引数を使うと、同じプロシージャを色んな値で再利用できます。
例えば「文字列」と「回数」を渡して、その文字列を何回か連結してセルに出す、などが典型例です。
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 に こんにちはこんにちは
解説:msg と times という 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
VBOptionalを付けるとその引数は省略可能。省略された場合は= 値に設定したデフォルト値が入る。- 注意:古い慣習で
IsMissingはVariant型の 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
CallとCallを省略する書き方、どっちが良い? - A
Callはあってもなくても動きます。Callを使うと読みやすい場合もありますが、慣習的に省略してSubName arg1, arg2と書くことも多いです。Functionを呼んで戻り値を無視する場合にCallを使う人もいます。
- Q引数の順番は変えられる?
- A
基本は定義した順。VBA は命名して渡す(キーワード渡し)もできますが、初心者は順番どおりに渡すのが安全です。
9. 練習問題
HelloWorldを 3 回繰り返してセル B1 に入れるSubを作って実行してみてください。ByRefを使って、呼び出し元の数を +1 するSubを作り、呼び出し前後の値をDebug.Printで確認してください。- Optional 引数を使って「挨拶メッセージ」を作る
Subを作る(省略時は “さん” を付ける)。 ParamArrayを使って複数の数値を受け取り、その合計をMsgBoxで表示するSubを作ってください。- 範囲(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
VB11. 最後に — 実務でのコツ
- 引数が増えすぎたら「その処理は別のプロシージャに分ける」ことを検討する。読みやすさ優先。
- 型宣言(
As StringやAs Integer)は必ず書く。バグを防げます。 Option Explicitをモジュールの先頭に書くと変数の未宣言ミスを防げます。
