|11| sp. FileMakerでアウトライン

このサイトの記事内容があっちに行ったり、こっちに行ったりで書いている本人もわからなくなってしまうことがよくあります。文章力の無さですが、読んでくださる方々には迷惑な話です。少し、整理しながら記事を書かなければと思い、アウトライナーを使うことにしました。ネット上のworkflowyのフリー版が使い勝手も良さそうなのでそれを使い始めたのです。

しかし、どうもしっくりこないこともある。そう、画面キャプチャを取り込めないのです。アウトライナーとしては普通のことですが、画面キャプチャを見ながら記事を書く、あるいは記事を書きながら、必要なキャプチャを撮るということに慣れている私にはしっくりこないのです。
それまではFileMakerにキャプチャを取り込み、その横に記事を書いていましたのでFileMakerでアウトライナーを作ろうと無謀なことを考え始めたわけです。

今回は本来のテーマから外れたスペシャル編としてアウトライナーを作ってみます。

アウトラインの概要・サンプルデータ

このサイトはWordPressを使っていて、見出しレベルH1は投稿のタイトルになっています。見出しレベルはH6までありますが、個々の段落ですぐに設定できるのはH2〜H4までなので、H5、H6はほとんど使っていません。
過去の記事内容はFileMakerのレコード数で20〜40レコードぐらいなのでアウトラインとしては3階層の親子関係と1投稿の内容として最大60レコードぐらいを目処に考えてみました。

見出しレベル単位で展開・折りたたむ簡易バージョン

by Guantare.com

サンプルの画像データは私が普段設定しているピクセル数よりかなり少なく、
圧縮率もかなり大きくして全体の容量を減らしています。

 

H2、H3、H4の見出しレベル単位で一括して展開、折りたたむ仕様の簡易バージョンです。カレントテーブルはa02_投稿詳細TOで必要な時にアウトラインを表示する仕組みになっています。
アウトラインの左端にあるレコードの順番をクリックすることで、カレントテーブルにある同じ順番のレコードに移動することができます。
順番の入れ替えは下の階層を伴って入れ替えることができます。

見出しレベルを個別に展開、折りたたむバージョン

by Guantare.com

 

それぞれの見出しレベル単位で個別に展開、折りたためる仕様のバージョンです。簡易バージョン同様、見出しレコードの順番をクリックすることで、カレントテーブルにある同じ順番のレコードに移動でき、下の階層を伴って順番を前後に入れ替えることができます。

テーブル構成

テーブルの概略としては投稿テーブルと投稿詳細(記事)テーブルになります。タグのテーブルもありますが、今回は中身が空っぽです。

記事本文には関連付けられる見出しレベルがあったりしますが、本文そのものは文章の体裁上、フラットな関係になるので、同じテーブルのレコードに入力します。それぞれのレコードには見出しレベルのフィールドと見出しのフィールドがあり、見出しレベルのフィールドを利用してアウトラインを作ろうというものです。

投稿テーブル

 

画面キャプチャ:投稿と投稿詳細のリレーションシップマップ

投稿IDが投稿詳細テーブルの全てのレコードに入力されるようにしてあり、投稿テーブルと投稿詳細テーブルに投稿IDをキーとしたリレーションが組まれています。

 

画面キャプチャ:投稿のリスト表示とそのレイアウト上の投稿詳細のポータル

アイキャッチ画像

私がWordPressで使っているのはLionMediaというフリーのテーマで、アイキャッチ画像は1投稿に1点となっています。投稿テーブルのリストにはアイキャッチに選定された写真が表示されます。この画像は投稿詳細レコードに入力された画像の中で、アイキャッチのフラグを立てたものが表示される仕組みです。これは投稿詳細のポータルに最初の1行だけを表示させ、アイキャッチフラグのフィールドで降順にソートさせただけのものです。

見出しレベル表示

投稿テーブルでの見出し表示は投稿詳細のポータルにポータルフィルターを設定し、見出しレベルで表示を切り替えています。投稿テーブルと投稿詳細テーブルは一つのリレーションで成り立っています。このポータルは移動や入れ替えの機能はありません。見出しレベルによって投稿の概要を表示しているだけです。

投稿詳細(記事)テーブル

投稿詳細テーブルのレコードには画像のフィールド1個と記事本文のフィールド、見出しレベルや見出しのフィールドなどがあります。

