#オープンソースの表計算ソフトを探そう
Excel が一番いいんだが、わたしはオープンソースを配布しているのに その補助として Excel を用意してください、というのも不便だろう。
そこで今どきなら LibreOffice がいいのではないか。ダウンロードしてみよう。
#LibreOffice
Download site
http://www.libreoffice.org/
日本語版もあるのか……。でもまあ ゲーム開発の需要からすると 英語の方が 読者も多いだろう……。
しぶしぶ 英語のままで [DOWNLOAD VERSION 5.2.5] をクリック。
(ダウンロードが終わったらクリックする。インストール・ウィザードが出てきた)
あとは どんどん [次へ]、[次へ] と押していく。
ちなみに「できた」と言うと、閾値100%を超えていない「できた」は「できていないだ」という人がいた ので配慮し、20代の頃は「まだ進捗50%です」とか細かく刻んでいたが 30も過ぎると めんどくさくなって「でけた」と つぶやくことにしている。確かに日本語には 1%できた という表現がない。でけた はオヌヌメだ。おかげで言葉に不自由なく 日ごろから 1%ずつでけまくっている。
おっ、何か出てきた……。
やりたいことは、1つのブックに 6つ程度のシートをまとめ、
このシートは リレーショナル にできていてデータがばらけているので、データを1つにつなげた見やすいビューを作ることだ。
(1つのトランジションは、複数のコンディションを持っている)
たとえば この コンディション の方に……。
トランジションの 見出しを付けてくれるだけでも 入力はたいへん楽になるはずだ。
……、よくよく考えると エクスポートでも コメント行ぐらい付けれるか。
だが せっかくだし 表計算ソフトでやってみるか。
おおっ! ぱっと見、Excel とはなんだったのかという同等の見た目をしているが、Excel のすごいところは VBA でマクロが組めることにある。Libra Office Calc は何まで できるのだろうか。
(Python を実行するのに Java Runtime Environment(JRE) がいるのか。また今度にしよ)
Unity で開発しているゲームの 補助 として使いたいので、C#言語でもあればベストだったんだが無いし、Java Script も Java の上で動かすようだ。
Unity で Java は使わないので JRE をインストールしてない。ボタン1発でインストールできはするが……。使用者としては 相性が悪い。
Libre Office Basic マクロ とは何だろうか。
とりあえず様子見で 新規作成してみよう。
今作ったばかりの「無題1」ブックに マクロを新規作成してみたい。
じゃあ、シートに ボタンを置いて、そのボタンを押すとマクロを実行するようにして、それで ファイル読み込み とかできるのだろうか?
分かり次第、この記事に追記していきたい。
#Libre Office Basic のおべんきょをしよう
新人・若手SE スキルアップnavi 「LibreOfficeマクロ入門講座 最低限知っておきたいこと」
http://seskillup.jp/libreoffice-maro-beginner/
このサイトを頼りに コーディングを進めてみる。
新人・若手SE スキルアップnavi 「【LibreOffice マクロ】実行方法」
http://seskillup.jp/%E3%80%90libreoffice%E3%83%9E%E3%82%AF%E3%83%AD%E3%80%91%E5%AE%9F%E8%A1%8C%E6%96%B9%E6%B3%95/
help.libreoffice.org 「ボタンを挿入して編集する」
https://help.libreoffice.org/Common/Inserting_and_Editing_Buttons/ja
(VTJ [表示(V)] - [ツールバー(T)] - [フォームコントロール(J)])
あれっ? 日本語版にした覚えはないが 日本語だ。
これがボタンか。
(マウスでドラッグして シート上にボタンを配置して右クリック、[コントロール(T)]を選ぶ)
ここで色々設定できそうだ。
([イベント]タブをクリックし、[実行時]の横の[…]ボタンを押下)
今、デザイン・モードになっていると思うんだが、どこかに デザイン・モードを解除するボタンがあるはず。
ファイルの入出力も、このあと 記事に追記していきたい。
#マクロでシートが追加できない
なんだか サンプル・プログラムが動かない。やっぱ Java 入れてみるか……。
##Javaをインストールしよう
Java
https://www.java.com/
ここからボタン1発でインストールできる。
([無料Javaのダウンロード]ボタンをクリック)
##マクロのセキュリティを[高]から[中]へ下げよう
(Libre office calc を再起動したぞ)
あれっ? Java とか関係なくてセキュリティの問題だったのか?
(TO [ツール(T)] - [オプション(O)])
(Y [LibreOffice] - [セキュリティ] - [マクロセキュリティ(Y)])
トップ画面から [ALT]キーを押しっぱなしにして [T][O][Y] (トイ)で マクロセキュリティ―に行けるじゃないかwwwwwww
続きはまた、この記事に追記していきたい。
#さて、マクロを編集するか……
Javaも入れて、マクロ・セキュリティーも下げたし、さて実行できるようになったのかどうか……。
(今度は[編集]をクリック)
##スマートクォート問題
(んっ? 前は出てこなかったエラーが出ている)
これって、コピペ・プログラマを悩ます「スマートクォート」問題じゃないのか。 Qiita の引用欄では解決できているからといって 他のブログでもそうであるとは限らないことをすっかり忘れていた。
#信頼のおけるソースにする
(それは置いておいて まだ実行できない)
どこまで マクロ・セキュリティーを下げればいいのか……。
(信頼のおけるソースにしておこう)
[Alt]+[T][O][Y] の出番だ。
マクロ・セキュリティーを**[低]にするのは嫌だ**。このフォルダーの中にあるマクロは 信頼する、という機能を利用しよう。
(Libre office を一旦閉じて、信頼するフォルダーの中のファイルをダブルクリック)
Libre office を再起動して叩き直し。
(マクロは実行されるようになった)
ようやく シートの1個を追加できるようになった。
続きはまた、この記事に追記していきたい。
#さすがに Libre office calc ブックを吐き出すプログラムはつらかろう
C#言語で CSV(comma separated value)ファイルを吐き出すのは簡単だ。ただのテキスト出力だ。シートを6つ程度吐くのも簡単だ。
できれば Libre office calc マクロの方で 6つのCSVを1つのブックに読込んでくれた方が楽ではないか。そういうボタンを作りたい。
#まずはワークブックの作成だ
##サンプル・プログラムを読み漁ろう
新人・若手SE スキルアップnavi 「【LibreOfficeマクロ】WorkBook作成、書込、保存、閉じる」
http://seskillup.jp/%E3%80%90libreoffice%E3%83%9E%E3%82%AF%E3%83%AD%E3%80%91workbook%E4%BD%9C%E6%88%90%E3%80%81%E6%9B%B8%E8%BE%BC%E3%80%81%E4%BF%9D%E5%AD%98%E3%80%81%E9%96%89%E3%81%98%E3%82%8B/
LibreOffice Calc Basic fun!!! 「ドキュメントを上書保存する」
http://calibreblo.blogspot.jp/2011/04/blog-post_4128.html
LibreOffice Calc Basic fun!!! 「名前を付けてドキュメントを保存する」
http://calibreblo.blogspot.jp/2011/04/blog-post_13.html
LibreOfficeへの道 「Dir 指定したドライブの現在のカレントパスを返します」
https://libreoffice.jimdo.com/%E9%96%A2%E6%95%B0-%E3%82%B9%E3%83%86%E3%83%BC%E3%83%88%E3%83%A1%E3%83%B3%E3%83%88-%E3%83%9E%E3%82%AF%E3%83%AD/d-%E3%81%A7%E5%A7%8B%E3%81%BE%E3%82%8B%E9%96%A2%E6%95%B0-%EF%BD%BD%EF%BE%83%EF%BD%B0%EF%BE%84%EF%BE%92%EF%BE%9D%EF%BE%84-%E3%83%9E%E3%82%AF%E3%83%AD/dir/
Libre Basic Ref 「Libre:025 ワークシート名を変更する」
http://librebasic.momiji-mac.com/?p=76
LibreOffice Calc Basic fun!!! 「シートの取得 (2)」
http://calibreblo.blogspot.jp/2011/04/2_18.html
#ブックを新規作成し、シートを6つ作って保存しよう
やっと分かってきた。
REM ***** BASIC *****
Sub Main
msgbox "Hello World!!"
Dim oSheet as Object ' シート
Dim oSheets As Object ' シートのリスト
Dim sheetName As String ' シートの名前
Dim oDoc As Object ' 新しいブック
Dim Dummy() ' 使わない引数に
Dim folder As String ' 信頼のおけるディレクトリ
folder = "C:\Users\Takahashi\Documents\muzudho\Unity\KifuwarabeFighter2\KifuwarabeFighter2\" 'どうにかならんのか
oDoc = StarDesktop.loadComponentFromURL("private:factory/scalc", "_blank", 0, Dummy()) ' ブックを新規作成
oSheets = oDoc.getSheets() ' シートのリストを取得
'--------------------------------------------------------------------------------
' 最初からあるシートを名前変更
oSheet=oDoc.Sheets(0)
oSheet.Name="Rensyu0"
'作成したシートへの書込
oSheet.getCellRangeByName("A1").String= "セルへの書き込み0"
'--------------------------------------------------------------------------------
' 2つ目のシートを作成
sheetName = "Rensyu1"
' シートを追加
if oSheets.hasByName(sheetName) = false then
oSheets.insertNewByName(sheetName,1)
end if
oSheet = oSheets.getByName(sheetName)
'作成したシートへの書込
oSheet.getCellRangeByName("A1").String= "セルへの書き込み1"
'--------------------------------------------------------------------------------
' 3つ目のシートを作成
' シートの名前
sheetName = "Rensyu2"
' シートを追加
if oSheets.hasByName(sheetName) = false then
oSheets.insertNewByName(sheetName,2)
end if
oSheet = oSheets.getByName(sheetName)
'作成したシートへの書込
oSheet.getCellRangeByName("A1").String= "セルへの書き込み2"
'--------------------------------------------------------------------------------
' 4つ目のシートを作成
' シートの名前
sheetName = "Rensyu3"
' シートを追加
if oSheets.hasByName(sheetName) = false then
oSheets.insertNewByName(sheetName,3)
end if
oSheet = oSheets.getByName(sheetName)
'作成したシートへの書込
oSheet.getCellRangeByName("A1").String= "セルへの書き込み3"
'--------------------------------------------------------------------------------
' 5つ目のシートを作成
' シートの名前
sheetName = "Rensyu4"
' シートを追加
if oSheets.hasByName(sheetName) = false then
oSheets.insertNewByName(sheetName,4)
end if
oSheet = oSheets.getByName(sheetName)
'作成したシートへの書込
oSheet.getCellRangeByName("A1").String= "セルへの書き込み4"
'--------------------------------------------------------------------------------
' 6つ目のシートを作成
' シートの名前
sheetName = "Rensyu5"
' シートを追加
if oSheets.hasByName(sheetName) = false then
oSheets.insertNewByName(sheetName,5)
end if
oSheet = oSheets.getByName(sheetName)
'作成したシートへの書込
oSheet.getCellRangeByName("A1").String= "セルへの書き込み5"
'--------------------------------------------------------------------------------
'C:test.odsとして保存
oDoc.storeAsURL(ConvertToUrl( folder & "sample.ods"), Dummy())
'ファイルを閉じる
oDoc.dispose
End Sub
このコードで、
ブックを作って、シートを追加して、セルに書き込んで保存できた。
次は CSVファイル読取 も調べてみたい。
続きはまた、この記事に追記していきたい。
#CSVファイルを読込もう
##まずはサンプル・プログラムを読み漁ろう
White Tiger 「CSVファイルを読み込む方法」
http://www7b.biglobe.ne.jp/~whitetiger/ex/liboffice032.html
OpenOffice.org Basic メモ
http://www.geocities.jp/penguinitis2002/computer/programming/OOo_basic.html
help.libreoffice.org 「Text Functions」
https://help.libreoffice.org/Calc/Text_Functions
##はいでけた
(CSVファイルを読込んだ。7つのシートを持ったブック)
LibreOffice には CSVファイルを読むという便利な関数が見つからなかったので、
自分で書いた CSVパーサー を LibreOffice Basic に書き直した。
ソースコードを置いておく。
REM ***** BASIC *****
Option Explicit
Sub Main
'msgbox "Hello World!!"
Dim oSheet as Object ' シート
Dim oSheets As Object ' シートのリスト
Dim sheetName As String ' シートの名前
Dim oDoc As Object ' 新しいブック
Dim Dummy() ' 使わない引数に
Dim folder As String ' 信頼のおけるディレクトリ
Dim file1 As String
Dim file2 As String
Dim file3 As String
Dim file4 As String
Dim file5 As String
Dim file6 As String
Dim file7 As String
folder = "C:\Users\Takahashi\Documents\muzudho\Unity\KifuwarabeFighter2\KifuwarabeFighter2\" 'どうにかならんのか
file1 = "C:\Users\Takahashi\Documents\muzudho\Unity\KifuwarabeFighter2\KifuwarabeFighter2\_log_(AniCon@Char3)parameters.csv" 'どうにかならんのか
file2 = "C:\Users\Takahashi\Documents\muzudho\Unity\KifuwarabeFighter2\KifuwarabeFighter2\_log_(AniCon@Char3)layers.csv" 'どうにかならんのか
file3 = "C:\Users\Takahashi\Documents\muzudho\Unity\KifuwarabeFighter2\KifuwarabeFighter2\_log_(AniCon@Char3)stateMachines.csv" 'どうにかならんのか
file4 = "C:\Users\Takahashi\Documents\muzudho\Unity\KifuwarabeFighter2\KifuwarabeFighter2\_log_(AniCon@Char3)states.csv" 'どうにかならんのか
file5 = "C:\Users\Takahashi\Documents\muzudho\Unity\KifuwarabeFighter2\KifuwarabeFighter2\_log_(AniCon@Char3)transitions.csv" 'どうにかならんのか
file6 = "C:\Users\Takahashi\Documents\muzudho\Unity\KifuwarabeFighter2\KifuwarabeFighter2\_log_(AniCon@Char3)conditions.csv" 'どうにかならんのか
file7 = "C:\Users\Takahashi\Documents\muzudho\Unity\KifuwarabeFighter2\KifuwarabeFighter2\_log_(AniCon@Char3)positions.csv" 'どうにかならんのか
oDoc = StarDesktop.loadComponentFromURL("private:factory/scalc", "_blank", 0, Dummy()) ' ブックを新規作成
oSheets = oDoc.getSheets() ' シートのリストを取得
'--------------------------------------------------------------------------------
' 最初からあるシートを名前変更
oSheet=oDoc.Sheets(0)
oSheet.Name="parameters"
'作成したシートへの書込
'oSheet.getCellRangeByName("A1").String= "セルへの書き込み0"
ReadCsv(file1, oSheet) ' CSV読込
'--------------------------------------------------------------------------------
' 2つ目のシートを作成
sheetName = "layers"
' シートを追加
if oSheets.hasByName(sheetName) = false then
oSheets.insertNewByName(sheetName,1)
end if
oSheet = oSheets.getByName(sheetName)
'作成したシートへの書込
'oSheet.getCellRangeByName("A1").String= "セルへの書き込み1"
ReadCsv(file2, oSheet) ' CSV読込
'--------------------------------------------------------------------------------
' 3つ目のシートを作成
' シートの名前
sheetName = "stateMachines"
' シートを追加
if oSheets.hasByName(sheetName) = false then
oSheets.insertNewByName(sheetName,2)
end if
oSheet = oSheets.getByName(sheetName)
'作成したシートへの書込
'oSheet.getCellRangeByName("A1").String= "セルへの書き込み2"
ReadCsv(file3, oSheet) ' CSV読込
'--------------------------------------------------------------------------------
' 4つ目のシートを作成
' シートの名前
sheetName = "states"
' シートを追加
if oSheets.hasByName(sheetName) = false then
oSheets.insertNewByName(sheetName,3)
end if
oSheet = oSheets.getByName(sheetName)
'作成したシートへの書込
'oSheet.getCellRangeByName("A1").String= "セルへの書き込み3"
ReadCsv(file4, oSheet) ' CSV読込
'--------------------------------------------------------------------------------
' 5つ目のシートを作成
' シートの名前
sheetName = "transitions"
' シートを追加
if oSheets.hasByName(sheetName) = false then
oSheets.insertNewByName(sheetName,4)
end if
oSheet = oSheets.getByName(sheetName)
'作成したシートへの書込
'oSheet.getCellRangeByName("A1").String= "セルへの書き込み4"
ReadCsv(file5, oSheet) ' CSV読込
'--------------------------------------------------------------------------------
' 6つ目のシートを作成
' シートの名前
sheetName = "conditions"
' シートを追加
if oSheets.hasByName(sheetName) = false then
oSheets.insertNewByName(sheetName,5)
end if
oSheet = oSheets.getByName(sheetName)
'作成したシートへの書込
'oSheet.getCellRangeByName("A1").String= "セルへの書き込み5"
ReadCsv(file6, oSheet) ' CSV読込
'--------------------------------------------------------------------------------
' 7つ目のシートを作成
' シートの名前
sheetName = "positions"
' シートを追加
if oSheets.hasByName(sheetName) = false then
oSheets.insertNewByName(sheetName,6)
end if
oSheet = oSheets.getByName(sheetName)
'作成したシートへの書込
'oSheet.getCellRangeByName("A1").String= "セルへの書き込み6"
ReadCsv(file7, oSheet) ' CSV読込
'--------------------------------------------------------------------------------
'C:test.odsとして保存
oDoc.storeAsURL(ConvertToUrl( folder & "sample.ods"), Dummy())
'ファイルを閉じる
oDoc.dispose
End Sub
'--------------------------------------------------------------------------------
' CSV読取
Sub ReadCsv(filename As String, oSheet as Object)
Dim fileHandle As Integer ' ファイルハンドル番号
fileHandle = Freefile
Open filename For Input As fileHandle ' 外部ファイルの内容をシートに読込む
Dim row As Integer
Dim source As String
row = 0
Do While not eof(fileHandle)
Line Input #fileHandle, source
'oSheet.getCellByPosition( 0, row ).String = source
CsvLineParser( source, row, oSheet )
row = row + 1
Loop
Close #fileHandle
End Sub
Sub CsvLineParser(source As String, row As Integer, oSheet as Object)
Dim caret As Integer
Dim column As Integer
Dim cell As String
If Len(source) < 1 Then
Exit Sub
End If ' 空文字列なら終わり
caret = 1 ' 文字列の文字目は1スタート
column = 0 ' テーブルの列は0スタート
'Do While caret < Len(source)
' oSheet.getCellByPosition( caret, row ).String = Mid(source,caret,1)
' caret = caret + 1
'Loop
'Exit Sub
cell = "" ' 1セル分の文字列
Do While caret-1 < Len(source) ' このループで1行分に対応
Select Case Mid(source,caret,1)
Case ",": ' トークンを出力して次へ。
caret = caret + 1
oSheet.getCellByPosition( column, row ).String = cell
column = column + 1
cell = ""
Case """":
' ここからリテラル文字列処理へ
caret = caret + 1
' エスケープしながら、単独「"」が出てくるまでそのまま出力。
Do While caret-1 < Len(source)
If """"=Mid(source,caret,1) Then
' これが単独の「"」なら終わり、2連続の「"」ならまだ終わらない。
If caret + 1 - 1 = Len(source) Then
caret = caret + 1
Exit Do ' 「"」が最後の文字だったのなら、無視してループ抜け。
ElseIf """" = Mid(source,caret+1,1) Then
caret = caret + 2
cell = cell & """" ' 2文字目も「"」なら、2つの「""」すっとばして代わりに「"」を入れてループ続行。
Else ' 2連続でない「"」なら、次の「,」の次までの空白等をスキップ。//【改変/】2012年10月30日変更。旧: index++;//【改変/】2017年02月01日変更。次のカンマの次まで飛ばした。旧: index+=2;
caret = InStr( caret, source, "," )
caret = caret + 1
Exit Do
End If
Else
cell = cell & Mid(source,caret,1)
caret = caret + 1 ' 通常文字なのでループ続行。
End If
Loop
oSheet.getCellByPosition( column, row ).String = Trim(cell) ' 前後の空白はカット
column = column + 1
cell = ""
Case Else: ' ダブルクォートされていない文字列か、ダブルクォートの前のスペースだ。
cell = cell & Mid(source,caret,1)
caret = caret + 1
End Select
Loop
End Sub
ボタンを押すと ブックを作ってくれるようなアプリケーションとして シートを1個作っておくと いいのかもしれない。
続きはまた、この記事に追記していきたい。
#ファイルパスをセルから取ってくるようにした
いまのところ これで良しとしよう。
' アクティブ・シートを取得
oSheet = ThisComponent.GetCurrentController.ActiveSheet
' ( column, row ) is 0 start.
folder = oSheet.getCellByPosition( 5, 12 ).String ' folder. end is "\"
file1 = folder & oSheet.getCellByPosition( 5, 16 ).String ' parameters.csv
file2 = folder & oSheet.getCellByPosition( 5, 18 ).String ' layers
file3 = folder & oSheet.getCellByPosition( 5, 20 ).String ' stateMachines
file4 = folder & oSheet.getCellByPosition( 5, 22 ).String ' states
file5 = folder & oSheet.getCellByPosition( 5, 24 ).String ' transitions
file6 = folder & oSheet.getCellByPosition( 5, 26 ).String ' conditions
file7 = folder & oSheet.getCellByPosition( 5, 28 ).String ' positions
これで Unity上のStellaQLウィンドウ が CSV を出力し、
LibraOffice の [CSV Import]ボタンを押すと 7つのシートを持ったブックが作られる。
#自動再計算させるには?
(セル番号を入力しても 数字を参照してこない)
何か設定があるのか。
続きはまた、この記事に追記していきたい。
##シートを作り直すと再計算されるが……
気まぐれな空 「LibreOfficeの更新に伴う数式の不具合について」
http://d.hatena.ne.jp/Aki270/20130824/1377316150
じゃあ シートを作り直そう。
どうも、マクロで作ったシートが再計算されない。すべてのセルが文字列だと思われているのだろうか。
どうもそのようだ。だが Standard に変えても再計算はされない。
Unityの方の話しなんだが、この Name というのは ステートのラベルのことだ。欲しいのは Name ではなくて FullName なのだった。
StellaQL の方に頑張ってフルネームを取ってきてもらうか。
続きはまた、この記事に追記していきたい。
#がんばってフルパスを引っ張ってきた
(D列の ParentPath を Unityのステートマシンを再帰ループして拾ってきた)
Parent Path と Name を連結した文字列を 数字にしたのが nameHash だと思うんだが、Unityを触っていてもいまいちよく分からん。
多分、Name は ステートに書いているラベルで、ステート自体は FullPath を持っていないので オブジェクトを辿って拾ってくる必要があるのだろう。
データが変わったので また CSVインポートして新しいブックを作りたいんだが、さて困った。
ビュー用のシートを せっせと作っているところなのに……。
ビューと インポート・データは 別ブックに分けて 読み取りに行く仕掛けにした方が良さそうだ。
続きはまた、この記事に追記していきたい。
#別ブック(別ドキュメント)のセルを引っ張ってこよう
(別ブックのシートのセルを、引っ張ってきた)
できるのか。 ファイルパス設定用のシートを作って 文字列連結させてみよう。
(CONFIGシートに ファイルパスが入っていて、それを文字列連結して INDIRECT( ) に入れると参照してくれる)
ややこしい。計算式のところが ぐちゃぐちゃになるのが嫌だ。
中間にシートを1つ用意しておいて、文字列連結は済ませてから 表の中で これを使うことにしよう。
この文字列のところに 自動連番が効くようにするには どうすればいいんだろう。調べるか。
続きはまた、この記事に追記していきたい。
#自動連番の数字を文字列化する
(末尾にM2、M3、M4……と付けたかったんだが、でけた)
& ADDRESS( ROW(セル番号), COLUMN(セル番号), 1, 1)
とすると、末尾にセル番号を文字列化して付けれるようだ。
CSVファイルの場合、シート名には ファイル名が入っていたので ややこしかったが、少しずつ仕組みが分かってきた。
ファイル名#シート名.行列番号
になってるわけだ。
これで、他のブックのセルを参照することは でけた。
続きはまた、この記事に追記していきたい。
#入力シートを自動作成できないか
こういう感じで、各パラメーターの更新を スプレッドシートに入力し、これを Unity 側でインポートして データ入力装置として使えないか、という試みだ。
- データ入力できるパラメーターはどれか?
- そのパラメーターは int, float, bool, string のいずれか?
- 空文字列にしたいときは delete フラグを指定すればいいか?
といったあたりだろうか。
例えば StellaQL に 列定義シート も吐き出してもらって、これをもとに LibreOffice Basic のマクロを使って ビュー・シートを作成してはどうか。
続きはまた、この記事に追記していきたい。
##列定義シートを作成
(StellaQL で出力した列定義シート)
これをひとまず ブックにまとめたい。
なんつーか Unity にデータベース連携機能がないので自分で なんちゃってデータベース風スプレッドシートを実装する。
データ・シートと、列定義シートができたので、なんちゃってデータ入力フォーム を作ろう。
続きはまた、この記事に追記していきたい。
#ひとまずビューを手作りしよう
(左が手作りで作成中のビュー、右は出力されたデータ)
空白セルを参照すると 0 と表示されるのは 書式 が数字にでもなっているのだろうか?
Excelでは @を使って 書式も設定できたような気がするが、覚えてない。
0 を空白に置換するスクリプトを書くより、書式設定で楽したい。調べてみよう。
というか、テキスト形式にしていて 0 と表示されるようだから、データ・シートの方で 空白は0だというふうに返しているんじゃないか。
データを出力するときに、書式をテキストに設定する方法を探してみよう。
運用で対応した方が 楽じゃないか。 文字列型に 0 が入っていれば空白扱い、本当に "0" が入っているときは……うーむ。区別はどうするのか。
IsBlank関数で 空白だけを調べることができるので、取ってきた値の列、IsBlankの列を2列余分に用意しておけば 空白は判定できるか。なんか無駄が多いけど。
なんかもっと便利な関数でも無いものか……。
続きはまた、この記事に追記していきたい。
#ビュー・シートを作るマクロを書こう
どうやったら Module2 が作れるのか見つからなかったんだが……
(新しいモジュールを作るダイアログボックス)
[新規作成(N)] ではなく、[管理(E)...] から進むと モジュールを作ることができるようだ。ややこしい……。
エンド・オブ・ファイル(ファイルの終わり)の記号 EOF を一応書いておく。
あっ、エンド・オブ・ライン(行の終わり)の記号 EOL も付けとこ。25年ぐらい前のエディタみたいだ。
ループが何をやっているのか 分かりやすくなった。
##EOFが役に立つ場面
(ずぼらな自動連番の途中で 抜けることができる)
続きはまた、この記事に追記していきたい。
#中間ファイルを作ろう
(シート名の末尾に _obj を付けた、中間ファイル)
データ・シート及び列定義シートから ビュー・シートに 1ステップで変換すると 不具合発生時の問題の切り分けができなかったことから、一旦、中間ファイルを挟むことにした。
中間シートは、
- 列定義シートに #Key、#FullPath という2つのフィールドを追加した
- 列定義シートから、「キー用フィールド」「表示用フィールド」「入力用フィールド」を残し、「出力用フィールド」を除外した
- せっかく表計算ソフトを使っているのだし、ヘッダー行の色を変えてみるという恩恵を得てみた
というものだ。オープンソースでやっているので ソースコードは後ほど まとめて GitHub で公開する。
この中間シートを タテヨコ入れ替えれば、ビューができそうじゃないか? プログラマーにも実行時の状態を把握する能力の負担があり、中間シートで労力を軽減することで むずかしさを減らすことができる。中間シート大切。
続きはまた、この記事に追記していきたい。
#ビューを作成した
##フィールドのスキップが勘所
(マクロで作ったビュー・シート)
入力できるフィールドだけカウントしていると ずれたので、出力しないフィールドは スキップする、といった処理も入れて、なんとか形はでけた。
列幅の自動調整にも 挑戦しているんだが 思った通りに動いてくれない。
続きはまた、この記事に追記していきたい。
##ウィンドウ枠も固定したし、できあがり
(アクティブ・シートを切り替えながら 表を作成すると 動きが見れる)
シートをアクティブにしながら メソッドを呼び出さないと 効き目がないメソッドがあるようだ。
列幅の最適化は 良く分からなかったので パスで。
これで ビュー・シート は でけたのではないか。
ひとまず Libre Office の記事を終わる。
#ソース公開中 Open source
https://github.com/muzudho/KifuwarabeFighter2