FileMakerで作るメディア管理の作成と育成、第5弾。前回インポートを作ったので今回はエクスポートを作っちゃいます。もうひとつ、フィルター機能も乗せました。インポート、フィルタ、エクスポート。最低限の実用の流れが果たせることになりました。
作成と構築 R5 の概要と使い方
実作編改め作成と構築、今回 R5 は二つのネタがあります。エクスポートとフィルタです。どちらも高機能とは言えませんが、かと言ってカスいわけでもなく、まあまあいい線です。第一期と思えば上等じゃないかと自画自賛。
MediaDB R5
FM v19 ファイル、ご自由にどうぞ。一部機能がMac用です。
Update 2023.04.22(エクスポートの不出来を修正)
- エクスポート設定パネルを使って書き出しが出来ます
- いくつかの分類項目でレコードをフィルタ(絞り込み)できます
- セッション名を好きに変更できます
- その他、スペースキーでプレビュー、矢印キーでレコード移動、代替アイコン、ビデオのキャプチャサムネイルなど、これまでの機能はもちろん踏まえています
ダウンロードしたファイルは何も入っていないので適当にメディアをインポートして使ってみてください。
エクスポート設定パネル
エクスポートはオブジェクトフィールドのメディアを指定フォルダに書き出します。画像ならリサイズできます。エクスポートパネルで設定してボタンぽんです。
簡単なパネルで済むと思ったら可能性の渦に飲み込まれ、多くの設定項目が出来てしまいました。隠すを駆使してもちょっと雑な印象になっています。
リサイズするかオリジナルを書き出すか
最初の重要設定は、サイズ変更するかオリジナルをそのまま書き出すのかの選択です。ターゲットが汎用的な画像ファイルならリサイズして書き出せます。
一つのファイルか、対象レコードか
次も重要設定、レコードから一点だけ書き出すのか、対象レコードをごっそり書き出すのかの設定です。どちらか選んでください。
ファイルの名前
ファイルの名前はいろいろ出来ます。「ファイル名を変更」ボタンで詳細設定が出てきます。
オリジナルファイル名の前後に追加するテキスト、そもそもオリジナルファイル名を使用するしないのボタンも真ん中にあります。
さらに連番が付けられます。対象レコードを選んでいれば「連番を使用」ボタンで詳細が出てきます。セパレータ( – とか)と番号( 01とか )を入力、さらに、ファイル名の前に付くか後ろに付くかまで設定できます。最初の番号のところで001と3桁で書けば連番も3桁になります。ちょっと懲りすぎ?
設定したら、下方に完成形のサンプルファイル名が現れます。
ちょいやり過ぎ系ですが可能性考えたらこうなった。
イメージのリサイズ設定
汎用的な画像ファイルでは、リサイズして書き出せます。
元のサイズより大きくはできません。クロップもありません。比率が保たれます。
名前変更とリサイズを組み合わせて対象レコードをだーっと書き出せるというのは、少しは実用できそうですか?
私個人は、メディア管理に求めるのが1に検索2にフィルタ、34抽出5に分類。でありまして、だから以前の実作編でも、エクスポートは最後の最後にようやく軽く搭載しただけでした。でも世間ではもしかすると「読み込んで、フィルタして、書き出す」という流れが王道なのかも知れないと、エクスポート機能を先に追加しました。
読み込んで、フィルタして ・・・そうすね、フィルタもついでに少し充実させました。
フィルター
簡易と言うほど簡易でもなく、高機能というにはそれほどでもない、それが何かと言うたなら、R5 のフィルタ機能でございます。
登録方法、セッション、FMType、拡張子、そして検索窓。これらでフィルタできます。
and 検索です。絞り込んでいきます。
自慢しとる場合やなくて、「動的値一覧」にもしていないので、検索結果が0の項目もポップアップに出てきてしまいます。今の時点ではこれ以上突っ込みませんのでご了承ください。
セッションの名前を変更できます
セッション名を変更できるようにしました。
セッションとは、フォルダインポート時の指定フォルダ(のパス)です。パスが自動で保存されますが、表示用はフォルダの名前です。この部分を好きな名前に変更できるようにしました。これにより、管理上の使い勝手がよくなります。
大雑把には以上です。
他に、レイアウトデザインが変更されたり細かい変化があります。ファイルをダウンロードして触ってみてください。今回はフリースペースもありますんで、お好きなフィールドを追加するもよしです。
仕組みの概要
ここからは、動作の詳細や仕組みに興味がある方にお届けします。
エクスポート [ 第一期版 ]
エクスポートパネルを作り始めたときは舐めていましたが、選択肢がいろいろあって複雑になり、フィールドも増えました。
最初は設定の記録をグローバル変数で済ませていました。でもそうすると、設定パネルが即座に変更に追随せず、設定ボタンすべてに「再表示」のスクリプトを仕込んで発動しなければならなくて、かえって面倒なことになりました。それならフィールド化した方がよほどシンプルであると結論づけ、全部フィールドとなりました。
上から、オリジナルかリサイズか、レコードが対象レコードか、名前を変更するかどうか、連番を使用するかどうか、元のファイル名を使うかどうか、連番がファイル名の前か後か、いちいち全部フィールドです。
ファイル名の前後のテキスト、連番の指定、セパレータ、リサイズの指定値と続きます。
メインテーブルでは大事なのはオブジェクトフィールドだけですが、こちらも名前やパスをフィールドで保存しています。
オブジェクトフィールドにリサイズした画像が入り、これを書き出します。「オリジナル」指定のときは、メインのオブジェクトフィールドから書き出します。
エクスポート設定パネルはごちゃごちゃしていますが、スクリプトそのものはシンプルです。分岐が多いだけで、結局は「フィールド内容のエクスポート」するだけですから。
ファイル名と連番にこだわったせいで、名前を決定させる計算式だけはちょっと複雑なことになっています。
書き出し名を決定する計算式はこんな感じです。眠くて面倒なのでたらたら式を並べていますが。
Let ( [ sep = 設定::sep; sNTemp = 設定::startNum ; digits = Length ( sNTemp ); sN = Right ( "0000000000" & sNTemp + Get ( レコード番号 ) - 1 ; digits ) ; addSN = If ( 設定::NumberPosition = "前" ; sN & sep ; sep & sN ); addsN = If ( 設定::export = 1 ; "" ; addSN ) ; bN = 設定::addBeforeName ; aN = 設定::addAfterName ; fN = If ( 設定::useFileName = 1 ; Substitute ( MediaDB::ファイル名 ; "." & MediaDB::拡張子 ; "" ); "" ); name = If ( 設定::NumberPosition = "前" ; addSN & bN & fN & aN ; bN & fN & aN & addSN ) ; fileName = name & "." & MediaDB::拡張子 ]; fileName )
セッションの名前
フォルダからインポートを行うと、指定したフォルダパスをセッションとして保存します。実際はフォルダパスですが、文字が長いので最後のフォルダだけを抽出したものを「セッションフォルダ名」というフィールドに置いていました。これを好きに変更できます。名前を変えても実態はパスです。見た目だけの問題なので管理しやすい名前に変更できるのは、これは良いことですね。
セッションフォルダ名は sessionFolderName というフィールド名でしたが、sessionName と変更しました。目的と名前が一致しました。
さて保存したセッションパス、再利用するために「選びやすい分類」としても保存しています。つまり値一覧に仕込んであります。値一覧に仕込んだので、フィールド入力もポップアップでできます。
セッション名を変更するのを許したので、フィールドにスクリプトトリガを仕込みました。内容が変更され保存されると発動します。
新規ウインドウを開いて同じセッションを検索し
↓
今変更したセッション名を全置換で全員にセット、
↓
ウインドウを閉じます。
目にもとまらぬ早さで処理が済むので使用者には何が起きたか見えません。
フィルター機能 [ 第一期版 ]
「セッションフォルダを値一覧に登録し」と、しれっと書きました。値一覧にフィールドを指定するのは便利なことに繋がります。フィールドの設定で値一覧からの入力が使えますから。
グローバルな入れ物フィールドをレイアウトに置いて、表示を値一覧にし、スクリプトトリガで検索スクリプトを仕込むとあっというまにフィルター機能が実装できます。
現時点でのフィルター機能は暫定的なものです。フィルタ項目が少ないから成り立っているところもあります。
グローバルフィールドに汎用性を持たせず、決め打ちフィールドにするんです。「GLB_登録方法」「GLB_FMType」とか。これにより、グローバルフィールドの内容と検索する実際のフィールドが1対1の関係となりますから、検索モードで直接フィールドに内容をたたき込めます。
スクリプトで何をやっているかざっくり言うと次の通りです。
検索フィールドに中身があるかないかを最初に見ます。
↓
もしあれば先にクイック検索を済ませます。
↓
結果があれば、さらに各分類フィールドを「絞り込み」で検索します。
↓
検索フィールドが空なら、分類フィールドで「検索」します。
ポイントは、各フィルタフィールドの中身が空だった場合は検索モードで空にするのではなく「*」を入力することですね。
このやり方はスクリプトがシンプルでいい案配ですが、分類項目が増えてくると鬱陶しいことになるかもしれません。分類が少ないからこそ成り立つ、暫定的というのはそういうことです。
課題
何か機能を追加するとすぐさま不満が出てきて次への課題が発生します。
インポートができて、登録したレコードをフィルタできて、そしてエクスポートができるようになりました。
第一期的にはそれで十分かと思いきや、試用しているとフィルタだけでは満足出来ないことを自覚するでしょう。
それはセレクトです。
一般的なメディア管理では、シフトキーやコマンドキーを押しながらクリックし、複数のメディアを選択しますね。これが我が実作編、作成と構築Rのファイルではできません。シフトやコマンド押しながらというのは無理だと思うんで、せめて例えば「セレクトボタン」みたいのを付けてチェックしていくとか、そうやって選択していきたいものですね。
付録:スクリプトの詳細
自分以外の誰の役に立つのか不明ですが、いくつか詳細を掲載しておくのです。
検索とフィルタ
検索窓とポップアップ検索を一緒くたにした簡易なand検索のスクリプトです。これまでは検索窓とポップアップ検索を別個のものとしてスクリプトを分けていましたが、一緒にしたほうがむしろ簡単に絞り込めることに気付きました。
#検索フィールド 変数を設定 [ $find ; 値: 設定::検索用フィールド ] #登録方法 変数を設定 [ $登録方法; 値:If ( IsEmpty ( 設定::popup_登録方法 ) ; "*" ; 設定::popup_登録方法 ) ] #sessionFolderFM 変数を設定 [ $session; 値:If ( IsEmpty ( 設定::popup_sessionFolder ); "*" ; 設定::popup_sessionFolder ) ] #FMType 変数を設定 [ $FMType; 値:If ( IsEmpty ( 設定::popup_FMType ); "*" ; 設定::popup_FMType ) ] #拡張子 変数を設定 [ $拡張子; 値:If ( IsEmpty ( 設定::popup_拡張子 ); "*" ; 設定::popup_拡張子 ) ] If [ not IsEmpty ( $find ) ] #$find があればクイック検索 エラー処理 [ オン ] クイック検索の実行 [ $find ] If [ Get ( 最終エラー ) ≠ 0 ] 全レコードを表示 対象外のみを表示 Else If [ not IsEmpty ( 設定::popup_登録方法 ) or not IsEmpty ( 設定::popup_sessionFolder ) or not IsEmpty ( 設定::popup_拡張子 ) or not IsEmpty ( 設定::popup_FMType ) ] #post_type post_status があれば絞り込む 検索モードに切り替え [ ] フィールド設定 [ MediaDB::登録方法; $登録方法 ] フィールド設定 [ MediaDB::sessionFolderFM; $session ] フィールド設定 [ MediaDB::FMType; $FMType ] フィールド設定 [ MediaDB::拡張子; $拡張子 ] エラー処理 [ オン ] 対象レコードの絞り込み [ ] End If End If Else #$find がなければpopupフィールドを検索 検索モードに切り替え [ ] フィールド設定 [ MediaDB::登録方法; $登録方法 ] フィールド設定 [ MediaDB::sessionFolderFM; $session ] フィールド設定 [ MediaDB::FMType; $FMType ] フィールド設定 [ MediaDB::拡張子; $拡張子 ] エラー処理 [ オン ] 検索実行 [ ] End If
フィールドごとの内容をクリアするスクリプトも用意しておきます。ボタンの横に置いて、特定グローバルフィールドを空にします。フルフィールド名をスクリプト引数に書いておくことで使いまわし可能に。
#ボタンに仕込んでスクリプト引数のフィールドをクリアする
変数を設定 [ $fld; 値:Get ( スクリプト引数 ) ]
フィールドを名前で設定 [ $fld; "" ]
スクリプト実行 [ 「検索とフィルタ【R5】」 ]
エクスポートのスクリプト
エクスポート設定パネルに配置したグローバルフィールドの内容に基づいて「フィールド内容のエクスポート」を行うスクリプト。
基本は単純だけど以下の分岐それぞれ作っていきます。
- レコードを書き出す
- オリジナルを書き出す
- リサイズして書き出す
- 対象レコードを書き出す
- オリジナルを書き出す
- リサイズして書き出す
対象レコードになるとループや全置換が入ってきて面倒くささアップ。
#***************************************************** #オブジェクトをエクスポート #***************************************************** #----------------------------------------------------- ## ポップオーバーかもしれないので一応閉じるスクリプトを入れておく スクリプト実行 [ 「ポップオーバー閉じる【R4】」 ] ## カード表示かもしれないので閉じるを入れておく If [ Get ( ウインドウスタイル )=3 ] ウインドウを閉じる [ 現在のウインドウ ] End If #----------------------------------------------------- #エクスポートパネルで設定済みであることが前提 変数を設定 [ $folderPathFM; 値:設定::sessionFolderFM ] 変数を設定 [ $original; 値:設定::original ] 変数を設定 [ $export; 値:設定::export ] If [ $export = 1 ] #--------------------------------------- #レコード単体を書き出す #--------------------------------------- #書き出しファイル名とパス(オリジナル、サイズ変更 共通) フィールド設定 [ MediaDB::exportName; Let ( [ sep = 設定::sep; sNTemp = 設定::startNum ; digits = Length ( sNTemp ); sN = Right ( "0000000000" & sNTemp + Get ( レコード番号 ) - 1 ; digits ) ; addSN = If ( 設定::NumberPosition = "前" ; sN & sep ; sep & sN ); addsN = If ( 設定::export = 1 ; "" ; addSN ) ; bN = 設定::addBeforeName ; aN = 設定::addAfterName ; fN = If ( 設定::useFileName = 1 ; Substitute ( MediaDB::ファイル名 ; "." & MediaDB::拡張子 ; "" ); "" ); name = If ( 設定::NumberPosition = "前" ; addSN & bN & fN & aN ; bN & fN & aN & addSN ) ; fileName = name & "." & MediaDB::拡張子 ]; fileName ) ] 変数を設定 [ $filePathFM; 値:$folderPathFM & MediaDB::exportName ] If [ $original = 1 ] #--------------------------------------- #オリジナルを書き出す #--------------------------------------- フィールド内容のエクスポート [ MediaDB::オブジェクト; 「$filePathFM」; フォルダを作成:はい ] Else #--------------------------------------- #変更して書き出し #--------------------------------------- フィールド設定 [ MediaDB::exportObject; GetThumbnail ( MediaDB::オブジェクト ; 設定::ExportSizeWidth ; 設定::ExportSizeHeight ) ] フィールド内容のエクスポート [ MediaDB::exportObject; 「$filePathFM」; フォルダを作成:はい ] End If Else #--------------------------------------- #対象レコードの書き出し #--------------------------------------- If [ $original = 1 ] #--------------------------------------- #オリジナルを書き出す #--------------------------------------- #fileName フィールド内容の全置換 [ MediaDB::exportName; 計算で置き換える: Let ( [ sep = 設定::sep; sNTemp = 設定::startNum ; digits = Length ( sNTemp ); sN = Right ( "0000000000" & sNTemp + Get ( レコード番号 ) - 1 ; digits ) ; addSN = If ( 設定::NumberPosition = "前" ; sN & sep ; sep & sN ); addsN = If ( 設定::export = 1 ; "" ; addSN ) ; bN = 設定::addBeforeName ; aN = 設定::addAfterName ; fN = If ( 設定::useFileName = 1 ; Substitute ( MediaDB::ファイル名 ; "." & MediaDB::拡張子 ; "" ); "" ); name = If ( 設定::NumberPosition = "前" ; addSN & bN & fN & aN ; bN & fN & aN & addSN ) ; fileName = name & "." & MediaDB::拡張子 ]; fileName ) ] [ ダイアログなし ] #pathFM フィールド内容の全置換 [ MediaDB::exprtPathFM; 計算で置き換える: 設定::sessionFolderFM & MediaDB::exportName ] [ ダイアログなし ] レコード/検索条件/ページへ移動 [ 最初の ] Loop #レコードの書き出し 変数を設定 [ $filePathFM; 値:MediaDB::exprtPathFM ] フィールド内容のエクスポート [ MediaDB::オブジェクト; 「$filePathFM」; フォルダを作成:いいえ ] レコード/検索条件/ページへ移動 [ 次の; 最後まできたら終了 ] End Loop レコード/検索条件/ページへ移動 [ 最初の ] Else #--------------------------------------- #変更して書き出し - FMType = "picture" に限定する #--------------------------------------- #FMType = "picture" のみ対応 変数を設定 [ $現在の対象レコード数; 値:Get ( 対象レコード数 ) ] エラー処理 [ オン ] #FMType = "picture" を絞り込み 対象レコードの絞り込み [ 指定された検索条件: レコードの検索; 条件: MediaDB::FMType: 「picture」 ] [ 記憶する ] If [ Get ( 対象レコード数 ) = 0 ] カスタムダイアログを表示 [ メッセージ: "FMType が 「picture」のみ、サイズ変更のエクスポートができます。該当するレコードがありませんでした。終了します。"; デフォルトボタン: 「はい」, 確定: 「はい」 ] #対象がない。終了 スクリプト実行 [ 「エクスポート設定キャンセルボタン【R5】」 ] 全スクリプト終了 Else If [ Get ( 対象レコード数 ) < $現在の対象レコード数 ] カスタムダイアログを表示 [ メッセージ: "FMType が 「picture」のファイルのみ、サイズ変更してエクスポートできます。"; デフォルトボタン: 「続ける」, 確定: 「はい」; ボタン 2: 「中止」, 確定: 「いいえ」 ] If [ Get ( 最終メッセージ選択 )=2 ] スクリプト実行 [ 「エクスポート設定キャンセルボタン【R5】」 ] 全スクリプト終了 End If End If # 対象レコードのデータを準備 #オブジェクト作成 フィールド内容の全置換 [ MediaDB::exportObject; 計算で置き換える: GetThumbnail ( MediaDB::オブジェクト ; 設定::ExportSizeWidth ; 設定::ExportSizeHeight ) ] [ ダイアログなし ] #fileName フィールド内容の全置換 [ MediaDB::exportName; 計算で置き換える: Let ( [ sep = 設定::sep; sNTemp = 設定::startNum ; digits = Length ( sNTemp ); sN = Right ( "0000000000" & sNTemp + Get ( レコード番号 ) - 1 ; digits ) ; addSN = If ( 設定::NumberPosition = "前" ; sN & sep ; sep & sN ); addsN = If ( 設定::export = 1 ; "" ; addSN ) ; bN = 設定::addBeforeName ; aN = 設定::addAfterName ; fN = If ( 設定::useFileName = 1 ; Substitute ( MediaDB::ファイル名 ; "." & MediaDB::拡張子 ; "" ); "" ); name = If ( 設定::NumberPosition = "前" ; addSN & bN & fN & aN ; bN & fN & aN & addSN ) ; fileName = name & "." & MediaDB::拡張子 ]; fileName ) ] [ ダイアログなし ] #pathFM フィールド内容の全置換 [ MediaDB::exprtPathFM; 計算で置き換える: 設定::sessionFolderFM & MediaDB::exportName ] [ ダイアログなし ] レコード/検索条件/ページへ移動 [ 最初の ] Loop #レコードの書き出し 変数を設定 [ $filePathFM; 値:MediaDB::exprtPathFM ] フィールド内容のエクスポート [ MediaDB::exportObject; 「$filePathFM」; フォルダを作成:いいえ ] レコード/検索条件/ページへ移動 [ 次の; 最後まできたら終了 ] End Loop レコード/検索条件/ページへ移動 [ 最初の ] End If End If
レコードの処理とループ処理を一つのスクリプトで
さらにオマケですが。
サムネイルを作成するとか、存在チェックするとか、何かするとか、一つのレコードに対して行うスクリプトがあります。同じスクリプトをループさせて対象レコードに施したいこともあります。
事前の変数仕込みなどがあって、ただスクリプトを読み込んでループさせるだけで済まない場合がありまして、つい単体用とループ用の2個のスクリプトを作ったりしていました。
今は少し知恵が付いて大抵の場合は1個のスクリプトで済ませています。あらかじめ呼び出すボタンやスクリプトにスクリプト引数をセットします。「loop」の文字です。これがあるかないかで処理を分けます。
単体用の用事であっても、処理を常に loop に書きます。スクリプト引数に「loop」がなければ、ループ一回目で抜ければいいだけです。
$loop [if (get ( スクリプト引数 )= "loop" ; 1 ; "" )] 事前処理 カウント$c = 0 loop $c = $c + 1 処理 exit loop if [ IsEmpty ( $loop ) ; $c = 1 ] end loop 後処理
レコード処理のシンプルなスクリプトならこれでイケます。オマケ話でした。
FileMaker で作る本気のメディア管理。リセットしてリスタートしてリメイクしてリブートしておりますが、もうすでに過去記事とぜんぜん関係ない展開になってきております。