記事本文はすべてフラットな関係になるので見出しレベルによってテーブルを変えずに、階層化しています。こうすることによって、見出しレベルを変更しても簡単に対応することができます。

自己リレーション

このテーブルでは同じテーブル同士で自己リレーションを組んでいます。ポータルフィルターを使うことも考えましたが、今までの経験から慣れている複数行のキーを使ったリレーションにしました。

複数行のキーというのは、投稿詳細の見出しレベルにはH2、H3、H4の3種類の文字列が入力されているので、見出しレベルのキーになるフィールドに「H2¶H3」と入力するとH2とH3の見出しレベルを持つレコードが関連づけられる仕組みです。

以前はリレーションキーに文字数制限があったような気がしていたので、12桁のIDを持つレコードを10000件作って、12桁10000行のキーで10000件のレコードと関連付けられるか試してみましたが、問題はありませんでした。

両方に共通する基本的な動き

二つのバージョンの違いは展開したり、折りたたむ仕組みが異なるだけで共通する項目が多くあります。

レコードの順番作成

投稿詳細テーブルでは新規レコードを末尾に作ったり、あるレコードの前あるいは後ろに作ったりできます。また、あるレコードを前にあるいは後に移動することで順番を入れ替えることもできます。レコードの並びはレコードに振られた順番という整数の数字でソートされる仕組みです。例えば、前に新規レコードを追加する場合は現在、選択しているレコードの順番から0.1引いた数字を新しいレコードの順番に入れてソートし、最初のレコードから整数の順番を振り直しています。この時に個別に展開するバージョンではアウトラインで必要なキーコードを書き換えたりしています。見出しレベルを変更した時も順番作成のスクリプトを走らせています。

レコードが増えれば増えるほど時間がかかり、レスポンスが悪くなります。

レコードへの移動、順番入れ替え

アウトライン上での順番入れ替えは下の階層も含めた入れ替えになるので0.001単位で足したり引いたりしています。このアウトラインで一度に入れ替えできるのは999レコードまでになります。0.0001単位にすればもっと増えるのですが、私の使い方であれば999レコードで十分です。999レコードまでというのは一度に移動できるレコード数なのですが、実際には1件の投稿の投稿詳細レコードが1000件以上になると順番作成のスクリプトが動かないようにしてあります。

レコードへの移動

これはアウトラインのポータルで順番の数値を取得して、カレントテーブルの同じ順番のレコードに移動するというものです。ここで重要なのは順番が1から始まる整数で、欠番や重複がないようにしなければならないことです。同じ順番のレコードを探しているわけではなく、順番と同じレコード番号のレコードに移動しているだけなので必ず整数の連番でなければなりません。

順番の入れ替え・前へ

 

画面キャプチャ:投稿詳細レコードのリストでH2レベルを前に入れ替える時のリストの位置

レコードを遡っていき、同じ見出しレベルかそれより大きい見出し(数字が小さい)を探し、その順番から1を引いた数字を取得します。元の位置に戻って、取得した数字に0.001足して次のレコードに移動して、0.001を足していきます。同じ見出しレベルかそれより大きい見出しレベルになるまで繰り返し、ソートして順番を振り直します。

一番最初のレコードはそれ以上前には行けないので、それぞれの見出しレベルの先頭はグループレベルで判断しています。グループレベルは順番作成の時に作成しています。

順番の入れ替え・後ろへ

 

画面キャプチャ:投稿詳細レコードのリストでH2レベルを後ろに入れ替える時のリストの位置

レコードを後ろへ下っていき、同じレベルかそれより大きいレベルの見出しを探しますが、そこはその見出しレベルの先頭でその下の階層が続いているはずですから、さらに後ろに下っていきます。次の同じレベルか大きいレベルの順番とその前の順番の数字を取得し、その間の数字を振っていくことになります。ただ、最初に出会った見出しが最後の見出しだとその次がありません。最後の見出しだとわかっていれば対象レコード数が最後の順番になるので、それ以降の番号を振れば良いことになります。最後の見出しレベルには順番作成の時にフラグを立てておきます。

一括で展開、折りたたみのバージョン

簡単な仕組みでアウトライン表示ができるように見出しレベルでのリレーションを組んであります。

見出しレベルでのリレーション

 

画面キャプチャ:簡易バージョンでの投稿詳細同士の自己リレーションのリレーションシップマップ

