ブログの説明

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

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

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

LibreOffice Basic 変数 データ型 スコープ 定数 演算子 配列 構造体

LibreOffice Basicの文法はマクロソフトのVBAに似ている。ExcelでVBAを使っている人にとっては覚えやすい。ただしVBAのほうがより厳格なので、VBAの構文がLibreOffice BasicでエラーになるよりもLibreOffice Basicの構文がVBAでエラーになることのほうが多いらしい。

コメントの付け方

アポストロフィ(')かREMで始まってその行末までがコメント。REMは大文字と小文字を区別しないのでremでもREMでもRemでもみな同じ。

'改行までがコメント
REM 改行までがコメント
rem 改行までがコメント

ステートメント

一つの命令や一つの宣言を表すLibreOffice Basicの基本単位がステートメント。文章でいえば一つの文。LibreOffice Basicでは改行によって一つ一つのステートメントが区切られる。改行をまたいで一つのステートメントを記述したい場合にはアンダースコア(_)を使う。また、一つの行に複数のステートメントを記述したい場合にはコロン(:)を使う。

REM **** BASIC ****

Sub Main
  MsgBox("Hello World")
  '2行に渡って1つのステートメントを記述
  MsgBox("Hello") & _
    " LibreOffice"
  '1行に複数のステートメントを記述
  MsgBox("Hello Basic") : MsgBox("Good Night")
End Sub

文字列定数

Option Compatibleとモジュールの冒頭に宣言しておくと、マイクロソフトのVBやVBAと同じように、次のような文字列定数を使用することができる。Option CompatibleはLibreOffice BasicにVBAと同様の機能を付け加えるためのもの。

vbLf
ラインフィード(改行)。C言語でいうところの\n
vbCr
キャリッジリターン(行頭)。C言語でいうところの\r
vbCrLf
キャリッジリターンとラインフィード
vbTab
水平タブ。C言語では\t
vbVerticalTab
垂直タブ。C言語では\v
vbFormFeed
フォームフィード(改頁)。C言語では\f
vbNewLine
各プラットフォームに適した改行
vbNullString
空の文字列リテラル。""と同じ
vbNullChar
ASCIIコード表で0x00に当たる空文字

ただしこれらはダブルクォーテーションの外で連結演算子&を使って用いなくてはならない。

REM **** BASIC ****
'VBA拡張
Option Compatible

Sub Main
  MsgBox("Serebro" & vbNewLine & "Mama Luba")
End Sub

命名の規則

変数名、定数名、関数名、サブルーチン名、ラベル名として使うことができる名前のルールは次のとおり。

  • 255文字まで有効
  • 最初の文字は、大文字のAからZ、または小文字のaからzまでの英字である必要がある
  • 2文字目からは英字のほかにアラビア数字やアンダースコア(_)を使うことができる
  • 大文字と小文字は識別されない
  • 角括弧ではさめば変数名にスペースを含めることができる
  • UNOのAPI定数は大文字と小文字を識別する

変数の宣言

LibreOffice Basicではあらかじめ宣言することなく変数を使うことができるが、Dimというキーワードを使って明示的に宣言してから使うようにすることもできる。モジュールの冒頭でOption Explicitと宣言した場合、宣言せずに変数を使うとエラーになる。

変数の宣言にはDim 変数名 As データ型という書式を使う。変数に値を代入するには変数名 = 値という書式を使う。変数の宣言と同じ行で代入を行うこともできる。

REM **** BASIC ****
'変数を明示的に宣言して使う
Option Explicit

Sub Main
  '変数の宣言
  Dim family_name As String
  Dim [personal name] As String
  
  '変数への値の代入
  family_name = "Suzuki"
  [personal name] = "Ichiroo"

  '出力
  MsgBox(family_name & " " & [personal name])
End Sub

スコープ(適用範囲)

サブルーチンの中や函数の中でDimまたはStaticというキーワードによって変数を宣言すると、その変数は局所変数として扱われる。局所変数とは、その宣言が通用する範囲がサブルーチンや函数の中に限られている変数のこと。したがって、同じ名前の変数が別のサブルーチンや函数の中にあってもその変数は別個の変数として扱われる。

Staticによって宣言された局所変数は静的変数となる。サブルーチンや函数の中で宣言された変数はサブルーチンや函数が呼び出されるたびにその値を初期化してしまうが、そうせずに値を保持する働きを持つのが静的変数。静的変数があると、サブルーチンや函数を呼び出した回数を呼び出し先のサブルーチンや函数の中で数えることができるので便利。

サブルーチンの外や函数の外でかつモジュールの冒頭で宣言された変数には、パブリックドメイン変数と大域変数とプライベート変数がある。

パブリックドメイン変数と大域変数はモジュールの違いを越えてすべてのサブルーチンや函数においてその宣言が通用する変数。パブリックドメイン変数を宣言するにはDimまたはPublicというキーワードを用いる。大域変数を宣言するにはGlobalというキーワードを用いる。パブリックドメイン変数はマクロの実行中だけ変数の値を保持するが、大域変数はマクロの実行後も変数の値を保持するという違いがある。

プライベート変数を宣言するにはPrivateというキーワードを用いる。プライベート変数はそれが宣言されたモジュール内だけでその宣言が通用する変数だが、実際に試してみるとDimやPublicと同様に機能するように見える。プライベート変数の機能を有効にするにはCompatibilityMode(True)がどうやら必要らしい。

データ型

LibreOffice Basicで扱うことができるデータ型は次のとおり。型宣言子はいわゆるショートカットであり、変数名の末尾に添え付けるとAs データ型と同じ意味を持つ。

Integer
-32768から32767までの整数値。型宣言子は%
Long
-2147483648から2147483647までの整数値。型宣言子は&
Single
-3.402823掛ける10の39乗から3.402823掛ける10の39乗までの単精度浮動小数点数。型宣言子は!
Double
-1.79769313486232掛ける10の308乗から1.79769313486232掛ける10の308乗までの倍精度浮動小数点数。型宣言子は#
String
65536文字までの文字列。文字列の値そのものはダブルクォーテーション(")ではさむ必要がある。文字列の中にダブルクォーテーションを使う場合にはダブルクォーテーションを二重にする("")。型宣言子は$
Currency
通貨値。小数点以下4桁まで有効な固定小数点数。このデータ型を使うと丸め誤差を避けることができる。型宣言子は@

次のコードはデータ型にSingleを使った場合とCurrencyを使った場合を比較している。55.55から55を差し引くと0.55になるはずだが、Singleを使った場合には丸め誤差が生じて0.5499992になってしまうことが分かる。

REM **** BASIC ****
'変数名を宣言してから使う
Option Explicit
'VBA拡張
Option Compatible

Sub Main
  'Single型の場合
  Dim a!, b As Single
  a = 55.55
  b = a - 55
  MsgBox("データ型にSingleを使うと" & vbNewLine _
    & "55.55 - 55 = " & b)

  'Currency型の場合
  Dim c As Currency
  Dim d As Currency
  c = 55.55
  d = c - 55
  MsgBox("データ型にCurrencyを使うと" & vbNewLine _
    & "55.55 - 55 = " & d)
End Sub
Boolean
TrueかFalseの値をとる論理値。内部的には整数値であり、0がFalseを意味し、それ以外がTrueを意味する
REM **** BASIC ****
'変数名を宣言してから使う宣言
Option Explicit
'VBA拡張
Option Compatible

Sub Main
  'Boolean型変数を宣言
  Dim a As Boolean
  Dim b As Boolean
  Dim c As Boolean
  '代入
  a = 1
  b = 0
  c = -1
  '出力
  MsgBox( _
    "1 = " & a & vbNewLine & _
    "0 = " & b & vbNewLine & _
    "-1 = " & c)
End Sub
Date
年月日と時分秒。書式は"2019/08/25 10:05:30"。現在の年月日と時刻を取得するにはnow()関数を用い、現在の年月日だけを取得するにはdate()関数を用い、現在の時刻だけを取得するにはtime()関数を用いると便利。
REM **** BASIC ****
'変数名を宣言してから使う宣言
Option Explicit
'VBA拡張
Option Compatible

Sub Main
  'Date型変数を宣言
  Dim dateTime As Date
  '現在の年月日時分秒を代入
  dateTime = now()
  '出力
  MsgBox(dateTime)
  '整形して出力
  MsgBox( _
    Year(dateTime) & "年" & _
    Month(dateTime) & "月" & _
    Day(dateTime) & "日" & vbNewLine & _
    Hour(dateTime) & "時" & _
    Minute(dateTime) & "分" & _
    Second(dateTime) & "秒")
End Sub
Object
オブジェクト。キーワードDimでオブジェクト型として宣言した変数にオブジェクトを代入する際にはSet 変数名 = New オブジェクトという書式を用いる
Variant
未定のデータ型。Asというキーワードを使ってデータ型を指定しなかった場合にもこのデータ型に自動的になる。

定数

変数は代入した値が実行中に変化することを想定しているが、定数は値を不変に保つ。よって定数は別名や代名詞のように機能する。constというキーワードを使って定数を作成することができる。C言語のマクロであるdefineのような用途に使うことができる。

文字列定数もOption Compatibleによって有効になる定数の一種。

次のコードは消費税率を定数に代入して税別価格から税込価格を計算するもの。

REM **** BASIC ****
'変数を明示的に宣言して使う
Option Explicit

Sub Main
  '消費税率を定数化
  Const TAX As Single = 0.08

  '変数を宣言
  Dim pureprice As Currency
  Dim sumprice As Single

  'ユーザーからの入力
  pureprice = InputBox("税別価格を入力してください")

  '計算
  sumprice = pureprice * (TAX + 1)

  '計算結果を出力
  MsgBox("税込価格は" & sumprice & "円です")
End Sub

演算子

LibreOffice Basicの演算子は他のプログラミング言語やスプリクティング言語とだいたい同じだが、ここでは異なるもの、または注意すべきものについて言及する。

引き算による余りは%ではなくMOD。

Sub Main
  remainder = 20 MOD 3
  MsgBox("20 MOD 3 = " & remainder)
End Sub

累乗は**ではなく^という算術演算子を使って表す。

文字列を連結する演算子は&ばかりでなく、C言語のように+も連結演算子として同様に使うことができる。&と+との違いは数値型と文字列型とを連結させるときに生ずることがあるので要注意。

Sub Main
  MsgBox("連結" + "演算" + "子")
End SUb

通常の割り算を行う演算子である/とは別に、答えの小数点以下を切り捨てる割り算を行う演算子である\がある。

REM **** BASIC ****
'変数を明示的に宣言して使う
Option Explicit
'VBA拡張
Option Compatible

Sub Main
  Dim numDiv As Double
  Dim conInt As Integer
  Dim intDiv As Double

 '通常の除算
  numDiv = 671 / 3
  ' Double型をInteger型へ代入
  conInt = numDiv
  '整数除算演算子を使う
  intDiv = 671 \ 3

  MsgBox("671 / 3 = " & numDiv & _
    vbNewLine & "671 / 3 = " & conInt & _
    vbNewLine & "671 \ 3 = " & intDiv)
End Sub

比較演算子の等しいことを表すのは==ではなく=。代入演算子と同じ。等しくないことを示すには!=ではなく<>を用いる。

論理演算子またはビット演算子としては、NOT, AND, OR, XOR, EQV, IMPがある。これらは通常、評価される優先順位がもっとも低いが、NOT演算子だけはもっとも高い優先順位を持っている。

演算子は、他の多くのプログラミング言語同様に左から右へと順番に評価されるのが基本原則だが、しかしその基本原則に優先する評価順位がある。数学と同様に足し算や引き算より掛け算や割り算が優先される。優先順位がもっとも高いのは論理またはビット演算子であり、次いで比較演算子、そして算術演算子の順に優先順位が低くなる。NOT演算子がもっとも優先順位が低い。優先順位を変えるには丸括弧ではさむ必要がある。

REM **** BASIC ****
'VBA拡張
Option Compatible

Sub Main
  num1 = 3 + 30 / 5
  num2 = (3 + 30) / 5
  MsgBox("3 + 30 / 5 = " & num1 & vbNewLine _
  + "(3 + 30) / 5 = " & num2)
End SUb

配列

配列は変数の拡張版。配列では複数の変数を数学でいうところの行列のように縦や横に規則正しく並べて一つの集合のように扱うことができる。Option Explicitが宣言されていない場合でも配列は必ず宣言してから使わなくてはならない。配列の宣言時にデータ型を指定すれば同じデータ型に統一され、データ型としてVariantを指定するか何も指定しなければ異なるデータ型を代入することができる。

配列を宣言するときの書式はDim 配列名(開始要素番号 to 最終要素番号)またはDim 配列名(最終要素番号)もしくはDim 配列名(開始要素番号 to 最終要素番号) As データ型またはDim 配列名(最終要素番号) As データ型のようになる。丸括弧の中に指定するのは要素数ではなく最終要素番号であることに要注意。最終要素番号だけを指定したときには開始要素番号は0から始まる。配列名(要素番号)という書式で配列の要素に代入したり参照したりすることができる。

REM **** BASIC ****
'変数を明示的に宣言して使う
Option Explicit
'VBA拡張
Option Compatible

Sub Main
  '配列の宣言
  Dim vec1(5 to 7) As String
  Dim vec2(3) As Integer
  Dim vec3(0 to 2) As Variant
  
 '代入
  vec1(5) = "りんご"
  vec1(6) = "みかん"
  vec1(7) = "すいか"
  vec2(0) = 2
  vec2(1) = 4
  vec2(2) = 6
  vec2(3) = 8
  vec3 = Array("LibreOffice",250,True)

  '出力
  MsgBox( _
    "vec1 = " & vec1(5) & "," & vec1(6) & _
      "," & vec1(7) & vbNewLine & _
    "vec2 = " & vec2(0) & "," & vec2(1) & _
      "," & vec2(2) & "," & vec2(3) & vbNewLine & _
    "vec3 = " & vec3(0) & "," & vec3(1) & _
      "," & vec3(2))
End Sub

Array函数はVariant型のデータを常に返すことに要注意。例えばArray("Hellow")の"Hellow"はVariant/String型になる。

配列の要素数を途中変更

すでに要素数を宣言した配列の要素数を実行途中で変更するためにはReDimキーワードを使って再宣言する。ただしその際、データ型を指定しないか元の配列と同じにしなくてはならない。ReDimによって要素数を変更すると、その配列の中にすでに入っている要素はすべて失われて空になってしまう。これを防ぐためにはReDim Preserveと指定する。

Sub Main
  '配列の宣言
  Dim vec(2) As String
 
 '代入
  vec(0) = "りんご"
  vec(1) = "みかん"
  vec(2) = "すいか"

  '出力
  MsgBox( "vec = " & vec(0) & "," _
    & vec(1) & "," & vec(2))
  
  '配列をリサイズ
  ReDim Preserve vec(3) As String
  
  '代入
  vec(3) = "いちご"
  
  '出力
  MsgBox("vec = " & vec(0) & "," _
    & vec(1) & "," & vec(2) & "," & vec(3))
End Sub

Array函数を用いて値を代入すると「Variant/各要素のデータ型」というデータ型になる。そのためか、データ型の違いによってPreserveがうまく機能しなくなるようなので要注意。

多次元配列

配列は一次元配列ばかりでなく多次元配列としても利用することができる。二次元配列を宣言する場合、その書式はDim 配列名(列の開始要素番号 to 列の最終要素番号, 行の開始要素番号 to 行の最終要素番号) As データ型またはDim 配列名(列の最終要素番号,行の最終要素番号) As データ型のようになる。

REM **** BASIC ****
'変数を明示的に宣言して使う
Option Explicit
'VBA拡張
Option Compatible

Sub Main
  '配列の宣言
  Dim vec(2, 1) As String
 
 '代入
  vec(0,0) = "I"
  vec(0,1) = "we"
  vec(1,0) = "you"
  vec(1,1) = "you"
  vec(2,0) = "he/she/it"
  vec(2,1) = "they"

  '出力
  MsgBox( _
    vec(0,0) & vbTab & vbTab & vbTab & vec(0,1) & vbNewLine & _
    vec(1,0) & vbTab & vbTab & vbTab & vec(1,1) & vbNewLine & _
    vec(2,0) & vbTab & vec(2,1))
End Sub

この要領で三次元配列、四次元配列、五次元配列というふうに拡張していくことが可能であるらしい。高次元の配列になると抽象的すぎて視覚的に想像するのが難しい。

変数をグループ化して構造体を作成

Typeというキーワードを使うと、C言語の構造体のように、異なるデータ型の複数の変数を一つの集合のようにまとめて独自のデータ型を定義することができる。

REM **** BASIC ****
'変数名を宣言してから使う宣言
Option Explicit
'VBA拡張
Option Compatible

'Bookというデータ型の集合(構造体)を定義
Type Book
  title As String
  author As String
  publishedDay As Date
  price As Currency
End Type

Sub Main
  'Bookという構造体を使う宣言
  Dim book1 As New Book
  Dim book2 As New Book
  
  '値を代入
  book1.title = "種の起原〈上〉"
  book1.author = "チャールズ・ダーウィン"
  book1.publishedDay = "1990/2/16"
  book1.price = "1166"

  book2.title = "論理哲学論考"
  book2.author = "ウィトゲンシュタイン"
  book2.publishedDay = "2003/8/20"
  book2.price = "842"
  
  '出力
  MsgBox( _
    "タイトル:" & book1.title & vbNewLine & _
    "著者:" & book1.author & vbNewLine & _
    "発行日:" & book1.publishedDay & vbNewLine & _
    "価格:" & book1.price)
    
  MsgBox( _
    "タイトル:" & book2.title & vbNewLine & _
    "著者:" & book2.author & vbNewLine & _
    "発行日:" & book2.publishedDay & vbNewLine & _
    "価格:" & book2.price)
End Sub

定義したデータ型を使う宣言をする際にNewというキーワードを使っても使わなくてもよい。Newを使うとクラスのインスタンス化っぽい。その他にCreateObject関数を使う方法がある。その書式は変数名 = CreateObject("定義したデータ型名")のようになる。

Withステートメント

Withステートメントを用いると次のようにコーディングできるので便利。

With book1
  .title = "種の起原〈上〉"
  .author = "チャールズ・ダーウィン"
  .publishedDay = "1990/2/16"
  .price = "1166"
End With

With book2
  .title = "論理哲学論考"
  .author = "ウィトゲンシュタイン"
  .publishedDay = "2003/8/20"
  .price = "842"
End With

今回はここまで。サブルーチン、函数、制御構文、例外処理、オブジェクトの操作、イベントの処理などについてはまたの機会に。

コメント

このブログの人気の投稿

LATEXで数式:指数と順列などで使う添数・添字

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

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