フォームのテキストボックスに入力したサブルーチン名(ストリング)と同等名のサブルーチンを記述しておき、これを実行するには、プログラム内でどの様な操作をしたら良いでしょうか。
サブルーチンというのは、GoSub / Return ステートメントで使われる物を
指しますが、その点は大丈夫ですよね。
で、サブルーチンを文字列指定で呼び出すのは無理です。
On〜GoSubステートメントによる分岐ならば可能ですけれども。
代わりに、フォームやクラスに Public Sub プロシージャとして
実装するというのはどうでしょう。これならば、「CallByName」を
使う事で、文字列指定で呼び出せるようになります。
早速の回答ありがうございます。
サブルーチンはPublic指定にしております。
具体的に、「CallByName」とはどの様に使うのでしょう。
FormのTextに例えばサブルーチン名 Kaisan(X,y,z) (()内は引数)が記述されていた場合、テキスト値としてプログラム上の変数に同名を持ってきます。変数は
K="Kaisan(X,y,z)"となっているでしょう。ここでサブルーチンを呼び出すには
Call K ではエラーとなってしまいますが、この後の記述がわかりません。
引数はやはりフォーム上から持って来て、変数X=0,Y=1など与えます。
> 具体的に、「CallByName」とはどの様に使うのでしょう。
ヘルプの使用例だと分かりにくいかもしれませんね。
たとえば、このようになります。
'--------------------
Option Explicit
Private Sub Form_Load()
Text1.Text = "Method1"
Text2.Text = "Method2"
End Sub
Private Sub Command1_Click()
CallByName Me, Text1.Text, VbMethod
End Sub
Private Sub Command2_Click()
CallByName Me, Text2.Text, VbMethod, "引数データ"
End Sub
'==== サンプルメソッド ====
Public Sub Method1()
MsgBox "メソッド1", vbInformation, "Method1"
End Sub
Public Sub Method2(ByVal arg As String)
MsgBox arg, vbInformation, "Method2"
End Sub
'--------------------
> FormのTextに例えばサブルーチン名 Kaisan(X,y,z) (()内は引数)が記述されていた場合、
変数ではなく、「12345」や「"ABCD"」などのリテラルで指定することを検討してください。
もしもどうしても変数が必要なら、それらがどの変数かを示す必要があります。
たとえば、その変数 X や Y がフォームモジュール上で
Option Explicit
Public X As String
Public Y As Integer
と書かれていれば、これは
Private Sub Form_Load()
X = "あいうえお"
Y = 12345
End Sub
Private Sub Command1_Click()
'変数名 X や Y を文字列で指定して取得
Debug.Print CallByName(Me, "X", VbGet)
Debug.Print CallByName(Me, "Y", VbGet)
End Sub
などのようにして値を得ることができます。
他のフォーム(あるいはクラス等)にある変数の場合は、Me の部分を書き換えてください。
(標準モジュール上の変数や、非Public な変数には、CallByName を使えません)
先のコードと組み合わせれば、たとえば Call Method2(X) を文字列指定するために
Dim methodName As String
Dim varName As String
methodName = "Method2"
varName = "X"
Dim argValue As String
argValue = CallByName(Me, varName, VbGet)
CallByName Me, methodName, VbMethod, argValue
といった処理になりますね。
> サブルーチンはPublic指定にしております。
それは「サブルーチン」ではなく、「Sub プロシージャ」と呼ばれる事が多いかと。
<以下蛇足>
QuickBASIC 時代の名残から、Function プロシージャを「関数」と表記し、
Sub プロシージャを「サブルーチン」と表記する場合もありますが、
現在では サブルーチン(subroutine) という表現は減ってきています。
なお、ヘルプの「GoSub...Return ステートメント」や、その「使用例」の項目では、
Sub プロシージャとサブルーチンを明確に使い分けています。
「CallByName Me」の具体的使用方法を丁寧に紹介頂き本当にありがとうございます。
私には、これが何なのかサッパリ理解できませんでしたが、MicroSoftWebサイトで関数であることを知りました。VB5を使っていることと、未熟者であることで理解出来なかった物と思います。VB6では同関数が追加されているようですが、VB5でも同様な事は出来るのでしょうか。また、この関数をAccess97のVBA等に導入する事は可能なのでしょうか。
バージョンは最初に書いてくださいませ。(泣)
先に書いた内容がゴッソリ無駄になってしまいます。
> MicroSoft
MicroSoft ではなく、
Microsoft だったりします。
> VB5でも同様な事は出来るのでしょうか。
できないので、たとえば
If S = "Method1" Then
Call Method1
ElseIf S = "Method2" Then
Call Method2
ElseIf S = "Method3" Then
Call Method3
といった方法になってしまうでしょう。
もしくは Microsoft Scripting Control を使うか、ですね。
こちらであれば、メソッドや変数自体は VBScript で記述して、
それを VB5 から利用するといった運用が可能です。
(VB5 側のメソッドを VBScript から呼び出させる事もできます)
> また、この関数をAccess97のVBA等に導入する事は可能なのでしょうか。
ここでいう「等」とは、どの範囲を指しているのでしょうか?
とりあえず、Access 97 VBA に限って言えば、
Public Function Method1(ByVal a As Integer, ByVal b As Integer) As Integer
Method1 = a + b
End Function
を呼び出すために、
'579 が得られる
Debug.Print EVal("Method1(123, 456)")
といったコードを利用できます。
VBのバージョンを先に記すべきでした。
>先に書いた内容がゴッソリ無駄になってしまいます。
無駄にはしておりません。しっかり備忘録ファイルに頂きました。
VB5ではフォームで与えたサブルーチン名に対し、サブルーチンを呼び出すテーブルが必要なことが分かりました。(本当はこれを記述したくは無かった)
VB6では「.... CallByName Me, methodName, VbMethod, argValue」さえ記述しておけば、サブルーチンの追加に対し、サブルーチン呼び出しテーブルの追加、変更等の必要は無いと理解しました。
Access 97 VBA のEVal関数では変数部分をリテラルで与える必要がある様で、ひと工夫いるのでしょう。
色々、ありがとう御座いました。
ツイート | ![]() |