ブログの説明

学校に通わないで学んだことを記しています。間違っているところが何かありましたらご指摘下さると幸いです。コメントに対する返信が遅れる可能性があります。その場合は申し訳ありません。

このブログではサイドバーに広告を表示しています。このブログ内の投稿記事を検索するには右上の拡大鏡のアイコンを、アーカイブやラベル付けから投稿記事を閲覧するには左上の三重線のアイコンをクリックして下さい。

数式の表示にはMathJaxを利用させていただいています。数式の表示のためにJavaScriptが有効である必要があります。そうでない場合、訳の分からないLatexのコードが表示されます。幾何学図形やチャートの表示にはHTML5 CanvasやGoogle Chartを使用しています。その表示のためにもJavaScriptが有効である必要があります。

LibreOffice Basic ユーザーが定義するデータ型(構造体)

ユーザー定義のデータ型(構造体)

この投稿ではLibreOfficeかApache OpenOfficeのマクロ言語であるBasicにおいてユーザー定義のデータ型を宣言する2種類の方法について記す。

ユーザー定義のデータ型はカスタム・データ型と呼ばれていることもある。それは型の違いに関わらず1つ以上の変数をまとめて1つのデータ型とし、そのデータ型に名前を付けたもの。その要素となる変数はメンバーと呼ばれている。

ユーザー定義のデータ型はC言語で言うところの構造体、Pascalで言うところのレコードによく似ている。Pythonの辞書にも似ているが、辞書はハッシュ・テーブルの一種であると解釈されるものかもしれない。

構造体やレコードとクラスとの違いは、構造体やレコードがデータ・プロパティだけを持ち、コード・プロパティを持たないこと。データ・プロパティとは単にプロパティと呼ばれていたりメンバー変数と呼ばれていたりするもの。コード・プロパティとはメソッドと呼ばれていたりメンバー函数と呼ばれていたりするもの。

LibreOffice BasicまたはApache OpenOffice Basicでは、ユーザー定義のデー型(構造体)を次のような2種類の方法で定義することができる。

  • Type宣言を用いる方法。
  • UNO(Universal Network Objects)を利用する方法。

Type宣言を用いて構造体を定義

モジュール内のサブルーチンの外にType宣言を記述することによって構造体を定義することができる。

Type宣言はサブルーチンの外側に置く必要があり、Typeというキーワードによって始まり、End Typeというキーワードによって終わる。

次の例では出版物の属性をひとまとまりにしたBooksという構造体を定義している。

REM  ***** 構造体を定義 *****

'VBA拡張
Option Compatible

'Typeを用いた構造体宣言
Type Books
  BookTitle As String
  Subtitle As String
  Author As String
  Translator As String
  Publisher As String
  PublicationDate As Date
  PrintLength As Integer
  PriceYen As Integer
End Type
 
Sub Main
  'インスタンス変数を宣言
  Dim books1 As Books
  'データを代入
  books1.BookTitle = "科学と仮説"
  books1.Subtitle = void
  books1.Author = "ポアンカレ"
  books1.Translator = "伊藤邦武"
  books1.Publisher = "岩波書店"
  books1.PublicationDate = "2021/12/17"
  books1.PrintLength = 494
  books1.PriceYen = 1320

  'メッセージボックスへ表示
  MsgBox("書籍:" & books1.BookTitle & vbNewLine & _
   "副題:" & books1.Subtitle & vbNewLine & _
   "著者:" & books1.Author & vbNewLine & _
   "翻訳:" & books1.Translator & vbNewLine & _
   "出版社:" & books1.Publisher & vbNewLine & _
   "発行日:" & books1.PublicationDate & vbNewLine & _
   "頁数:" & books1.PrintLength & vbNewLine & _
   "価格:" & books1.PriceYen)
End Sub

Option Compatibleという宣言はvbNewLineという文字列定数を使うために必要だった。

Booksと名付けた構造体をType宣言によって定義した。

例えば「Dim BookTitle As String」という文はString型としてBookTitleという名のメンバー変数(データ・プロパティ)を定義する」というような意味。

Type宣言の後に置かれたMainというサブルーチンでは、まず構造体のBooksからbooks1というインスタンス変数を宣言し、次にその構造体の各メンバー(データ・プロパティ)に値を代入した。ここでは岩波書店から出版されているポアンカレの『科学と仮説』を例に挙げさせていただいた。

voidは空の値を意味する。

構造体に値を設定し終わったら、メッセージボックスにそれらを表示するようにした。文字列定数のvbNewLineは改行を意味している。

ちなみにこのMainサブルーチンは、C言語のmain函数と違い、プログラムの開始点を意味しない。

改行前のアンダーバー(_)はこの文が改行後も続くという意味。ただしこの例の場合、アンダーバーの前に空白を入れる必要があることに要注意。

PropertyValue UNO構造体を用いる方法

サブルーチンの外でType宣言を行う代わりにユニバーサル・ネットワーク・オブジェクト(UNO)のサービスであるcom.sun.star.beans.PropertyValueを利用しても構造体を定義することができる。

ただし構造体のメンバーが複数ある場合、構造体に番号を振って順序付構造体にする必要がある。

次の例では上述のコードと同様にBooksという構造体を定義した。

Booksには配列のように8つの番号を付けて順序付構造体にした。0から数えるのでBooks(7)となる。

REM ***** UNO構造体を定義 *****

