OpenOffice.org Basic メモ

2012年3月10日

はじめに

OpenOffice.org Basic による、OpenOffice.org Calc の操作についてのメモ。

OpenOffice.org 3.2.1 Windows 版/3.2.0 Linux 版を使用。

ドキュメントの取得

現在のドキュメント

ThisComponent

ドキュメントを開く

Dim Dummy()
doc = StarDesktop.loadComponentFromURL(ConvertToUrl(path)), "_blank", 0, Dummy())

以下、"ThisComponent" は "doc" と読み替え可能。

ドキュメント情報の取得

ファイル名の取得

title = ThisComponent.getTitle()

パスの取得

path = ThisComponent.getLocation()

パスのディレクトリ部分の取得

path_url = ThisComponent.getLocation()
title = ThisComponent.getTitle()
path_dir_url = Left(path_url, Len(path_url) - Len(title))

パスの頭の "file://" を取り除く

path_dir = ConvertFromURL(path_dir_url)

ドキュメントの操作

ドキュメントの保存

ThisComponent.store

ドキュメントを閉じる

ThisComponent.close True

引数の意味は不明。

シートの取得

現在のシート

sheet = ThisComponent.CurrentController.ActiveSheet

インデックスによるシートの取得

sheet = ThisComponent.Sheets(0)

名前によるシートの取得

sheet = ThisComponent.Sheets.getByName("Sheet1")

シートにアクセス

シートの名前

name = sheet.Name

シートのインデックス

i = sheet.RangeAddress.Sheet

シートのアクティブ化

ThisComponent.CurrentController.setActiveSheet(sheet)

シートの表示・非表示

sheet.IsVisible = False ' 非表示
sheet.IsVisible = True  ' 表示

シートの保護

sheet.protect ""   ' 保護
sheet.unprotect "" ' 保護の解除

引数はパスワード。"" はパスワードなしを意味する。

セルの取得

名前によるセルの取得

cell = sheet.getCellRangeByName("A1")

インデックスによるセルの取得

cell = sheet.getCellByPosition(column, row)

注意: 第 1 引数が列のインデックスで、第 2 引数が行のインデックス。

選択されているセルの取得

cell = ThisComponent.CurrentSelection

セルにアクセス

セル値

' 値の場合
cell.Value = value

' 文字列の場合
cell.String = str

' 数式の場合
cell.Formula = "=A1+B1"

セルの位置

column = cell.CellAddress.Column
row = cell.CellAddress.Row

セルの選択

ThisComponent.CurrentController.Select(cell)

セルの巡回

あるセル以降を、空のセルが現れるまで巡回する。

sheet = ThisComponent.CurrentController.ActiveSheet
cell = sheet.getCellRangeByName("A1")
c = cell.CellAddress.Column
r = cell.CellAddress.Row

i = 0
While sheet.getCellByPosition(c, r+i).Type <> Empty
	' ここに処理を書く
	
	i = i + 1
Wend

ファイルの書き出し

ファイルに文字列を書き出すには、つぎのようにする。

path = ThisComponent.getLocation()
title = ThisComponent.getTitle()
path_dir = Left(path, Len(path) - Len(title))

fn = Freefile
Open path_dir & "output.txt" For Output As fn

Print #fn, "text"

Close #fn

ファイルの読み込み

ファイルから空白区切りの文字列を読み込み、それぞれをセルに配置するには、つぎのようにする。

path = ThisComponent.getLocation()
title = ThisComponent.getTitle()
path_dir = Left(path, Len(path) - Len(title))

sheet = ThisComponent.CurrentController.ActiveSheet
cell = sheet.getCellRangeByName("A1")
c = cell.CellAddress.Column
r = cell.CellAddress.Row

fn = Freefile
Open path_dir & "input.txt" For Input As fn

i = 0
Do While not eof(fn)
	Line Input #fn, s
	
	v = Split(s, " ")
	
	For j = 0 To UBound(v)
		sheet.getCellByPosition(c+j, r+i).String = v(j)
	Next
	
	i = i + 1
Loop

Close #fn

Tab 区切りの場合は Split() で " " の代わりに Chr(9) を指定する。

ディレクトリの巡回

あるディレクトリ以下にあるすべてのファイル、もしくはある条件を満たすファイルに対して処理を行うような場合は、つぎのようにする。

Sub search_dir
	path_url = ThisComponent.getLocation()
	title = ThisComponent.getTitle()
	path_dir_url = Left(path_url, Len(path_url) - Len(title))
	path_dir = ConvertFromURL(path_dir_url)

	sheet = ThisComponent.CurrentController.ActiveSheet

	' 処理の開始
	change_dir(path_dir)
End Sub


