SAK 図書館
VB 基礎編 (その五) 関数構造(sub、function) private、public、ByVal、ByRef
VB の関数構造について説明します。 関数内へは、他のルーチンから goto で飛んできたり、飛びたしたりはできませ ん。関数には、戻り値のあるものと、ないもので宣言の仕方が VB では違います。 昔はサブルーチンなどと呼ばれました。 ■戻り値のないもの sub 関数名 (引数) end sub public sub 関数名 (引数) end sub private sub 関数名 (引数) end sub ■戻り値のあるもの function 関数名 (引数) as 戻り値 end function public function 関数名 (引数) as 戻り値 end function private function 関数名 (引数) as 戻り値 end function public 宣言を標準モジュール(コードモジュール) で使用すると、プロジェクト のどこからでも呼び出せる関数になる。 private 宣言すると、そのモジュールでのみ呼び出し可能となる。 関数名は予約語でなければなんでも自由に指定できます。 引数と言うのは、その関数に渡される値です。 尚、VB の引数はアドレスで渡されるので注意して下さい。 (他の言語は、ほとんど値で渡される。) これは、その関数内で引数の値をいじると、呼びたした側の値も変わることを意 味します。基本的に引数の値をいじることはしないように。 戻り値は、呼び出した側に受け渡すものです。 値渡しにする場合は、ByVal キーワードを使用する。(ByVal p1 as long) アドレス渡し(参照渡し) は、ByRef で省略値である。 (p1 as long、ByRef p1 as long) 【例】'** エラーメッセージを表示する関数 sub ErrMsg (titl as string, msg as string) msgbox msg, 48, titl end sub 呼び出す側で、 ErrMsg "タイトル", "なんちゃらエラー" と、指定すると、その文字をセットしたメッセージボックスが表示される。 【例】'** 2 つの数値を掛ける関数 function Kakeru (a as long, b as long) as long Kakeru = a * b end function 呼び出す側で、 dim kotae as long kotae = Kakeru (2, 3) と、指定すると、kotae には、6 がセットされます。 【例】'** 2 つの戻り値がほしい関数 function KakeruTasu (a as long, b as long, c as long,) as long KakeruTasu = a * b c = a + b end function 呼び出す側で、 dim kotaekakeru as long dim kotaetasu as long kotaekakeru = KakeruTasu (2, 3, kotaetasu) と、指定すると、kotaekakeru には 6 が、kotaetasu には 5 がセットさ れます。 【例】'** アドレス渡しの危険性 function Kakeru (a as long, b as long) as long KakeruTasu = a * b c = a + b a = 10 b = 20 end function 呼び出す側で、 dim dt1 as long dim kotae as long dt1 = 2 kotae = Kakeru (dt1, 3) と、指定すると、kotae には 6 が入るのはいいが、dt1 が 10 に変更さ れてしまう。(リテラルの 3 は、当然そのままだけど。) 実際には、こんな見え見えのミスはしないですが、いいかげんな名前をつ けると引数とローカル変数を間違えて更新したり、気づきにくいミスを起 こします。 ■引数省略指定(Optional) ・function、sub のパラメタ省略値の指定をするには、次のようにする。 public function test(a as long, Optional b as long = 100) as long ... end function ■再帰呼び出し ・関数内で、自分自身を呼び出すことを再帰呼び出しと言う。 クイックソートやヒープソートのロジックでよく使用する。 身近なところでは、フォルダのサブフォルダ内検索などに使用する。 次の例で、GetFld "c:\", fs と呼び出すと、c:\ の配下の全てのフォルダ を再帰検索する。(fs は、ファイルシステムオブジェクト) ・再帰呼び出しは、終了条件がなければ無限ループになる。 また関数コールにスタックを使用するので、度重なる再帰呼び出しでは スタックオーバーフローを招く可能性がある。 (32bits Windows では、スタックオーバーフローを経験したことはない。) Private Sub GetFld(dnm As String, fs As Variant) Dim fld As Variant Dim fc As Variant Dim fl As Variant '** フォルダ毎の処理 '** サブフォルダ再帰呼び出し Set fld = fs.GetFolder(dnm) Set fc = fld.subFolders For Each fl In fc GetFld dnm & fl.Name & "\", fs Next End Sub ■VB 基礎編資料
■VB 入門編資料
■VB ビジュアル編資料
■VB テクニック編資料