InterSystems IRIS ObjectScriptのClassMethodとVB.NETを接続するAPIの作り方

プログラムというのは「連動して動く」ことが自動化のカギであり、これが異なる処理言語である場合には「少なくとも一方の言語から、他方の言語の関数を呼び、処理結果を戻す」必要があります。ここではInterSystems IRISのプログラミング言語であるObjectScriptで作成したストアドプロシージャ(Stored Procedure)の[ClassMethod]で書かれた関数を、VB.NETから引数を渡して実行し、戻り値を得るいくつかのバリエーションについて示します。この記法を一度覚えてしまえば、あとはClass Referenceを見ながら、必要な引数と戻り値の型を身に着けていく段階に移行できます。


ケースを4つに分けます：
１・引数がなく、戻り値がないストアドプロシージャの呼び方
２・引数がなく、ResultSet型の戻り値があるストアドプロシージャの呼び方
３・引数があり、ResultSet型の戻り値があるストアドプロシージャの呼び方
４・引数があり、参照渡し型の戻り値がある(SQL型でない)ストアドプロシージャの呼び方

まず１、２から
１・引数がなく、戻り値がないストアドプロシージャの呼び方
２・引数がなく、ResultSet型の戻り値があるストアドプロシージャの呼び方

ObjectScript側の書き方：

```VB:User.MercForNLP
//Userネームスペースに、新規クラス名としてMercForNLPを作成する。%Persistentは、ディスクにデータを永続化する、という意味
Class User.MercForNLP Extends (%Persistent)
{
Property contentField as %String; //フィールドを記述する方法は、Propertyをつけて宣言する。最後に;が入る（ここだけ）

//メソッドに相当する、ClassMethodの書き方。StoredProcTest1, StoProcTest1 以外はお約束と思って可
ClassMethod StoredProcTest1() [ ReturnResultsets, SqlName = StoProcTest1, SqlProc ]
{

    #dim rs // ResultSet。ここで%Integerや％Stringなどの型を宣言してもよいが、宣言しなくてもVariableとして機能する（最初は型宣言を入れるとわかりにくいものも多いので、まず動くことを優先する）

   //関数はSet宣言をして使う。クラス名は##class()の中に記述し、新規インスタンスは%New()で宣言する。
   //ここでは、%library.Resultset型の変数rsを宣言し、そのResultSetが%iKnow.Queries.EntityQAPI:GetBySource(...)の戻り値を受ける。という動きを表している
    Set rs=##class(%Library.ResultSet).%New("%iKnow.Queries.EntityQAPI:GetBySource") 

    //ドメインIDが引数で必要なので、これを取得する。すでにAnalyzeMercというドメイン名を作成している（前の記事を参照）
    Set domId = $system.iKnow.GetDomainId("AnalyzeMerc")
	
    //重要：GetBySourceの実行で、引数を指定している。引数はドメインID、エンティティID、（省略可能な引数）、バッファの4つ。
    Set sc=rs.Execute(domId,i,,1000)
    //実行結果がrsに格納されたので、これをSQL型で呼べる内容に変換してセットする。（実際上、この処理で戻り値を出したことになる）
    //戻り値がないときは、この最後の関数を記述しない
    Do %sqlcontext.AddResultSet(rs) 
}
}
```

VB側の書き方：

```VB:Form1.Button1_Click
Imports InterSystems.Data.IRISClient
Public Class Form1
'例としてButton3が押されたときに処理するようなコードにしている
    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click

        'IRISCommectionクラスを使って、IRIS DBサーバにアクセスする
        Dim connection As IRISConnection
        connection = New IRISConnection
        'IRIS DBサーバに接続する基本的な書式。NameSpaceは、格納されているデータが存在するところを指定すること。yourpassとyourIDは各自の環境に合わせて設定したものに置き換えること
        connection.ConnectionString = "Server=localhost; Port=51773; " + "Namespace = TESTSAMPLES; " + "Password = yourpass; " + "User ID = yourID;"
        '接続コマンドを送り、通信を開始する
        connection.Open()
        'ClassMethodを呼び出すためのIRISCommandCkassを宣言する
        Dim Command As IRISCommand
        'IRIS DBからSQL形式でデータを読み取るためのIRISDataReaderを宣言する
        Dim reader As IRISDataReader
        '重要：ObjectScript側で設定した[]内の”一意の呼び名”でコールする（ClassMethodの名前そのものではないことに注意！）
        Command = New IRISCommand("SQLUser.StoProcTest3", connection)
        'コマンドの方がストアドプロシージャであることを指定している
        Command.CommandType = CommandType.StoredProcedure

        '関数のAPIコール。これによって、readerにAPI実行結果が格納される。
        reader = Command.ExecuteReader()
        'Command.ExecuteNonQuery()とすると、戻り値のないAPI実行ができる。その場合は以下のReader処理は不要。

        '重要：Reader.Read()とすると、読み出した表の行フォーカスを1行送るようなイメージになる。
        While (reader.Read())
            '読み出す項目はreader.Item("フィールド名")で指定する。ここではObjectScript側でcontentFieldを作っているので、これを呼び出すことができる。
            MsgBox(reader.Item("contentField") )

        End While

    End Sub
End Class
```

ObjectScript、VB.NETの記述が互いのどの項目に相当するかを矢印で示してみました。（引数のある場合。次回に続きます）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/262065/bc5ca47f-98b2-e232-6e45-3b169b4b2352.png)