すべての投稿詳細レコードに投稿IDが入力されていますから、キーの一つは投稿IDになります。もう一つのキーは見出しレベルになります。

a02_g_見出しレベルkeyフィールドとa02_見出しレベルフィールドでリレーションを組みます。a02_g_見出しレベルkeyフィールドにはキーとして「H2」「H2¶H3」「H2¶H3¶H4」の3パターンを入力します。a02_g_見出しレベルkeyフィールドが「H2」の場合はa02_見出しレベルフィールドが「H2」のレコードだけ、a02_g_見出しレベルkeyフィールドが「H2¶H3¶H4」の場合はa02_見出しレベルフィールドが「H2」と「H3」と「H4」のレコードが関連づけられるわけです。

個別に展開、折りたたみができるバージョン

リレーションの仕組みは簡易版と同じですが、キーが異なります。

H2はアウトライン上に必ず表示されるので「H2」をキーとして使います。H3には親になるH2の投稿詳細ID、H4には親になるH3の投稿詳細IDを割り振ります。これらのキーは順番作成の時、a02_グループ親キーフィールドに入力されます。

投稿詳細IDによる自己リレーション

 

画面キャプチャ:個別バージョンでの投稿詳細同士の自己リレーションのリレーションシップマップ

H3やH4を一括で展開する場合でも、展開後に個別に折りたたむことを考えると「H3」や「H4」は使えません。

H3を一括で展開するにはアウトライン上にあるH2全てのIDを取得し、それぞれを改行で区切って複数のキーとしてa02_g_見出しレベルkeyフィールドに入力します。

同じようにH4を一括で展開するにはH3全てのIDを取得し、a02_g_見出しレベルkeyフィールドに入力し、a02_グループ親キーフィールドとの間でリレーションを組みます。

リレーションキーの追加と削除

H2の子供のH3を展開するには、H2のIDを取得してキーに加えます。H3の子供のH4を展開するにはH3のIDを取得してキーに加えます。

H3とH4が展開されているH2を折りたたむ時にはH2のIDとH3のIDを取得してPosition関数とReplace関数を使ってキーから削除します。Replace関数の中でPosition関数で取得した文字位置から1を引いているのは前にある改行コードを削除するためです。改行コードがあっても問題ないのですが、検証するときに空行が増えて検証しづらくなるので削除してあります。
下はスクリプトの一部です。

変数を設定 [ $格納キー ; 値 : a02_自己_投稿詳細::a02_投稿詳細ID ]
 ・
 ・
 ・
フィールド設定 [ a02_g_見出しレベルkey ; 
             Let ( 
                    [ V文字位置 = Position ( a02_投稿詳細::a02_g_見出しレベルkey ; $格納キー ; 1 ; 1 ) ] ; 
                 Replace ( a02_投稿詳細::a02_g_見出しレベルkey ; V文字位置 – 1 ; Length ( $格納キー ) + 1 ; “” ) 
                     )
       ]

アイコンの表示・非表示

アウトラインのポータル上には様々なボタンが並びます。展開、折りたたみボタンは必要な時だけ見えるようにしておいた方がスッキリします。

展開・折りたたみボタン

 

画面キャプチャ:インターフェースとしてのポータル画面のボタンの表示・非表示

展開と折りたたみボタンはどちらかが見えていればいいわけなので、展開しているのか折りたたまれているのか判断できるようにフラグを立ててあります。

孫子の件数とそのリレーション

 

画面キャプチャ:親子件数を表示するための投稿詳細同士の自己リレーションのリレーションシップマップ

子供がいないのに展開ボタンが表示されていてボタンをクリックしても何も変化がないのではユーザーにストレスが溜まります。子供がいない時には隠してしまいましょう。このボタンを隠すためだけになりますが、リレーションを組んで子供の件数を計算します。

順番入れ替えボタン

前と入れ替えられない先頭のポータルレコード、後ろと入れ替えられないポータルレコードでは移動アイコンを隠します。

これは両方のバージョンに共通です。

このアウトライナーでできないこと

そこそこアウトライナーらしくなったとは思いますが、普通のアウトラインの様には出来ないこともあります。

H4の前後順番入れ替え

H2の最初のH3、そのH3の最初のH4見出しレベルを前の見出しレベルと入れ替える場合、親の親であるH2を飛び越えて、その前のH2の最後の順番になるのが理想ですが、親のH3とその親のH2の間に入ります。
H2の最後のH3、そのH3の最後のH4見出しレベルを後ろの見出しレベルと入れ替える場合、次のH2とH3の間に入ります。

