読者です 読者をやめる 読者になる 読者になる
スポンサーリンク

OOo Calc Basicマクロで配列を初期化し,動的に要素数を増やし,引数に渡すサンプルコード。実用的な配列プログラミングをマスター

calc OpenOffice Basic OpenOffice.org プログラミング サンプルコード VBA

Excel/Wordオフィス製品のTipsまとめへ


OpenOffice.org Calc の Basic マクロで,配列の実用的な操作方法をサンプルコード付きで解説する。

Excel VBAと同じように,配列を自由自在に使いこなせるようになろう。

(1)配列の宣言と初期化・生成のサンプル

まず,OOo Basicで配列を操作する一番簡単なサンプルを見てみよう。

Array関数を使って,配列の全要素をいっぺんに指定するのが楽。

Sub hoge1

	arr = Array( "あ", "い", "う" )
	
	' 配列の要素を順番に表示
	For i = 0 To UBound( arr )
		Msgbox arr(i)
	Next i 

	' 「あ」「い」「う」と表示される。

End Sub


次に,文字列をSplitして配列を生み出してみよう。

文字列を区切り文字(デリミタ)で分解して,配列に格納し,要素を一つずつ表示してみるサンプルコード:

Sub hoge1
	
	' 文字列をデリミタで分割し,配列に代入
	arr = Split("http://example.com/abcd/efg/hijk/", "/" )
	
	' 配列の要素を1つずつ表示
	For i = 0 To UBound( arr )

		Msgbox arr(i)
		
	Next i
	
	' 以下のような順番で表示される。
	' 「http:」「」「example.com」「abcd」「efg」「hijk」「」

End Sub


また,配列の全要素数がはじめからわかっている場合,「Dim文」を使って配列を宣言(定義)し,要素数を指定することもできる。


このとき注意点として,Dim文のカッコ内に入る数字は「配列のインデックスの最大値」だ。

なので,要素数はそれにプラス1したものになる。


下記のサンプルコードを実行してみればわかる。

Sub hoge1

	Dim arr(3) ' 要素数は4なので注意
	arr(0) = "あ"
	arr(1) = "い"
	arr(2) = "う"
		' arr(3) を初期化していない

	' 配列の要素を1つずつ表示
	For i = 0 To UBound( arr )

		Msgbox arr(i)
		
	Next i
	
	' 以下のような順番で表示される。
	' 「あ」「い」「う」「」 で,4要素ある。


	' 初期化されていないインデックスを検査
	If IsEmpty( arr(3) ) Then
		Msgbox "第四要素は初期化されていないため,Emptyです。"
	End If


End Sub

上のコードで,Dim文ではカッコの中に3と指定している。

こうすると,UBoundが返す配列の最大インデックスも3。

ということはつまり,配列の要素数は4だ。混乱しないように。


配列の各要素は,Dim文の段階でそれぞれ初期化される。

バリアント型の配列で,なにも値を代入しないと,その要素には「Empty」が代入された状態になる。

このことは,上記のコードでは IsEmpty 関数を使ってチェックできている。


参考資料(配列の宣言):

配列 - Apache OpenOffice Wiki
https://wiki.openoffice.org/wiki/JA/D...

  • 1 次元配列 配列の宣言法は、通常の変数と基本的には同じです。ただし、配列名に続けて、配列の要素数をかっこで囲んで指定する点が異なります。
  • 配列は次のようにして宣言します。 Dim MyArray(3)


[Solved] How to initialize array? (View topic) • Apache OpenOffice Community Forum
https://forum.openoffice.org/en/forum...

  • There is an Array() function to create an array with optional arguments.
  • a = Array("a","b",1,2,3,Array(x,y,z),obj,Null)


参考資料(Split関数で配列を生成):

faq/4/851 - OpenOffice.org Q&A
http://oooug.jp/faq/index.php?faq%2F4...

  • 17*2*3*3*53*71のような文字列を、17,2,3,3,53,71のように分解して配列に入れたい

sData="17*2*3*3*53*71"
vShow = split(sData,"*")
for n = 0 to ubound(vShow()) ...


LibreOffice Calc Basic fun!!!: 文字列関数 (5)
http://calibreblo.blogspot.jp/2011/06...

  • Split 関数とは、文字列を指定された文字で分割して配列を作成する関数
  • Split(Text [, Delimiter [, Limit]])

参考資料(宣言されても初期化されていなければ,Variant配列の場合はEmptyで初期化される):

Empty, Null or Nothing in OpenOffice Basic - cereusapis
http://cereusapis.com/empty-null-or-n...

  • When you declare a variable of a specified type, other then Variant, the variable is initialized with a value and is not Empty.
  • Inspecting these variables with IsEmpty() will return False.

(2)配列の要素数を動的に増やし,末尾に新要素を追加してゆく方法

配列の長さは,事前にわからないことが多い。

「まず長さ 0 の配列を作っておいて,一つずつ要素数を増やしてゆく」という処理をしたくなる。


