配列を引数にするときの注意
配列を引数にするときの注意事項
配列引数はByRefでなければなりません
SubとかFunctionの引数に配列を使用しようとしたとき、「ByVal」キーワードを付けると、
こんなふうにコンパイル・エラーになる。
従って、引数を配列にしたときには必然的に参照渡しになってしまう、ということだ。
配列を加工して返すFunctionを使用した場合
……ということは、配列を受け取って、加工して返すようなFunctionを使用した場合、もはや元の(加工前の)配列は存在しない、ということなのだろうか。
やってみた
次のコードで実験。
リスト1 標準モジュール
Public Sub testTemperArray() Dim ar(3) As String ar(0) = "アホ" ar(1) = "ボケ" ar(2) = "クズ" ar(3) = "デコスケ" Dim el As Variant Debug.Print "【arの要素書き出し】" For Each el In ar '……(1)' Debug.Print el Next Dim ar2() As String ar2 = temperArray(ar) '……(2)' Debug.Print "【ar2の要素書き出し】" For Each el In ar2 '……(3)' Debug.Print el Next Debug.Print "【再びarの要素書き出し】" For Each el In ar '……(4)' Debug.Print el Next End Sub Private Function temperArray(ByRef targetArray() As String) As String() targetArray(2) = "KASU" temperArray = targetArray End Function
「temper」というのは、今はやりの「改竄する」という意味w
受け取った配列の第3要素を「KASU」というイカしたローマ字に改竄して返すプロシージャだ。
まず、冒頭で作成したarという要素数4の配列について、(1)からの3行
For Each el In ar Debug.Print el Next
で、For Eachを使って全要素をイミディエイトに書き出す。
次に、(2)の
ar2 = temperArray(ar)
で、バカ丸出しのFunctionプロシージャ「temperArray」に配列arを渡して、返り値をar2にぶち込む。
そして、(3)からの3行
For Each el In ar2 Debug.Print el Next
で、ar2の要素をイミディエイトに書き出す。
あとは、(4)からの3行
For Each el In ar Debug.Print el Next
で、再度arの全要素をイミディエイトに書き出す。
実行結果
arを引数として渡して加工したときに、arそのものが加工されてしまったっぽい。まさに参照渡し。
おわりに
気をつけないといけないなあ。