VB2010 文字列の計算式で演算関数も対応するには?

解決


アンディ  2013-03-21 16:49:19  No: 148118  IP: [192.*.*.*]

VB.NET2010で、文字列の計算式の結果を求めるとき、四則演算は
「Microsoft.Jscript」や「Microsoft.Vsa」を使ったり、
ScriptControlを使ったりと、例はよく見かけるのですが、
演算関数(ExpやPowなど)も含めた文字列でも計算できるように
するにはどうすればよいでしょうか?

例  Dim mojiretsu As String = "150+12*Pow(10,2)"

ご存知の方、ご教授の程よろしくお願い致します。

編集 削除
魔界の仮面弁士  2013-03-21 20:01:11  No: 148119  IP: [192.*.*.*]

With CreateObject("ScriptControl")
  .Language = "JScript"
  MsgBox(.Eval("150+12*Math.pow(10,2)"))
End With

とか

With CreateObject("ScriptControl")
  .Language = "VBScript"
  MsgBox(.Eval("150+12*10^2"))
End With

ならできますが、それでは駄目ですか?


どうしても「Pow」にしたいなら、自作関数として組み入れるとか。

プロジェクトのプロパティで、[アプリケーション]-[アセンブリ情報]の
[アセンブリをCOM参照可能にする]を有効にしておいてください。

Public Class Andy
    Public Function Pow(a As Object, b As Object) As Object
        Return a ^ b
    End Function
End Class

Module Module1
    Sub Main()
        With CreateObject("ScriptControl")
            .Language = "VBScript"
            .AddObject("Andy", New Andy(), True)
            MsgBox(.Eval("150+12*Pow(10,2)"))
        End With
    End Sub
End Module

編集 削除
アンディ  2013-03-22 13:44:21  No: 148120  IP: [192.*.*.*]

魔界の仮面弁士さん、アドバイスありがとうございました!
ScriptControlで対応できるのですね。

最終的には、文字列の一部を外部変数用に割り当てて、
教えて頂いた関数で変数を代入して、うまくいきました。

編集 削除
魔界の仮面弁士  2013-03-22 22:18:30  No: 148121  IP: [192.*.*.*]

> ScriptControlで対応できるのですね。

「Microsoft.Jscript.DLL」でもできますよ。


Imports System.CodeDom.Compiler

Module Module1

    Sub Main()
        Dim funcList = <![CDATA[
package Andy
{
  public class Sample
  {
    //--- evalを公開
    public function EVal(expression:System.String):System.Object { return eval(expression); }

    //--- 独自関数
    public function Pow(a, b) { return Math.pow(a, b); };
    public function Exp(a) { return Math.exp(a); };
  }
}
]]>.Value

        Using js As New Microsoft.JScript.JScriptCodeProvider()
            Dim cc = js.CreateCompiler()
            Dim res = cc.CompileAssemblyFromSource(
                New CompilerParameters() With {.GenerateInMemory = True}, funcList)

            If res.Errors.HasErrors Then
                Dim msg = String.Join(vbNewLine, _
                            res.Errors.OfType(Of CompilerError)().Select(Function(c) c))
                MsgBox(msg, MsgBoxStyle.Exclamation Or MsgBoxStyle.SystemModal)
                Return
            End If

            Dim andySample = Activator.CreateInstance(res.CompiledAssembly.GetType("Andy.Sample"))
            Dim EVal = Function(expression As Object)
                           Return CallByName(andySample, "EVal", CallType.Method, expression)
                       End Function

            MsgBox(EVal("150+12*Pow(10,2)"),
                   MsgBoxStyle.Information Or MsgBoxStyle.SystemModal)

            MsgBox(EVal("Exp(123.45)"),
                   MsgBoxStyle.Information Or MsgBoxStyle.SystemModal)

            MsgBox(Math.Log(EVal("Exp(123.45)")),
                   MsgBoxStyle.Information Or MsgBoxStyle.SystemModal)

        End Using
    End Sub

End Module

編集 削除
アンディ  2013-03-26 16:49:24  No: 148122  IP: [192.*.*.*]

魔界の仮面弁士さん、更なる書き込み、ありがとうございました。

Microsoft.Jscript.DLLというのもあるのですね。初心者の私には
使いこなすのにまだ難しいですが、勉強になります。

編集 削除
魔界の仮面弁士  2013-03-26 19:34:33  No: 148123  IP: [192.*.*.*]

> Microsoft.Jscript.DLLというのもあるのですね。

あれ? この DLL は初見ですか?

最初の質問時には、四則演算の時に使っておられたかのような
記述がありましたが…。


>> VB.NET2010で、文字列の計算式の結果を求めるとき、四則演算は
>>「Microsoft.Jscript」や

編集 削除