さまよう大アリクイ

横浜市に住む。ホームページを作っていたりするが、最近滞り気味。

OpenOfficeのプログラミング:コンボボックスのリストを変更

データベースの入力をする際に、過去と同じ値を入れることがあります。コンボボックスはリストから入力値を得られるので同じ値を入れるときに使えます。リストの値は、別の項目に依存するのもあると思います。例えば、装置名に続けて部品名を入力れるときや、チーム名に続けて選手名を入力する場合や、RFC番号に対して、翻訳者名を入れる場合です。

以下、Machineフィードの値に応じてPartsフィードのコンボボックスのリストを変更するマクロのサンプルです

Sub SetParts

Dim oDoc As Object

Dim oForm As Object

Dim Machine As Object

Dim Parts As Object

Dim Connection As Object

Dim Sql As String

Dim Statement As Object

Dim ResultSet As Object

Dim len As Integer

Dim Names(0) As String

Dim i As Integer

' 各種オブジェクト取得

oDoc = ThisComponent

oForm = oDoc.getDrawPage().getForms().getByName("MainForm")

Machine = oForm.getByName("Machine")

Parts = oForm.getByName("Parts")

Connection = oForm.ActiveConnection

' Machineが空なら、コンボボックスのリストは空に設定

If Machine.Text = "" Then

Parts.StringItemList = Array()

Exit Sub

End If

' データベースアクセス

Sql = "SELECT ""Parts"" FROM ""hogeTable"" WHERE ""Machine"" = '" + Machine.Text +"'"

Statement = Connection.createStatement()

Statement.ResultSetConcurrency = 1007 ' 更新を許可しない

Statement.ResultSetType = 1004 ' 全ナビゲーションを許可、オリジナルデータへの変更は記録しない

ResultSet = Statement.executeQuery( Sql )

' 結果が空なら、コンボボックスのリストは空に設定

If IsNull(ResultSet) Then

ResultSet.Close()

Statement.Close()

Parts.StringItemList = Array()

Exit Sub

End If

' 結果の行数を得る

ResultSet.last()

len = ResultSet.getRow()

ResultSet.first()

' 行数ゼロなら、コンボボックスのリストは空に設定

If len <= 0 Then

ResultSet.Close()

Statement.Close()

Parts.StringItemList = Array()

Exit Sub

End If

' 配列変数サイズを変更

ReDim Names(len-1) As String

' 配列変数にSQLの結果をコピー

i = 0

Do

Names(i) = ResultSet.getString(1)

i = i + 1

Loop While ResultSet.next()

' データベースアクセス終了

ResultSet.Close()

Statement.Close()

' ドロップダウンリスト設定

Parts.StringItemList = Names

End Sub

このマクロは、メインフォームの「レコード置換後」イベントや、Machineコントロールの「更新した後」イベントに登録して、使用します。

Statement.ResultSetConcurrency = 1007』は、もしかしたら少しは早くなるかもしれない、と思っての設定です(関係ないかも)。『Statement.ResultSetType = 1004』は、ResultSet.last()やResultSet.first()を使うために必要そうだったので、設定しました。

ResultSet.last() : len = ResultSet.getRow() : ResultSet.first() 』の部分で、結果の数を数えています。ファイルサイズを調べるときに使うのと同じ方法ですが、結果を逆戻りできないデータベースでは、ResultSet.first()がエラーになるかもしれません(もしかしたら、Statement.ResultSetTypeの設定時点でエラーかな?ResultSet.first()の戻り値をチェックすべきなのかな?)。BASEのHSQLDBではOKみたいです。

SQLのSELECTの結果がなにもなしの場合、最初は『 If IsNull(ResultSet) Then 』の検査だけで、

OKと思っていたのですが、len = ResultSet.getRow()の結果が1以上にならない場合があるようなので、『If len <= 0 Then』のチェックもしています。

フォームの入力フィールドの値ですが、テキスト入力フィールドだと、hogehoge.Text で読み書きできますが、数時入力フィールドだと、hogehoge.Value になります。最初、気がつかず、エラーになってしまいました。