これはスクリプトの組み方で是正できるのですが、前や後ろのH2にH3見出しレベルが作成されていない場合にどうするのかという難しい問題が出てきます。試行錯誤しましたが条件分岐が複雑すぎて、目視レベルで対応していくのが現実的かなと判断し、途中で諦めてしまいました。

見出しレベルの変更

見出しレベルの変更はアウトライン上ではできません。下の階層の取り扱いなど難しく、そこまで作り込むスキルはありません。変更したい見出しレベルの順番をアウトライン上でクリックし、カレントテーブルでそのレコードに移動して変更します。親子関係とは無関係に見出しレベルだけを変更する仕様です。

レスポンス

アウトラインを作っていて一番気になったのが、レスポンスです。単純に考えると対象となるレコード件数が多ければ多いほどレスポンスは悪くなります。また、使っているマシンの状態、バックグラウンドで他のタスクが動いていたりすると遅くなります。

私の体感では処理時間が0.3秒未満だと速く感じ、0.4秒で「ん?」となり、0.5秒を超えると「んんん?」となりますが、「1秒」を超えると「頑張ってるね」と思ってしまいます。

スクリプトの基本

スクリプトのほとんどはレコードの移動です。ひたすらLoopさせています。検索なども試してみましたが、レコード移動の方が速いと感じました。そしてポータル内での動きは最小限にして、カレントテーブルで動かすことでレスポンスを稼いでいます。本当に単純なスクリプトばかりですが、スクリプトの順番を間違えたり、ポータルのフィールドとカレントテーブルのフィールドを間違えたり、慎重さに欠ける私には何度もやり直す面倒な作業でした。中でも条件分岐が難しいと感じています。

マシン性能

動画の中に経過時間が映っています。使っているマシンは2015年製のMacBook12、CPUはCore M 1.3GHz、MacBook12の中では速いマシンでしたが、当時のMacの中でMacBook12は一番遅いマシンです。メモリは8GB、ストレージは500GBフラッシュ(空き領域は49GB)という構成です。

ファイル容量

 

サンプルには600レコードの投稿があります。これで試すとレコード数が8倍ですから動画より遅い!

サンプルは7MB程度の容量ですが、ファイル容量が大きくなるとどうなるのでしょうか?

600レコードの最初のレコードに飛行機の写真が入力されています。写真が3.5MBぐらいありますが、フィールドの全置換で600レコード全てに同じ写真を入力します。ここで一旦、FileMakerを閉じて容量を確認してみてください。あまり変化していないと思います。

もう一度開いて「画像Export」ボタンをクリックすると600枚の写真が異なるファイル名で「pct_expt」フォルダにエクスポートされます。さすがに時間がかかります。書き出された写真をフォルダ単位でインポートします。「対象レコードの既存のレコードを更新」でインポートすると順番はバラバラですが、600レコードに違うファイル名の写真がインポートされます。これも時間がかかります。FileMakerの容量は3.5MB×600で2GBぐらいと思っていたら、??? 3GB近くになってしまいました。2GBと3GBの差はさて置き、この状態でアウトラインを試して、そのレスポンスを体感してみてください。

試した結果はどうでしょうか? このレスポンスをどのように評価するでしょうか?

データベースの容量を減らすには最初のレコードを対象外にして、それ以外のレコードの写真を削除、フィールドの全置換で写真は無くなります。「pct_expt」フォルダに書き出された写真も削除してマシンの空き容量を増やしておきましょう。

 

・・・・・・・・・・・・・・・・・・・・・・・・・・・
最後に考えることは、このアウトラインはツールに過ぎず、これを使ったからといって良い文章が書けるとは限らない。わかりやすい文章を書くにはツールを利用しつつ、うまく整理することができるかどうか、私の思考回路の問題だと考えねば!


水面に木々が映り込む御射鹿池の写真

日本画家東山魁夷の「緑響く」のモチーフとしても有名な御射鹿池(みしゃかいけ)。
この日は明け方まで雨の降っていて、昼過ぎの御射鹿池は薄く靄がかかり、しっとりしていました。
Nikon D50 18-55mm 38mm ISO1600 1/125 F6.3 0.0EV P
Raw SILKYPIX
2017/6 Chino City