引数付きプローシージャと変数(5-1)::システムトレード完全攻略(エクセル活用術)

システムトレードのトップへ > VBA > VBA入門  >引数付きプローシージャと変数(5-1)

引数付きプローシージャと変数(5-1)

1つの大きなプロシージャよりも幾つかに部品化することの利点を前にお話しました。今回はVBAを理解する最大の障害といわれている引数付きプロシージャと変数の宣言場所の説明です。



ここで再度、第2回で用いた料理人の師弟関係を再度使って部品化された「プロシージャ」のイメージのおさらいです。下図は前回の時に使ったイメージ図です。天ぷら御前という注文をうけた店主が天ぷらをあげながら、店員Aに小鉢とご飯のセットを指示し、店員Bのはサシミ盛を作るように指示している関係図です。思い出しました?



エクセルdeシステムトレード



下図が今回の「引数付きプロシージャ」がある場合のイメージ図です。違いが分かるでしょうか?



プログレスバーdeシステムトレード



目立つように赤字表示された、「イカそうめん抜き」が唯一違うところです。つまり、親方が弟子Bに今度の天ぷら御膳の刺身盛りは「イカそうめん抜き」にしろとオプションをつけて命令しています。普段は刺身盛りの中にイカそうめんは入っているのですが、注文したお客さんが要望があり、イカそうめん抜きにする感じです。命令するときにオプション(引数)というものをつけて、子(弟子)プロシージャを呼びだしています。これをVBAでは、「引数付きプロシージャを呼びだす」といいます。コードで書くとこんな感じです。


Sub 親方()
海老3本揚げる 
ナス1本揚げる
かき揚げ1つあげる
白身魚を揚げる
Call 弟子A ’弟子Aを呼ぶ
Call 弟子B(イカそうめん抜き) ’弟子Bを呼ぶ
End Sub

Sub 弟子A()
ご飯を盛りつける
小鉢を盛りつける
End Sub