Sub change_dir(path)
	
	next_file = Dir(path, 0)
	
	While next_file <> ""
		' ファイルに対する処理を書く
		
		next_file = Dir
	Wend
	
	next_dir = Dir(path, 16)
	
	list_str = next_dir
	While next_dir <> ""
		next_dir = Dir
		list_str = list_str & " " & next_dir
	Wend
	
	list = Split(list_str, " ")
	
	For j = 0 To UBound(list)
		next_dir = list(j)
		If next_dir <> "." And next_dir <> ".." And next_dir <> "" Then
			change_dir(path & next_dir & "\") ' for Windows
			'change_dir(path & next_dir & "/") ' for Linux
		End If
	Next

End Sub

画像の貼り付け

document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

dim args1(2) as new com.sun.star.beans.PropertyValue
args1(0).Name = "FileName"
args1(0).Value = ConvertToURL(path_dir & "picture.png")

dispatcher.executeDispatch(document, ".uno:InsertGraphic", "", 0, args1())

最後に貼り付けた画像のサイズを変更するには次のようにする。

' size
dp = sheet.getDrawPage
d = dp.getByIndex(dp.getCount - 1)

dim size as new com.sun.star.awt.Size
size.Width = d.Size.Width * 0.5
size.Height = d.Size.Height * 0.5

d.setSize(size)

size.Width, size.Height に直接数値を指定する場合、1/1000 cm 単位で指定する。つまり、12 cm なら 12*1000 を指定する。

外部プログラムの実行

Shell "C:\Program Files\Mozilla Firefox\firefox.exe", 1, "http://www.yahoo.co.jp", False

第 1 引数はプログラムのパス、第 3 引数以降はプログラムに渡す引数を指定する。第 2 引数の数字ではプログラム起動時のウインドウのスタイルを指定する。

  1. ウインドウ非表示、フォーカスを移動
  2. ウインドウ標準サイズ、フォーカスを移動
  3. ウインドウ最小化、フォーカスを移動
  4. ウインドウ最大化、フォーカスを移動
  5. ウインドウ標準サイズ、フォーカスを移動しない
  6. ウインドウ最小化、フォーカスを移動しない
  7. ウインドウ全画面表示

第 4 引数は同期の指定で、True の場合は外部プログラムの終了を待ってから次に進む。

注意: OpenOffice.org Basic ではカレントディレクトリを直接指定することができない。相対パスでファイルを読み書きするプログラムを実行する場合には注意が必要である。

メッセージボックス

MsgBox "message", 0, "title"

第 1 引数に表示する文字列、第 3 引数にメッセージボックスのタイトルを指定する。第 2 引数の数字は、メッセージボックスの種類を表わす。

  1. OK ボタンのみ
  2. OK ボタン・キャンセルボタン
  3. 中止・やり直し・取消しボタン
  4. はい・いいえ・キャンセルボタン
  5. はい・いいえボタン
  6. やり直し・キャンセルボタン

アイコンの指定には、指定する数字に次の値を加える。

  1. ストップ記号
  2. 疑問符
  3. 感嘆符
  4. ヒント記号

押されたボタンの種類は、返り値を調べることでわかる。

r = MsgBox("message", 2+16, "title")
  1. OK
  2. キャンセル
  3. 終了
  4. やり直し
  5. 無視
  6. はい
  7. いいえ

マクロ実行用ボタンの追加

シートにマクロ実行用ボタンを追加する。

  1. メニュー [表示]-[ツールバー]-[フォームコントロール] を選択。
  2. デザインモードをオンにする。
  3. ボタンを追加。
  4. 右クリックのポップアップメニューから [コントロール] を選択。
  5. [全般] タブの [タイトル] でボタンに表示させる文字列を指定。
  6. [イベント] タブの [実行時] で実行させるマクロを指定。
  7. デザインモードをオフにする。
  8. ボタンをクリックして、マクロが実行させるかどうか確認する。

画面表示更新の抑制

処理が終わるまで画面表示の更新を抑制することで、処理を高速化できる。以下で処理を囲む。

ThisComponent.addActionLock()
...
ThisComponent.removeActionLock()

オブジェクトのプロパティとメソッドのリストの取得

オブジェクトのプロパティ "Dbg_Properties", "Dbg_Methods" でそのオブジェクトのプロパティやメソッドのリストが得られる。シートのプロパティとメソッドのリストを得るには、つぎのようにする。

sheet = ThisComponent.CurrentController.ActiveSheet


' プロパティ
cell = sheet.getCellRangeByName("A1")
c = cell.CellAddress.Column
r = cell.CellAddress.Row

list = Split(sheet.Dbg_Properties, ";")

For i = 0 To UBound(list)
	sheet.getCellByPosition(c, r+i).String = list(i)
Next


' メソッド
cell = sheet.getCellRangeByName("E1")
c = cell.CellAddress.Column
r = cell.CellAddress.Row

list = Split(sheet.Dbg_Methods, ";")

For i = 0 To UBound(list)
	sheet.getCellByPosition(c, r+i).String = list(i)
Next

エラー処理

エラー処理には "On Error" を使う。たとえば、ファイルが開けないエラーを検出するにはつぎのようにする。

path_url = ThisComponent.getLocation()
title = ThisComponent.getTitle()
path_dir_url = Left(path_url, Len(path_url) - Len(title))
path_dir = ConvertFromURL(path_dir_url)

On Error GoTo open_error
fn = Freefile
Open path_dir_url & "file" For Input As #fn
Close #fn

End

open_error:
MsgBox("Open Error")