memorandums

日々の作業ログです。

VBAの関数の引数渡しのデフォルトはByRefです>自分

VBAExcelのワークシート中のデータをCSVファイルに書き出すプログラムを作っていたときのことです。ファイル名とシート名をある関数に渡してCSVを読み書きできるような関数を作りました。概略は以下のような感じです。

Sub func(arg1 As String, arg2 As String)
 (省略)
End Sub

Sub main()
    func "ファイル名", "シート名"
End Sub

で、ファイル名とシート名を一緒にすることが多いので、何気なく以下のようなユーティリティ関数を追加しました(VBAでは可変引数をサポートしていない;いろいろと工夫すればできるようですが。。。)。

Sub func2(arg1 As String)
 func arg1, arg1
End Sub

Sub main()
    func2 "シート名"
End Sub

で、動かしてみると実行エラーが。。。調べてみるとfunc関数でarg1とarg2の値が同じになっています。もしや。。。バッファーオーバー?とも考えましたが、よくよくコードを見ると、func関数の中でarg1の値を書き換えていました(昔の癖で普段は関数内で仮引数に代入するようなプログラムは書かないのですが横着しました。。。)。そうです。。。arg1はもとを辿るとfunc2で同じ変数を使用していました。。。arg1を変更すると同じ実体であるarg2も変更されます。。。そうなんですね。VBAでは関数の引数は参照渡し(ByRef)なんですね。ちなみにIntegerも参照渡しです。忘れないように>自分。


ちなみに、ついでにRubyもやってみました。

def func arg1, arg2
  arg1 = 2
  p arg1 + arg2
end

def func2 arg 
  func arg, arg 
end

func2 1


さあ、結果は3でしょうか4でしょうか?ご興味のある方はご自分で確かめてみてください。