配列の要素数を動的に変更するには,ReDim文を使えばよい。

下記のサンプルコードを理解しよう。

Sub hoge1


	' 要素数が 0 の配列を定義
	Dim arr()

	' Dim arr(-1) 
	' こう書いてはいけない。「許可された範囲外のインデックス」のエラーになる

	Msgbox "現在の配列の最大インデックスは" & UBound( arr )
		' -1 と表示される。
	
	' 1から10までの数について,
	' 条件を満たすもののみ配列に格納
	For i = 1 To 10
	
		' 3で割り切れる数なら,配列に追加する
		If ( i Mod 3 = 0 ) Then
			' 3で割った余りが0ならば,という条件
			
			' 現在の配列の要素数を取得
			count_now = UBound( arr )
			
			' 配列の要素数を増やす
			ReDim Preserve arr ( count_now + 1 )
			
			' 配列の末尾に新しく値を格納
			arr(  UBound( arr ) ) = i

			Msgbox "現在の配列の最大インデックスは" & UBound( arr )
			' だんだん増えてゆく
			
		End If 
	
	Next i
	

	' 配列の全要素を順番に表示
	For i = 0 To UBound( arr )
		Msgbox arr(i)
	Next i
	
	' 「3」「6」「9」が表示される。

End Sub

上記のコードでは,まず長さ 0 の空配列を作成している。

そして,条件に合うものが見つかり次第,ReDim文で配列の長さを増やして要素を格納している。


参考資料(ReDim文):

配列 - Apache OpenOffice Wiki
https://wiki.openoffice.org/wiki/JA/D...

  • データフィールドのサイズを動的に変更させることが可能
    • 動的な配列の要素数は,最初はわからないため、後でフィールドの上限を変更する必要があります。
  • このような配列を作成するには、OpenOffice.org Basic では次のように宣言します。
    • ReDim MyArray(10)
    • OpenOffice.org Basic の場合は ReDim により動的および静的配列のサイズを変更できます。


[Bug報告] ReDim で要素数を増やすコードがエラーになる (トピック) • OpenOffice.org コミュニティーフォーラム
https://forum.openoffice.org/ja/forum...

  • 配列の要素数を ReDim Preserve で1つずつ増やす場合、 ReDim Preserve vntArray(0 to (UBound(vntArray) + 1)) のようなコードを使います。
  • 『現在の添字の上限値+1』で再定義する


AddinBox/VBAユーザーの為のOpenOffice.org 備忘録:ReDim Preserve で第1次元も追加可能
http://blog.livedoor.jp/addinbox/arch...

  • Excel VBAだと:
    • Preserve を指定した場合、変更できるのは動的配列の最後の次元のサイズに限られます。
  • OOo.Basic ( StarSuite Basic ) だと:
    • 最後の次元のサイズに限らず,他の次元も変更できます。

ちなみに,Excel VBAだと,空の配列を作成するためには要素数に -1 を指定する。

OOo Basicではそのような書き方はしない。

方法 : 要素を持たない配列を作成する
https://msdn.microsoft.com/ja-jp/libr...

  • Visual Basicでは,要素を持たない配列を作成するには 配列の次元のいずれかを -1 に宣言します。

(3)配列を引数に渡すには

では,配列を関数(サブルーチン)に渡してみよう。

これは全く手間がかからない。普通の変数と同じように渡すだけ。

Sub hoge1

	' 配列を作成
	arr = Array( "あ", "い", "う" )
	
	' ルーチンの引数に配列を渡す
	Call hoge2( arr )
	
	' 配列の要素を順番に表示
	For i = 0 To UBound( arr )
		Msgbox arr(i)
	Next i 
	
	' 「ま」「い」「う」 と表示される。

End Sub


' 配列を引数に取るルーチン
Sub hoge2( arr )

	' 配列の内容を加工する
	arr(0) = "ま"
	
End Sub

OOo Basicで,プロシージャや関数の引数に「配列」を渡す場合,引数にByRefをつける必要は無い。

デフォルトで参照渡しになっているので,ByRefがあってもなくても同じになる。


なので,プロシージャの呼び出し元と呼び出された処理内で,同一の配列オブジェクトを取り扱うことができる。


上記のサンプルコードでも,hoge2 内での変更操作が hoge1 内に影響を及ぼしている。

呼び出したルーチン内で同一の配列を扱っているため,このようになるのだ。


逆に,ByValで値渡しすることは不可能なので注意。

プロシージャと関数 - Apache OpenOffice Wiki
https://wiki.openoffice.org/wiki/JA/D...

  • OpenOffice.org におけるプロシージャや関数へのパラメータの渡し方は、基本的に VBA と同じ
  • 標準でパラメータは、参照渡しとして与えられます。
    • パラメータを値として渡すには、ByVal キーワードを使用します。
  • OpenOffice.org Basic では参照渡しが既に標準的な方法なので、OpenOffice.org Basic はこのキーワードを認識しますが, 無視します。


Excel/Wordオフィス製品のTipsまとめへ