パソコン活用研究5番街(Visual Basic、Excel(VBA)、BASIC プログラミング研究)

         プロシージャ(Sub, Function)とデータの受け渡し

------------------------------------------------------------------------------------
VBにしろ、VBAにしろ、コードはプロシージャに記述することになります。これはVB,VBAが旧BASIC
と大きく違う(進化した)点です。今回はプローシージャについて基本的なところをまとめてみました。
------------------------------------------------------------------------------------

(1) VB,VBAのプロシージャ
VB,VBAには以下の2つのプロシージャがあります。

T) Sub プロシージャ
  Sub

  End Sub

U) Function プロシージャ
  Function

  End Function


(2) プロシージャと旧Basicのサブルーチン(Gosub)
変数のスコープのところで、変数には、ローカル変数、モジュール変数、グロバル変数があると、説明
しました。全ての変数をグローバル変数としてしまえば、Subプロシージャの使い方も、旧Basicの
Gosub ......... Return によるサブルーチンにかなり近い感じになります。

例えば 変数X (=10)を2倍にして返すプログラムを考えます。
旧BAISC VB,VBA


10 X=10      
20 gosub 50
30 end

40 'sub routin
50 X=X*2
60 return
public X as integer

Sub main()
X=10
twise
End Sub

Sub twise()
X=X*2
End Sub

まあ、なんとなく似た感じのコーディングですね。
でも、なんでもかんでもグローバル変数にしてしまっては、進化したVB,VBAのよさをスポイルしてしまいます。
ではVB,VBAの進化にふさわしい使い方でコーディングしてみましょう。


(3) Subプロシージャ (参照渡し)
先に書いたように、プロシージャを呼ぶには、単にプローシジャ名を書けばO.K.です。

今回は、データも呼び出すプロシジャに渡します。データも渡す場合は
プロシージャ名 データ  (ここでは、 twise x)
と記述します。

呼び出される方は
Sub プロシージャ名(変数 as 変数型)
と記述します。
ここでは Sub twise(a as integer) です


それでは、上のプログラムをほんの少し拡張して、VBでテキストボックスに入力された整数を2倍にする
プログラムを作ってみます。フォームの構成は、テキストボックス1つに、コマンドボタン1つです。
コマンドボタンを押すと(Sub Command1_Click)、プロシージャtwiseを呼び、twiseプロシージャで
2倍にするという簡単なプログラムです。


'
最初はFORM等のプロパティ         

VERSION 4.00
Begin VB.Form Form1 
   Caption         =   "Form1"
   ClientHeight    =   1635
   ClientLeft      =   1140
   ClientTop       =   1515
   ClientWidth     =   3345
   Height          =   2040
   Left            =   1080
   LinkTopic       =   "Form1"
   ScaleHeight     =   1635
   ScaleWidth      =   3345
   Top             =   1170
   Width           =   3465
   Begin VB.CommandButton Command1 
      Caption         =   "twise"
      Height          =   375
      Left            =   1800
      TabIndex        =   1
      Top             =   120
      Width           =   1335
   End
   Begin VB.TextBox Text1 
      Height          =   375
      Left            =   1920
      TabIndex        =   0
      Top             =   840
      Width           =   1215
   End
   Begin VB.Label Label1 
      Caption         =   "値"
      Height          =   255
      Left            =   1920
      TabIndex        =   2
      Top             =   600
      Width           =   855
   End
End
Attribute VB_Name = "Form1"
Attribute VB_Creatable = False
Attribute VB_Exposed = False


' ここからがコードの本体
'


Sub twise(a As Integer)
a = a * 2
print"a: ";a
End Sub


Private Sub Command1_Click()
Dim x As Integer
x = Val(Text1.Text)
twise x
Print "結果"; x
End Sub

FORM上にtwiseプロシージャのローカル変数aと、twise呼出し後のxを出力させています。
実行結果は以下の通り。
5を入力した結果、xは10になりました。
プロシージャtwiseでは変数aに5を受けて、2倍にしています。
aは当然10になりますが、その結果、xも10になりました。どうしてでしょうか。
実は、これが参照渡しといわれる、データの受け渡しの秘密の部分なのです。
参照渡し、とは、データの格納されている場所(アドレス)を渡す方法です。