Sub 弟子B( イカそうめん抜き
刺身盛りを作る
刺身盛りを御膳にセットする
End Sub


親方プロシージャは弟子Bを呼びだす時に引数(オプション)をつけて指示をし、弟子Bはその引数(オプション)を受け取って、普段の作業+αをするという感じです。次は、実際に機能するコードを使ってさらに詳しく説明していきます。

あったら便利なプログレスバー

 

今回は「プログレスバー」を作りながら、引数付きプロシージャの作り方と使い方を説明しようかなと思います。まず、「プログレスバー」についての説明です。 時間の掛かる処理を実行している時には、「今動いてるのか?止まっているのか?」という思いでユーザーは不安になるものです。そこで、その不安を解消するとともに、「どの位進んだのか」を知らせる為のインターフェースとして使われるのが「プログレスバー」になります。「プログレスバー」を作る方法は色々な方法が考えられますが一番効果的で再配布できる利点を考えると、ユーザーフォームを使った自作プログレスバーになります。以下のプロシージャ2つが親プロシージャと子プロシージャの主要プログラム部分です。

ファイルをダウンロード





プログレスバー by システムトレード




VBA by システムトレード



図1のプロシージャはモジュール「テスト」の中に入っています。「テスト1」は実行すると図2の矢印分の数字が1秒ごとに1、2、3と増えていくプログラムです。

1.プロシージャの内容を詳しく見ていきます。まず、「テスト1」が実行されると、セルA1に1が記入されます。それが終わると子プロシージャーの「progress_bar」を引数「5」と「1」を付けて呼び出します。意味は定数「5」と「1」を渡すから、「progress_bar」は「5」と「1」を使って仕事しなさい。」という命令文です。先ほどの「イカそうめん抜き」の部分が「5」と「1」に変わっただけです。

2.数字「5」と「1」を受け取った「progress_bar」は自分の仕事であるプログレスバーの進捗状況を数字「5」と「1」で表す作業を始めます。全体が「5」で今「1」が終わったのですがら、プログレスバーは全体の5分の1進ませて、親プロシージャに命令を返します。

3.子プロシージャから作業の終わりをつげられたので、「テスト1」は次の「Sleep(1000)」という命令を実行します。「これは今から1秒間休め」という命令です。

4.次に、また初めに戻り、セルA2に数字の2を記入 → 「progress_bar」に引数「5」と、今度は「2」を付けて呼び出し → progress_bar」は数字の「5」と「2」を使い進捗状況を表示 → 親プロシージャに戻りスリープ1秒間。これをあと3回繰り返すとプログラムは終了します。

5.親プロシージャが引数付きで子プロシージャを呼び出す(命令する)時は、

Call 子プロシージャ名 (引数1、引数2、引数3・・・・)

になります。括弧内に引数1、2、3・・・という感じで、子プロシージャに渡す引数を指定します。尚、

子プロシージャ名 引数1、引数2、引数3・・・・

でも同じ結果になります。よく見かけるのはこの「Call」がないバージョンですが、親子関係がはっきりするのでなれるまでは「Call」付きをお薦めします。

6.一方、子プロシージャは、

Sub 名前〇〇〇〇(変数 as データ型、変数 as データ型 ・・・・)

とSubの括弧内に親とやり取りしたい数字を入れるための変数を宣言します。括弧内で変数のデータ型を指定するのですが、ここで注意点があります。親と子で渡す引数のデータ型は必ず同じにします。揃えないとエラーになります。図1の赤く囲った部分を比較してみてください。親プロシージャの呼び出し方と子プロシージャの宣言部分の文法がほぼ同じで分かりやすいと思います。呼び出すときは呼び出したいプロシージャに引数を付けて呼び出し、呼び出される方は、渡される引数を受け取るための変数をタイトル部分をあらかじめ用意しておきます。



次のプロシージャを見てください。

プログレスバー by システムトレード


先ほどの「テスト1」とこの「テスト2」の実行結果は同じです。違うのは、今回は親プロシージャに変数とループを使っている点です(ここではループの使い方は省略します)。特に注目してほしいのは、親が子プロシージャを呼び出すときに、引数が変数になっている点です。

Call progress_bar(total, i)


の「total」と「i」のことです。引数が今度は「定数」ではなく、「変数」に変わりました。図3のように引数「total」と変数「total」、引数「i」と変数「i」を矢印で指すと、まるで引数「total」が変数「total」に渡ったような錯覚に陥りますが、渡ったのは引数「total」に代入された「定数」だということを確認しておいてください。結構ここで誤解が生じ、引数について混乱する原因になっています。引数「total」と変数「total」が同じである必要は全くありません。例えば親プロシージャの引数「total」を「総数」、引数「i」を「カウント数」に変えても数字は子に渡ります。

Sub テスト2()
Dim カウント数 As Long
Dim 総数 As Long

Sheets(1).Select

総数 = Cells(2, 1).Value '実行回数を決める変数

プログレスバー.Show (vbModeless)

For カウント数 = 1 To 総数

Cells(1, 1).Value = カウント数 'セルA1にiを代入

Call progress_bar(総数, カウント数) 'progrees_bar に変数「total」の値と
'変数「i」の値を付けて呼び出し


Sleep (1000) '1秒寝るZZZZ

Next カウント数 'ループします。

Unload プログレスバー
End Sub


引数と変数は同じである必要がないのは、上記のプロシージャがエラーなく働くことから明らかです。では、どうやって2つある引数の区別を子プロシージャはしているのでしょうか?答えは引数の表示順で判断しています。つまり「前にある引数(総数)は、子プロシージャ内で宣言した前の変数(total)に渡すのだなとVBAは判断し、後ろにある引数(カウント数)は、後ろにある変数(i)に渡すのだなと判断します。


さて、使い方の基本は終わった訳ですが、最後に、なぜ引数を付けてまでも分ける必要があるのかい再度考えてみます。まず、もし、プログレスバーを部品化しなかった場合は図1の子プロシージャを呼び出す5箇所をすべてを以下に置き換える必要があります。


j = i / total * 100 'iを100あたり幾らかを計算した変数がj

With プログレスバー
.Label2.Caption = Int(j) & "%"
.Label1.Width = .Label2.Width * j / 100
End With


分かると思いますが、かなり無駄な作業です。また、「プログレスバー」は他のプロシージャでもたびたび使うので、部品化しておかないと、他のプロシージャでも同じことを繰り返す必要があります。これも同じように大変な無駄です。しかし、部品化しておけば呼ぶだけなので作業がかなり短縮されます。無駄に長いと後で仕様変更したときに、また他人が見た時に、なんのためのプログラムなのか理解するのに時間がかかります。それを少しでも防ぐためにもできるだけ細分化し、そのプログラムが何であるか、すぐ分かるようにするためにも引数付きプロシージャの構造は確実に理解しておきたいものです。


セルレーダー最新版ダウンロードした(^▽^)?

人気ブログランキングへ





1位取れたら未公開プログラム沢山吐き出すので応援のポチ2つしてね(≧ω≦)

投稿者 システムトレーダー壱式 : 2008年06月14日 04:48



トラックバック

このエントリーのトラックバックURL:
http://systemtrader.info/cgi/mt/mt-tb.cgi/87

コメント

コメントしてください




保存しますか?


//-->