2009-07-13 29 views
17

VBAの関数には特別な型はありません。 Excel VBAで関数の引数として関数を追加する方法を見るのは難しいです。私が達成しようとしています何excel vba:特殊型 - 関数の引数としての関数

次のようなものされています。現在、私はすべて自分自身を繰り返すことなく、特定の機能への1回の呼び出しではほとんどの機能のグループを持っている

function f(g as function, x as string) as string 
     f = g(x) 
end function 

答えて

13

コードから、関数gは文字列パラメータをとり、文字列を返します。 IStringFunction

はその後
Public Function Evaluate(ByVal s As String) As String 
End Function 

、例えば機能のカップルを作成します。

クラスモジュール:私はあなたがこのように、すべての機能がサポートするインタフェースの定義として動作するようにIStringFunctionと呼ばれるクラスモジュールを作成することをおすすめ

クラスモジュール:HelloStringFunction

Implements IStringFunction 

Public Function IStringFunction_Evaluate(ByVal s As String) As String 
    IStringFunction_Evaluate = "hello " & s 
End Function 
このインタフェースを実装します

クラスモジュール:GoodbyeStringFunction

Implements IStringFunction 

Public Function IStringFunction_Evaluate(ByVal s As String) As String 
    IStringFunction_Evaluate = "goodbye " & s 
End Function 

...そして最後に、いくつかのテストコードが機能を発揮するために:

(標準)モジュール:テスト

Sub Test() 

    Dim oHello As New HelloStringFunction 
    Dim oGoodbye As New GoodbyeStringFunction 

    MsgBox Evaluate(oHello, "gary") 
    MsgBox Evaluate(oGoodbye, "gary") 

End Sub 

Private Function Evaluate(ByVal f As IStringFunction, ByVal arg As String) As String 
    Evaluate = f.Evaluate(arg) 
End Function 

注意インターフェイスを実装しているクラスは、だけでなく、上記の例のように<Interface>_<Method>というメソッドを持たなければならないが期待通りです。

VBAはそれがインタラクティブな言語にルーツのしているので、それは常にテキストを実行する能力があったsimple demoまたはintermediate demoここ

+1

これは、彼がまだ各クラスに対して別々の評価関数を記述する必要があるためです。 – Treb

+0

@トレブ:多分私はその質問を理解していないかもしれませんが、あなたが何を意味するのか分かりません。各クラスは異なる関数を表しますので、もちろん別の評価関数を持たなければなりません!たぶん、問題が再表明される可能性があるなら、それはもっと明確になるだろう。 –

+0

こんにちは、これは正しい答えだと思います。これは、VBAにインターフェイスが存在することを、私は知らなかった、oo-languagesで行う方法です。私のせいです。私はこのテクニカルを小さなjava *で初めて見たことがあります。しかし、私は提案された解決策をテストしなければならない。現時点では、インターフェイスを実装しないというエラーメッセージが表示されました。 公開機能はブール エンド機能として(バリアントとしてByVal TMP)を適用 --- を実装IBooleanFunction 公開機能適用(ByValのTMPバリアントとして)ブールとして は= Application.IsText(TMP) エンド機能 –

15

をダウンロード:

function f(g as string, x as string) as string 
     f = application.run(g,x) 
end function 

MyStringA = f("functionA",string1) 
MyStringB = f("functionB",string1) 
+0

これは素晴らしいですが、実際にスコープが行くまで関数を渡すのと同じだとは思わない... – epeleg

+0

これはドープです!理想的なスコープの有無にかかわらず、私はそれを取るでしょう。 – grisaitis

+0

Excel VBA 2010では、次の構文でコンパイルエラー "Expected:End of statement"が返されます。パラメータはそれらの周りにかっこを必要とします:f = Application.Run(g、x) –

0

をそれのように関数を渡すことが可能です引数を入力し、その後の動作を正確に取得しますが、これは少しハッキリです。これは

はあなたの関数

Public Function sayHi(ByVal s As String) As String 
    sayHi = "Hi " & s 
End Function 

書き出し、それを含むクラスmyFunctionを作成し、開いて、クラスのデフォルトプロパティを活用することによって達成されます。

:あなたは今、それはこのように見えるように、ラインAttribute Value.VB_UserMemId = 0を追加し、どこかのファイルで、その下に

Public Function sayHi(ByVal s As String) As String 

あなたの関数を定義する行が表示されるはずのテキストエディタ

でCLSファイル

Public Function sayHi(ByVal s As String) As String 
Attribute Value.VB_UserMemId = 0 
    sayHi = "Hi " & s 
End Function 

ここでは、sayHiをクラスのdefault propertyとマークしています。今、あなたはclass.function(args)

保存改正ファイルではなく、単独のクラスオブジェクトclass(args)によって関数を呼び出して、あなたのVBAプロジェクトにインポートすることができ

テストモジュール

Sub test() 
    Dim parameterFunction As Object   'this is what we'll be passing to our routine 
    Set parameterFunction = New myFunction 'create instance of the function object 
    MsgBox f(parameterFunction, "Greedo") 
End Sub 

Function f(ByVal g As Object, ByVal x As String) As String 
     f = g(x) 
End Function 

* NB、このどのような関数を渡すことができます。代わりにByVal g As IStringFunctionを指定して、適切なインターフェイスを持つサブセットのみを取得することもできます。Gary McGill's answer

関連する問題