少し具体的に言えば、プロシージャtwiseが呼び出された時、変数xの格納されているアドレス
が変数aの参照すべきアドレスとしてtwiseに渡されたのです。
すなわち aの参照するアドレス = xの参照するアドレス、となったわけです。
したがって、aの値を変更する = xの値を変更する、というわけです。

xもaもともにローカル変数です。このように参照渡しを使えば、グローバル変数を使わなくても、
プローシージャ間でデータの受け渡しができるわけです。
少し、VB,VBAの進化した部分を使ったプログラムとなりました。
ただし、この例のように、aの変更がxの変更につながってしまいますので、変数の独立性という
点はやや難ありです。参照渡しを使う場合の注意点です。


(4) Subプロシージャ (値渡し)
今度は、値渡しをみてみます。
値渡し、とは、データのコピーをプロシージャに渡す方法です。

値渡しでは、プロシージャの呼び出しは、参照渡しと同じです。
プロシージャ名 データ
と記述します。

呼び出されるプロシージャの方は、変数名の前にByvalをつけます。(”値によって”の意)
Sub プロシージャ名(Byval 変数 as 変数型)

とりあえず、twiseが値渡しになっている以外、上と同じVBプログラム(Byvalがついて、
いるだけ)をみてみましょう
プロパティの部分は省略します


Sub twise(ByVal a As Integer)
a = a * 2
print"a: ";a
End Sub


Private Sub Command1_Click()
Dim x As Integer
x = Val(Text1.Text)
twise x
Print "結果"; x
End Sub

実行結果です

5を入力して、twiseを呼びました
aは10になりましたが(当然です)、xは5のままです。aの変更の結果が、xに反映されていません。
これは、値渡しが参照渡しと違う方法で、データを受け渡ししているためです。

冒頭で、値渡しは、データのコピーを渡す、と書きましたが、下図を見てください。

xのダータ格納場所   5
   
   
   
aのデータ格納場所   5  <−−−5がコピーされた

twiseが呼び出されると、xの値である5がコピーされて、aのデータ格納場所に5が置かれます。
プロシージャtwiseでaが2倍されると、次のようにaは10になります。しかし、aとxの格納場所は互いに
別々で独立していますので、xには反映されません

xのダータ格納場所   5
   
   
   
aのデータ格納場所   10 

と、これが値渡しです。この方法では、変数の独立性がきわめて高くなります。
なお、VB,VBAではデフォルトでは参照渡しとなりますが、C言語では値渡しがデフォルトです。

(5) Functionプロシジャ
Functionプロシージャは、旧BASIC流にいうと関数に近い(ユーザー定義関数というのがあった)もの
と言ってもいいでしょう。
Subプロシージャとの違いは、戻り値を持つということです。

Functionプロシージャの呼び出しは
変数 = プロシージャ名(データ)
となります。
Functionプロシージャからの戻り値があるので、その戻り値を変数に代入します。
渡すデータは (   ) で囲みます

呼び出される方は
Function プロシージャ名(変数 as 変数型) as 変数型
と記述します。
2番めの変数型はFunctionプロシージャの戻り値の型です。

それでは、上と同じく、2倍にして返すプログラムをFunctionで作ってみます。
プロパティ部分は省略します

Function twise(a As Integer) As Integer
twise = a * 2
End Function


Private Sub Command1_Click()
Dim x As Integer, result As Integer
x= Val(Text1.Text)
result = twise(x)
Print "結果"; result
End Sub


result = twise(x) でFunction twiseに変数xを渡し、戻り値をresultに受けています。
なお、Functionプロシージャでの戻り値は、プロシージャ名と同じ名前の変数に代入します。
ここではtwiseです。
Functionプロシージャでも、値渡し、参照渡しの問題はSubプロシージャと同じことです。

(6) EXCELにおけるFunctionプローシジャの特例
EXCELではFunctionプロシージャで引数を持たないばあい、セルの数式として使えるという、特例があり
ます。
セルA1の値を2倍にするFunctionプロシージャ

[Moduleシート]
Function twise()
twise=cells(1,1)*2
End Sub


ワークシートのセルB1にプロシージャ名を式として書いて、リターンキーを押します

  A B C
1 10 =twise()  
2              
3      

すると,下記のとおりになります

  A B C
1 10 20      
2              
3      



TopPage > Visual BasIc&Excel活用研究目次