Sub Main
  'UNOを利用した構造体宣言
  Dim Books(7) As New com.sun.star.beans.PropertyValue
  '各データ名を代入
  Books(0).Name = "書籍"
  Books(1).Name = "副題"
  Books(2).Name = "著者"
  Books(3).Name = "翻訳者"
  Books(4).Name = "出版社"
  Books(5).Name = "発行日"
  Books(6).Name = "頁数"
  Books(7).Name = "価格"

  '各データを代入
  Books(0).Value = "論理哲学論考"
  Books(1).Value = void
  Books(2).Value = "ウィトゲンシュタイン"
  Books(3).Value = "野矢茂樹"
  Books(4).Value = "岩波書店"
  Books(5).Value = "2003/8/20"
  Books(6).Value = 256
  Books(7).Value = 858
  
  'オブジェクト型変数を宣言
  Dim Doc,Sheet As Object
  Dim Cell1,Cell2 As Object
  
  '現在のドキュメントのインスタンス変数
  Doc = ThisComponent
  'シート"Sheet1"のインスタンス変数
  Sheet = Doc.Sheets.getByName("Sheet1")

  Dim i As Integer
  'セルに1つずつ書き込むループ
  For i=0 To 7
    Cell1 = Sheet.getCellByPosition(0,i)  
    Cell1.String = Books(i).Name
    
    If i > 6 Then
      'セルのインスタンス変数
      Cell2 = Sheet.getCellByPosition(1,i)
      'データをセルに入力
      Cell2.string = Books(i).Value
    Else
      'セルのインスタンス変数
      Cell2 = Sheet.getCellByPosition(1,i)
      'データをセルに入力  
      Cell2.Value = Books(i).Value
    End If
  Next i
End Sub

UNOからインスタンス変数を宣言するためにはAsだけでなくNew演算子が必要。したがってAs Newとする必要がある。次のように代入演算子とNew演算子の組み合わせでも同じことができる。

Books(7) = New com.sun.star.beans.PropertyValue

そして作成したインスタンス変数から.Nameに構造体の要素となるデータ・プロパティの識別子(名前)を代入した。

その後に.Valueに各々のデータ・プロパティの値を代入した。ここでは岩波書店から出版されているウィトゲンシュタインの『論理哲学論考』を例に挙げさせていただいた。

Calcの現在開いているドキュメントのシート"Sheet1"のセルに構造体の各データを入力するFor文を最後に記述した。

現在のドキュメントと"Sheet1"というシートのインスタンス変数をそれぞれ宣言しておき、For文の中ではCell1とCell2というインスタンス変数を宣言してBooks(7)の.Nameと.Valueの値をそれらのセルに順番に入力していくコードを書いた。

For文の中で用いたIf文は、文字列や日付の値をStringとして数値をValueとして区別してセルに入力するために使った。

順序付構造体にしないと次のようなコードになってしまうかもしれない。やや冗長であり、エレガントではない。

REM  ***** UNO構造体を定義 *****

Sub Main
  'オブジェクト変数
  Dim BookTitle As New com.sun.star.beans.PropertyValue
  Dim BookSubtitle As New com.sun.star.beans.PropertyValue
  Dim BookAuthor As New com.sun.star.beans.PropertyValue
  Dim BookTranslator As New com.sun.star.beans.PropertyValue
  Dim Publisher As New com.sun.star.beans.PropertyValue
  Dim PublicationDate As New com.sun.star.beans.PropertyValue
  Dim PrintLength As New com.sun.star.beans.PropertyValue
  Dim PriceYen As New com.sun.star.beans.PropertyValue
  
  'プロパティ名を定義
  BookTitle.Name = "書籍"
  BookSubtitle.Name = "副題"
  BookAuthor.Name = "著者"
  BookTranslator.Name = "翻訳者"
  Publisher.Name = "岩波書店"
  PublicationDate.Name = "発行日"
  PrintLength.Name = "頁数"
  PriceYen.Name = "価格"
  
  '値を代入
  BookTitle.Value = "科学と仮説"
  BookSubtitle.Value = void
  BookAuthor.Value = "ポアンカレ"
  BookTranslator.Value = "伊藤邦武"
  Publisher.Value = "岩波書店"
  PublicationDate.Value = "2021/12/17" 
  PrintLength.Value = 494
  PriceYen.Value = 1320

  'オブジェクト型変数を宣言
  Dim Doc,Sheet As Object
  Dim Cell1,Cell2 As Object
  
  '現在のドキュメントのインスタンス変数
  Doc = ThisComponent
  'シート"Sheet1"のインスタンス変数
  Sheet = Doc.Sheets.getByName("Sheet1")

  'セルにプロパティ名を入力
  With Sheet
    .getCellByPosition(3,0).String = BookTitle.Name
    .getCellByPosition(3,1).String = BookSubtitle.Name
    .getCellByPosition(3,2).String = BookAuthor.Name
    .getCellByPosition(3,3).String = BookTranslator.Name
    .getCellByPosition(3,4).String = Publisher.Name
    .getCellByPosition(3,5).String = PublicationDate.Name
    .getCellByPosition(3,6).String = PrintLength.Name
    .getCellByPosition(3,7).String = PriceYen.Name
  End With
  'セルに値を入力
  With Sheet
    .getCellByPosition(4,0).String = BookTitle.Value
    .getCellByPosition(4,1).String = BookSubtitle.Value
    .getCellByPosition(4,2).String = BookAuthor.Value
    .getCellByPosition(4,3).String = BookTranslator.Value
    .getCellByPosition(4,4).String = Publisher.Value
    .getCellByPosition(4,5).String = PublicationDate.Value
    .getCellByPosition(4,6).Value = PrintLength.Value
    .getCellByPosition(4,7).Value = PriceYen.Value
  End With
End Sub

コメント

このブログの人気の投稿

Visual Studio 2019にはC++のためのフォームデザイナーがない件

10の補数と9の補数と2の補数と1の補数

LibreOffice 6 Calcでフォーム(ダイアログ)を作成してマクロで表示