GetAsText ( オブジェクト ) の秘密 [FileMaker]

FileMaker の関数 GetAsText の結果は時と場合によって結果が異なります。どういうときにどういう値が返ってくるのか徹底検証。GetAsText とインポートの誰も知らない秘密に迫ります。

すいません、誰も知らない秘密ではなく、ここの筆者が知らない秘密の誤りでした。

概要

ここでは GetAsText でオブジェクトフィールドを指定した時の挙動についてまとめます。

GetAsTextをオブジェクトに対して使うとき、その主な目的はパスを取得するためだと思いますが、この投稿では最初に GetAsText ( オブジェクト ) でパスを含む特定の値を取得することについての結論から示します。

後半では、その結論に達するまでの道筋、GetAsTextの詳細な挙動についての報告です。興味のある方のみご覧いただければと思います。

GetAsText関数

GetAsText はデータをテキストとして返す関数ですが、オブジェクト(フィールド)を指定すると、インポートしたオブジェクトファイルのパスなどいくつかの情報を得られます。FileMakerのヘルプでは次のように書かれています。

外部に保存されたオブジェクトデータでは、データは次の例にある書式で返されます:

GetAsText (オブジェクト) は、次を返します。

remote:cat.jpg
size:320,240
JPEG:Images/Animals/cat.jpg

https://help.claris.com/archive/fm19/ja/pro-help/content/getastext.html

GetAsText でオブジェクトを指定したときの戻り値はオブジェクトの状況によって変化し、何が返ってくるか使ってみないと判りません。ヘルプにも「例」以外の記述がなく、掴み所がありません。

GetAsText ( オブジェクト ) のよくある誤解

中途半端な理解のまま GetAsTextを使っていると、戻り値について間違った思い込みが発生しがちです。そこでよくある誤解を挙げてみました。・・・すいません、よくある誤解じゃなくここの筆者がやらかしていた誤解です。

❌ パスが表示されていれば、それは接頭辞付きのパスである

誤り。file:Images/Animals/cat.jpg と書かれていればFM仕様のパスなのだなと思いがちですが、じゃあ JPEG:Images/Animals/cat.jpg はどうなんだと。以前、これもパスだと思い「FM仕様のパスの接頭辞は出鱈目にいろんな文言が付く」と誤解していました。FM仕様のパスの接頭辞は file, filemac, filewin など限られています。多分。だからこれはパスの一部ではなく、キーであると認識すべきです。キーに対して値は、接頭辞を除いたパスのベーシックな部分です。

FileMaker世界でのパスは、接頭辞 + パスベース の形を取ります。接頭辞は file: とか  filemac: とか imagemac: とかです。パスベースとは、接頭辞の後ろ、ボリュームからスタートする絶対パス(/Macintosh HD/Users/user/…)またはFMファイルからスタートする相対パスの部分を勝手にそう呼んでいます。関数やスクリプト内で処理するとき、パスベースだけで成り立つものもあれば接頭辞付きでないと成り立たないものもあります。

❌ 戻り値は最大3行である

誤り。少なくとも5行まで確認済み。行数を何かの当てにしてはいけない。

❌ キーが「file:」なら値はパスである

誤り。相対パスの場合もあればファイル名の場合もある。file: を当てにしてはいけない。

❌ キーが「remote:」はファイル名である。

誤りでもないが誤解しやすい。それはファイル名ではなく元ファイル名でFileMaker管理するファイル名。実体ファイル名とは異なる場合がある。remote: で示されているものが何であるか理解しておくこと。

❌ 結果の最後の行は必ずパス(相対か絶対かいずれか)である

誤りでもないが誤り。最後の行はパスの形をしているが、インポートしたファイルのパスではない場合がある。何行目であるかを何かの当てにしてはいけない。

さらりと書いたので「それ何のこと?」と思われる項目があるかもしれませんが、後で詳しく。

ここの筆者は以上のような誤解をしたまま人生を送っており、その誤りに基づいてこれまでFileMakerファイルをこしらえてきました。さらに、その話をブログに書いてきました。

本日この投稿以前のすべてのFileMakerに関する投稿に誤りの影を落としています。特に「最後の行は必ずパスである」の誤解は、間違った話をこれまで書き散らかしてきており、誤解の拡散に加担してしまっていました。すいません。ヤバいです(動揺中💦)

GetAsText ( オブジェクト ) で値を取得する計算式

GetAsText ( オブジェクト ) で取得できる値は次です。

  • ファイル名(FileMaker管理上の)
  • イメージの幅と高さ
  • 相対パス
  • 絶対パス
  • 代替ファイルのパス

これらが1行〜5行で帰ってきます。各行は、「:」をセパレータに、キーと値で出来ています。値の部分を $value とします。

$value を示す図

値が何なのかを出力する

次は、戻り値をループで処理して $value を特定した後、それが何なのかを示す計算式の一例です。

// $value = 値。例えば remote:cat.jpg なら cat.jpg の部分
// $fileName = ファイル名(管理上のファイル名) 
// $fileName_noExt = 拡張子を除いた管理上のファイル名 
// $fileExt = ファイルに付属する拡張子 
// $fmExt = FileMakerが対応し管理するファイルタイプ
Case (
 key = "size" ; "イメージサイズ";
 key = "remote" ; "元ファイル名";
 Left ( $value ; 1 ) ≠ "/" and $value ≠ $fileName and PatternCount ( $value ; $fileName_noExt ) and ( PatternCount ( $value ; "." & $fmExt ) or PatternCount ( $value ; "." & $fileExt) ) ; "相対パス" ;
 Left ( $value ; 1 ) ≠ "/" and $value ≠ $fileName and PatternCount ( $value ; $fileName_noExt ) and not PatternCount ( $value ; "." & $fmExt ) and not PatternCount ( $value ; "." & $fileExt) ; "代替ファイル" ;
 value = $fileName ; "元ファイル名";
 Left ( $value ; 1 ) = "/" ; "絶対パス";
 "" )

この計算式は「絶対パス」「元ファイル名」などと、キーに対する値が何を返すかを返しています。こんな計算式があったところで実践で役に立ちませんか。

だからつまり、例えば絶対パスを取得したいときは$valueを特定した後に次の計算で取得できます。

if ( Left ( $value ; 1 ) = "/" ; $value  )

相対パスの場合は他のデータとの比較が必要です。FM仕様拡張子のデータなどを事前に用意して比較しています。

if (
   Left ( $value ; 1 ) ≠ "/" and
   $value ≠ $fileName and
   PatternCount ( $value ; $fileName_noExt ) and (
      PatternCount ( $value ; "." & $fmExt ) or
      PatternCount ( $value ; "." & $fileExt)
    ) ; $value )

/ で始まらない
元ファイル名と同じではない(あるいは / が含まれる でも可かな

元ファイル名に拡張子を除いたファイル名が含まれる
元ファイル名の拡張子と同じか同じと看做される拡張子*が含まれる

このような処理でパスを見分けています。その理由や詳細は後ほど。

結果をJSONに出力する

これまた一例として、GetAsTextの結果をJSONで出力する計算式を挙げておきます。JSONのキーはGetAsText結果のキーではなく、別の文言で置き換えています(下記の緑色テキストの部分)後述しますがGetAsText結果のキーは当てに出来ずJSONキーに採用しても役に立たないからです。

While ( [

 obj = main::object;

 // オリジナルファイル名、ファイル名に付属する拡張子、拡張子を除いたファイル名部分
 $fileNameOrg = GetContainerAttribute ( obj ; "fileName" );
 $fileExt = GetValue ( Substitute ( $fileNameOrg ; "." ; ¶ ) ; ValueCount ( Substitute ( $fileNameOrg ; "." ; ¶ ) ) );
 fileName = Substitute ( $fileNameOrg ; "." & $fileExt ; "" );
 
 // FMが変更する可能性がある拡張子
 $fmExt = Case ( 
  $fileExt = "jpeg" or $fileExt = "jpg" ; "jpg";
  $fileExt = "aiff" or $fileExt = "aif"; "aif";
  $fileExt = "tiff" or $fileExt = "tif"; "tif";
  $fileExt = "mpeg" or $fileExt = "mpg"; "mpg";
  $fileExt
 );

 // GetAsText
 gat = GetAsText ( obj );
 vc = ValueCount ( gat );
 c = 1 
] ;

 c ≤ vc ; [

 // GetAsTextの結果を行ごとに処理
 gv = GetValue ( obj ; c );
 $key = GetValue ( Substitute ( gv ; ":" ; ¶ ) ; 1 );
 $value = GetValue ( Substitute ( gv ; ":" ; ¶ ) ; 2 );

// キーを代替する変数に値を格納
 // イメージサイズ 
 $imageSize = If ( $key = "size" ; $value ; $imageSize );
 // パス
 $path = If ( PatternCount ( $value ; "/" ) ;$value ; $path );
 // 絶対パス - パス書式で "/" から始まる
 $path_abs = If ( Left ( $value ; 1 ) = "/" ; "file:" & $value ; $path_abs );
 // 相対パス - パス書式で "/" で始まらず、オリジナルと、ファイル名・拡張子またはFM仕様拡張子が等しい
 $path_rel = If ( 
    Left ( $value ; 1 ) ≠ "/" and
    $value ≠ $fileName and
    PatternCount ( $value ; $fileName ) and
    ( 
     PatternCount ( $value ; "." & $fmExt ) or
     PatternCount ( $value ; "." & $fileExt)
    ) ; "file:" & $value ;$path_rel
  );
 // ファイル名(パスから取得する実際のファイル名)
 $fileName = If ( not IsEmpty ( $path ) ; GetValue ( Substitute ( $path ; "/" ; ¶ ) ; ValueCount ( Substitute ( $path ; "/" ; ¶ ) ) ) ; "" );

 c = c + 1 ] ;

 // 結果をJSONで出力
JSONSetElement ( "" ;
  ["imageSize" ; $imageSize ; 1];
  ["絶対パス" ; $path_abs ; 1];
  ["相対パス" ; $path_rel ; 1];
  ["fileName" ; $fileName ; 1];
  ["元ファイル名" ; $fileNameOrg ; 1]
 )
)

キーはご覧の通り、imageSize、絶対パス、相対パス、fileName、元ファイル名としました。好きな文言に変更できます。

あまり精査していませんがこんな感じの計算をカスタム関数か計算式フィールドに仕込んでおくとパスの取得が捗るかも。

パスを取得することの補足

GetAsTextでパスを取得したい場合、次を踏まえます。

  • 相対パスと絶対パスの両方またはどちらかを取得できる
  • 管理上のファイル名と異なる可能性がある

値が相対パスか絶対パスかを見分ける計算式は上に示しましたが、相対パスしか取得できない場合に備え、FMファイルのオブジェクトフォルダ(管理>オブジェクトで指定するフォルダ)までのパスを別途用意しておくと良いでしょう。それがあれば、相対パスから絶対パスを得る計算式が簡単に作れます。

管理 > オブジェクト option

フィールド定義の “データの格納” で設定したパスもデータとして持っていれば何かと使えます。GetAsTextのパスから導かれるファイル名を、このフォルダパスに繋げることでもパスが作成できます。

フィールド定義のオプション

ということで安直な答えだけを見つけたいだけのあなたと将来の自分のために最初に答えだけ書いておきました。端折った説明で「何のこっちゃ」だと思いますが、この後詳しく説明します。

GetAsText ( オブジェクト ) が返す値

あらためまして、GetAsText ( オブジェクト ) が返す値は次の5種類です。

  • 絶対パス
  • 相対パス
  • 元ファイル名
  • イメージサイズ
  • 代替ファイルパス

それぞれについて以下説明します。

絶対パス

オブジェクトファイルの絶対パスです。キー:パスベースの書式です。パスベースというのは、FileMaker仕様のパス(接頭辞:パス)の接頭辞: 以降の部分です。いわゆる普通のパスの記述です。FMパスとして使用するときは “file:” をくっ付けます。

取得:キーがどうあれ、値が「/」で始まっていればそれは必ず絶対パスです。

相対パス

管理 > オブジェクト で設定した場所からの相対パスです。キー:パスベースの書式です。

オブジェクトの格納設定
この例だと、Media/ より後(Masters以降)が相対パス

取得:値の中に「/」が含まれており、かつ、「/」で始まっていなければ相対パスの書式です。ただし、相対パスの書式だからといって、それは必ずしもオブジェクトファイルの相対パスとは限りません。

正しく相対パスを取得するには、他のデータとの比較が必要です。他のデータとは、元ファイル名、元ファイルに付属している拡張子、FileMaker仕様の拡張子グループ(拡張子リスト)です。

なぜそんな比較が必要なのかというと、代替ファイルのパスと区別が付かないからです。代替ファイルとホンモノのファイルを見分けるには、元ファイルのファイル名とFM仕様拡張子リストが必要で、それを比較するんです。次の「元ファイル名」と「代替ファイル」で説明します。

元ファイル名

元ファイル名というのは、元々のオブジェクト(メディア)ファイルのファイル名です。実際にインポートした実体ファイル名と同じとは限りません。

格納でインポートすると、ファイルを管理下のフォルダに複製しますが、この時FileMakerがファイル名・拡張子を勝手に変更することがあります。

例えば、cat.jpeg というファイルを格納インポートしたら cat_1.jpg になったりします。

拡張子 … ファイルにくっ付いた拡張子は、FM仕様上の拡張子に変更されます( .jpeg が .jpg になるなど)

ファイル名 … オブジェクトフィールドに上書きでインポートしたらファイル名に連番が付き cat_1 のようになります。

FileMaker内では元のまま cat.jpeg ということになっています。GetContainerAttribute ( オブジェクト ; “fileName” ) で得られるのも cat.jpeg です。しかし実在するファイルは cat_1.jpg です。
そういうことがあり得ますので正しく認識しておく必要があります。

取得:キーが「remote」なら、その値は元ファイル名です。ただし、値が元ファイル名のキーが必ずしも「remote」とは限りません。

元ファイル名を取得するのにわざわざGetAsTextを使う必要はなく、より確実な GetContinerAttribute ( オブジェクト ; “fileName” ) を使うのが良いでしょう(実際のファイル名が欲しい場合はパスを取得します)

イメージサイズ

イメージサイズは幅と高さです。「320,180」みたいなカンマ区切りの値になります。オブジェクトがイメージで、サイズが取得できるファイルの場合にGetAsTextの戻り値に含まれます。

取得:キーが「size」なら、値は必ずイメージサイズです。逆に、値がイメージサイズの書式なら、キーは必ず「size」です。

代替ファイル

一部のファイルタイプは、格納でインポートされた際にオリジナルからJPEGまたはPNGまたはその両方に変換した新規ファイルが作られ、相対パスが返されます。

例えば cat.pdf を格納でインポートすると、cat.pdf の他に cat.jpg と cat.png が作られます。

これらは戻り値の最後の行付近に現れるので「最後の行がパス」などと誤った思い込みをしていると代替ファイルのほうを取得してしまう可能性があります。

取得した値がパスの書式であるとき、それがインポートした元ファイルから作られたファイルのパスなのか、代替ファイルのパスなのかの見分けが付きません。インポートした元ファイルと同じファイル名と拡張子であれば同じと判定できそうですが、どっこい、ファイル名も拡張子もFileMakerが勝手に変更することがあるので、同じである判定がとても難しいことになります。

「元ファイル名」のところで述べた通り、正しい判定をするために「cat」と「cat_1」が同じと判定出来る仕組みと、「.jpeg」と「.jpg」が同じと判定できる仕組みを作っとかないといけません。

取得:あえて代替ファイルパスを取得しようとするなら、その条件はどうなるでしょう。元ファイルが JPEG でも PNG でもないことを前提に、GetAsTextの値がパス書式かつJPEGまたはPNGである場合にそれは代替ファイルパスと判定できるでしょう。

あるいは、ちょっと手間ですが「代替ファイルを生成するファイルタイプ」を根気よく見つけてデータ化しておくというのもありますか。このやり方を実現した場合、元ファイルのパスを判定する計算式も少し簡略化できる可能性があります。

という、以上5種類の値が、様々なキーを付けられて GetAsText の戻り値となります。1行だけのこともあれば5行の場合もあります。

ということで大体以上です。ここからはさらに詳細と、結論を得るために作ったテストファイルについて書かれます。興味のある方のみどうぞ。

GetAsText ( オブジェクト ) 戻り値のパターン

ここから先は戻り値のパターン、それが返されるオブジェクトの条件など詳細を示していきます。

GetAsTextの秘密を探ろうとテストファイルを作って、オブジェクトフィールドにいろいろファイルをインポートしまくり、その結果を観察しました。

なお、結果論的に、以下を知ることはさほど重要ではありません。むしろどうでも良いです。ですが結論を得たのは観察結果を眺めたからこそでした。知ることは悪いことでもない。参考資料として続けます。

行数とキーと値のパターン

GetAsTextは、絶対パス、相対パス、元ファイル名、イメージサイズ、代替ファイルパスを 1行から 5行の範囲で返します。値には様々なキーが付けられます。

次の表は、付けられるキーと値のパターンを示したものです。

(1行で返ったときは一種類、キーが「image」値が「絶対パス」です。2行返ってきたときは表のが示す4種類のどれかになります)

行数  キー  値
1 image 絶対パス
2 remote
FILE
元ファイル名
相対パス
2 remote
(FileType)
元ファイル名
相対パス
2 movie
moviemac
元ファイル名
絶対パス
2 file
filemac
相対パス
絶対パス
3 remote
size
(FileType)
元ファイル名
イメージサイズ
相対パス
3 size
image
imagemac
イメージサイズ
相対パス
絶対パス
3 size
image
imagemac
イメージサイズ
元ファイル名
絶対パス
4 remote
size
(JPEG or PNGf)
(FileType)
元ファイル名
イメージサイズ
代替ファイル
相対パス
4 remote
size
(FileType)
(JPEG or PNGf)
元ファイル名
イメージサイズ
相対パス
代替ファイル
5 remote
size
(JPEG or PNGf)
(FileType)
(JPEG or PNGf)
元ファイル名
イメージサイズ
代替ファイル
相対パス
代替ファイル


キーの表記について
(FileType)
… この表記はキーがファイルのタイプであることを示します。JPEG:とかTIFF: とか。厳密にはファイルタイプに留まらず、クリエータ(PSD -> 8BPS)だったり、oracleの表記(PNG -> PNGf)だったりします。一貫性がなく挙動不審ですが、ファイルタイプなものがキー名になると了解しておけばいいでしょう。

(JPEG of PNGf) … JPEG または PNGf のいずれかがキー名です。代替ファイルの場合にこの表記をしています。

パターンから見えてくること

パターンを眺めて見えてくるのは以下のようなことです。

キーは信頼できない

ファイルタイプ的なテキストがそのままキーになったり、imagemoviefile と、FM仕様のタイプグループがキーになったりします。しかも同じキーでも、時と場合によって値がファイル名だったりパスだったりします。

キーが何であるかを条件に指定しても信頼できないことがわかります。

信頼できるキーが一つだけあります。size の値は必ずサイズです。逆も真で、値がイメージサイズの書式( w,h )ならキーは size です。

行の順番も信頼できない

戻り値のパターンすべてを把握しないまま少ないサンプル数だけを元に「最後の行はパスだな」と、うっかり解釈をしてしまいがちですが完全に間違いです。
「最初の行」や「最後の行」といった条件では狙った値を取得することができないと判ります。

値のみの戻り値パターン

キーを無視すると、値のパターンは概ね次の8種類になります。

No.行数GAT値
11絶対パス
22元ファイル名 / 絶対パス
32元ファイル名 / 相対パス
42相対パス / 絶対パス
53イメージサイズ / 元ファイル名 / 絶対パス
63イメージサイズ / 相対パス / 絶対パス
74元ファイル名 / イメージサイズ / 相対パス / 代替ファイル
85元ファイル名 / イメージサイズ / 代替ファイル / 相対パス / 代替ファイル2
No. というのは、単に番号を振っただけです。

オブジェクトによって戻り値が選ばれる

GetAsTextの戻り値にはパターンがあってそのどれかが返るわけですが、では、どういうときにどのパターンが返ってくるのか。それはオブジェクトが何であるのかによります。

オブジェクトによってGetAsTextの結果が変化するのは周知ですが、周知されていないのはオブジェクトにどういった種類があるか、どの種類がどの結果を返すのか、その実態です。

オブジェクトの種類 = インポートの種類

オブジェクトの種類とは何のことでしょうか。まずはファイルタイプです。イメージであったりムービーファイルであったりJPEGだったりMP4だったりです。それ以外に、FileMaker にどのようにインポートしたかです。例えば登録の形態です。「参照」でインポートしたのか「格納」したのか。

GetAsTextのよくある誤解と同じくらい誤解されるのがオブジェクトの種類かもしれません。

❌ オブジェクトの種類は、ファイルタイプを除けば参照か格納かの二種類である

誤り。もっとたくさんあります。

「オブジェクトの種類」とはズバリ何をどのようにインポートしたかです。GetAsTextの結果で考えた場合、種類は沢山あるんです。これは意外と知られていないインポートの秘密ではなかろうか。

インポートの秘密

何をどのようにインポートしたかで、GetAsTextの戻り値が変化しますので、まずはオブジェクトの種類=インポートの種類を把握します。ざっくり、種類を網羅します。

No形態方法optFMTypevol
1参照フォルダmovie
2参照フォルダfile
3参照フォルダpdf
4格納フォルダimage
5格納フォルダmovie
6格納フォルダfile
7格納フォルダpdf
8参照挿入内容file
9参照挿入内容movie
10参照挿入内容pdf
11参照挿入内容image
12参照挿入アイコンfile
13参照挿入アイコンmovie
14参照挿入アイコンpdf
15参照挿入アイコンimage
16格納挿入内容file
17格納挿入内容movie
18格納挿入内容pdf
19格納挿入内容image
20格納挿入アイコンfile
21格納挿入アイコンmovie
22格納挿入アイコンpdf
23格納挿入アイコンimage
24参照フォルダimage
25参照フォルダmovie
26参照フォルダfile
27参照フォルダpdf
28格納フォルダimage
29格納フォルダmovie
30格納フォルダfile
31格納フォルダpdf
32参照挿入内容file
33参照挿入内容movie
34参照挿入内容pdf
35参照挿入内容image
36参照挿入アイコンfile
37参照挿入アイコンmovie
38参照挿入アイコンpdf
39参照挿入アイコンimage
40格納挿入内容file
41格納挿入内容movie
42格納挿入内容pdf
43格納挿入内容image
44格納挿入アイコンfile
45格納挿入アイコンmovie
46格納挿入アイコンpdf
47格納挿入アイコンimage

 

実際にインポートされない行も含まれています(例えば、フォルダからの格納インポートで、タイプが file の場合、実際には何もインポートされません)

種類を構成する各項目について以下に詳しく。

インポートの種類

インポート種類とは、登録形態、保存ボリューム、インポート方法、挿入オプション、そしてファイルタイプの組み合わせです。

形態 – 登録形態

参照または格納のいずれか。

  • 参照
  • 格納

参照ならファイルは元の場所に、格納ならフィールド定義で設定した場所にあります。

方法 – インポート方法

インポート方法。フォルダから一括インポートか一個ずつ挿入(ファイル)するかの二種類です。

 

"インポート
"挿入

しかし挿入の場合はさらにオプションがあります。

opt – 挿入オプション

「挿入」のオプションがあります。ファイル名付きのアイコンまたはファイルの内容のいずれかです。この選択により、GetAsTextの戻り値も変化します。
「挿入」ダイアログ

従って、インポート方法と挿入オプションを合わせた組み合わせは以下の三種類と言えます。

  • フォルダ
  • 挿入(アイコン)
  • 挿入(内容)

FMType

FMTypeはFileMakerによるファイルタイプのグループです。ヘルプに載っている対応ファイルタイプに準じます。

  • FileMakerが「image」と判断するタイプ
  • FileMakerが「movie」と判断するタイプ
  • FileMakerが「pdf」と判断するタイプ
  • その他、「file」と判断するタイプ

image はFileMakerが対応するイメージファイルです。JPEGやPNGといった画像ファイルのタイプですね。Macでは psd や pdf も含まれます。

movie はビデオファイルだけでなく、オーディオファイルも含まれます。

file はその他すべてですが、image や movie も file として扱えますから正確にはその他ではなく、その他を含むすべてと理解できます。

この分類はFileMakerのヘルプに載っています。OSやFileMakerのバージョンによって変わります。

ファイルタイプ サポートされる形式タイプ
ピクチャ
(image)
Encapsulated Postscript (.eps)
GIF (.gif)
HEIF/HEIC (.heic) (macOS, iOS, iPadOS)
JPEG/JFIF (.jpg, .jpeg)
PDF (.pdf) (macOS)
Photoshop (.psd) (macOS)
PNG (.png)
TIFF (.tif, .tiff)
Windows ビットマップ (.bmp)
Windows メタファイル/拡張メタファイル (.wmf/.emf) (Windows)
オーディオ/ビデオ
(movie)
AIFF オーディオファイル (aif、.aiff)
AVI ムービー (.avi)
FLAC オーディオファイル (.flac) (iOS、iPadOS)
MP3 オーディオファイル (.mp3)
MPEG-4 オーディオファイル (.m4a)
MPEG-4 ムービー (.mp4)
MPEG ムービー (.mpg、.mpeg)
MPEG-4 ビデオファイル (.m4v)
QuickTime ムービー (.mov、.qt)
Sun オーディオファイル (.au)
WAVE オーディオファイル (wav)
Windows Media Audio (.wma)
Windows Media Video (.wmv)
PDF .pdf

https://help.claris.com/ja/pro-help/content/data-in-container-fields.html (引用を元に拡張子を追加したもの)

この情報を元にFMTypeそれぞれ(image, movie, pdf, file)のタイプリストを事前に作っておくことも必要です(値一覧に作っておくなど)GetAsTextで相対パスを判断する際に、リストに拡張子が含まれているかどうかを分岐の条件に使うからです。

格納でインポートする場合にFileMakerがファイルの拡張子を勝手に変更することがあるのでそれも踏まえます。例えば拡張子が .tiff の場合、.tif に変更されます。FMTypeのそれぞれのリストを作成する際に tiff と tif を両方含めておきます。上のほうで書いた通り、どちらも「同じ」と判断させる必要があるからです。

  • jpeg -> jpg
  • tiff -> tif
  • aiff -> aif
  • mpeg -> mpg

ファイル名の拡張子が変更されるケースです。他にもあるかもしれませんが今のところこの四つを確認済みです。

vol – ボリューム

オブジェクトの保存場所のボリュームがシステムボリューム(起動ディスク)にあるのか外付けストレージにあるのかの違いも結果に影響します。

  • 起 … 起動
  • 外 … 外部

これに関してはテスト不足で、単にファイルの場所がシステムボリュームか外部かという分け方です。FileMaker ファイルが置かれているボリュームについてテストしていませんので、その条件を含めれば条件分岐がさらに増えますがそこまではやっていません。このテストは完璧とは言えませんが堪忍してください。

種類と結果を網羅する

ファイルタイプをFM仕様でグループ分けしたのですが、実はまだこれでは種類を網羅することはできません。というのも、同じ image グループ内であっても GetAsText の戻り値が異なるパターンがあるからです。例えば jpeg と eps では異なる結果になります。

結局、ファイルタイプ(拡張子)を全部調査するしかないのか。そうなんですが、そうでもない、もう一つの策を練ります。GetAsText の結果を利用します。

GetAsText の戻り値を調査するためのオブジェクト調査で GetAsText を利用するとは、自己無限ループに陥りそうな無茶苦茶なやり方ですが仕方がありません。オブジェクトの種類を把握するために再帰的にGetAsTextを使用して結果を利用します。

オブジェクト種類とGetAsTextの戻り値

GetAsTextの戻り値はオブジェクトによって決まるが、そこに明確で汎用的な法則はなく個別ファイルタイプによるという、不明瞭な結論となっています。

この投稿の序盤で、GetAsTextから狙った値を取得する計算式を書きましたが、すべて「値」部分の書式を見て判断しているだけだったことを思い出してください。つまり、そういうことなんです。GetAsTextの戻り値パターンがオブジェクトによって決まることは判っても、そこにはルールが見当たらず個別の事情しかなかった。それで、ルールを見つけることを放棄して値だけを条件調査の対象にしたわけです。

結果論として、オブジェクトの種類とかインポートの種類とか、そういうのはGetAsTextの値を取得することにおいて、あまり意味をなさないというオチが付きました。

とはいえ、そのオチが付いたのは、せっせとテストファイルにサンプルデータを溜め込んで観察したおかげなので、「GetAsTextのルールを調べるためのオブジェクトの種類を調べる行為の中にGetAsText結果を組み入れる」という謎のセルフループ行為を組み入れることは決して無駄ではなかった。

とか何とか言いながら、オブジェクト種類(インポート種類)をGetAsText結果に基づいてリストしたのが以下です。

No形態方法optFMTypevolNoGetAsText
1参照フォルダmovie2元ファイル名 / 絶対パス
2参照フォルダfile1絶対パス
3参照フォルダpdf1絶対パス
4格納フォルダimage7元ファイル名 / イメージサイズ / 相対パス / 代替ファイル
5格納フォルダmovie2元ファイル名 / 絶対パス
6格納フォルダpdf8元ファイル名 / イメージサイズ / 代替ファイル / 相対パス / 代替ファイル2
7参照挿入内容file4相対パス / 絶対パス
8参照挿入内容movie4相対パス / 絶対パス
9参照挿入内容pdf6イメージサイズ / 相対パス / 絶対パス
10参照挿入内容image6イメージサイズ / 相対パス / 絶対パス
11参照挿入アイコンfile4相対パス / 絶対パス
12参照挿入アイコンmovie4相対パス / 絶対パス
13参照挿入アイコンpdf4相対パス / 絶対パス
14参照挿入アイコンimage4相対パス / 絶対パス
15格納挿入内容file3元ファイル名 / 相対パス
16格納挿入内容movie3元ファイル名 / 相対パス
17格納挿入内容pdf8元ファイル名 / イメージサイズ / 代替ファイル / 相対パス / 代替ファイル2
18格納挿入内容image7元ファイル名 / イメージサイズ / 相対パス / 代替ファイル
19格納挿入アイコンfile3元ファイル名 / 相対パス
20格納挿入アイコンmovie3元ファイル名 / 相対パス
21格納挿入アイコンpdf3元ファイル名 / 相対パス
22格納挿入アイコンimage3元ファイル名 / 相対パス
23参照フォルダimage1絶対パス
24参照フォルダmovie2元ファイル名 / 絶対パス
25参照フォルダfile1絶対パス
26参照フォルダpdf1絶対パス
27格納フォルダimage7元ファイル名 / イメージサイズ / 相対パス / 代替ファイル
28格納フォルダmovie2元ファイル名 / 絶対パス
29格納フォルダpdf8元ファイル名 / イメージサイズ / 代替ファイル / 相対パス / 代替ファイル2
30参照挿入内容file2元ファイル名 / 絶対パス
31参照挿入内容movie2元ファイル名 / 絶対パス
32参照挿入内容pdf5イメージサイズ / 元ファイル名 / 絶対パス
33参照挿入内容image5イメージサイズ / 元ファイル名 / 絶対パス
34参照挿入アイコンfile2元ファイル名 / 絶対パス
35参照挿入アイコンmovie2元ファイル名 / 絶対パス
36参照挿入アイコンpdf2元ファイル名 / 絶対パス
37参照挿入アイコンimage2元ファイル名 / 絶対パス
38格納挿入内容file3元ファイル名 / 相対パス
39格納挿入内容movie3元ファイル名 / 相対パス
40格納挿入内容pdf8元ファイル名 / イメージサイズ / 代替ファイル / 相対パス / 代替ファイル2
41格納挿入内容image7元ファイル名 / イメージサイズ / 相対パス / 代替ファイル
42格納挿入アイコンfile3元ファイル名 / 相対パス
43格納挿入アイコンmovie3元ファイル名 / 相対パス
44格納挿入アイコンpdf3元ファイル名 / 相対パス
45格納挿入アイコンimage3元ファイル名 / 相対パス

 

最初のNoは番号を振っただけのシリアル番号。保存形態、方法、オプション、FMType、vol と続き、次のNoは少し↑に挙げた表のGetAsTextの値ナンバーと値。

逆に、GetAsText 結果の値にオブジェクトの種類を組み入れた表が以下です。

No行数GetAsText 値obj-Noobject
11絶対パス2参照 フォルダ file 起
3参照 フォルダ pdf 起
23参照 フォルダ image 外
25参照 フォルダ file 外
26参照 フォルダ pdf 外
22元ファイル名
絶対パス
1参照 フォルダ movie 起
5格納 フォルダ movie 起
24参照 フォルダ movie 外
28格納 フォルダ movie 外
30参照 挿入 内容 file 外
33参照 挿入 内容 movie 外
34参照 挿入 アイコン file 外
35参照 挿入 アイコン image 外
36参照 挿入 アイコン pdf 外
37参照 挿入 アイコン movie 外
32元ファイル名
相対パス
15格納 挿入 内容 file 起
18格納 挿入 内容 movie 起
19格納 挿入 アイコン file 起
20格納 挿入 アイコン image 起
21格納 挿入 アイコン pdf 起
22格納 挿入 アイコン movie 起
38格納 挿入 内容 file 外
41格納 挿入 内容 movie 外
42格納 挿入 アイコン file 外
43格納 挿入 アイコン image 外
44格納 挿入 アイコン pdf 外
45格納 挿入 アイコン movie 外
42相対パス
絶対パス
7参照 挿入 内容 file 起
10参照 挿入 内容 movie 起
11参照 挿入 アイコン file 起
12参照 挿入 アイコン image 起
13参照 挿入 アイコン pdf 起
14参照 挿入 アイコン movie 起
53イメージサイズ
元ファイル名
絶対パス
31参照 挿入 内容 image 外
32参照 挿入 内容 pdf 外
63イメージサイズ
相対パス
絶対パス
8参照 挿入 内容 image 起
9参照 挿入 内容 pdf 起
74元ファイル名
イメージサイズ
相対パス
代替ファイル
4格納 フォルダ image 起
16格納 挿入 内容 image 起
27格納 フォルダ image 外
39格納 挿入 内容 image 外
85元ファイル名
イメージサイズ
代替ファイル
相対パス
代替ファイル2
6格納 フォルダ pdf 起
17格納 挿入 内容 pdf 起
29格納 フォルダ pdf 外
40格納 挿入 内容 pdf 外

 

というようなデータを作って観察し、オブジェクトのパターンからGetAsTextの戻り値を特定できないものか、なにか法則ないかと調べましたが期待通りとは行きませんでした。

これら結果から読み取れる事柄

表からいろいろと読み取れることがあります。定かとは言い切れないぼんやりした特徴もいくつかは見て取れるでしょう。

例えば絶対パスは「参照」の場合に取得できる。とか。ただし例外があってmovie ファイルでは格納でも絶対パスです。これには理由があって、多分、ムービーファイルは格納でインポートしても強制的に参照になるからだと思われます。

相対パスは基本「格納」インポートで得られます。これも例外があって、参照の場合でも、絶対パスと相対パス両方を取得出来るパターンがあります(「file」分類のファイルを挿入した場合に確認できました)

代替ファイルはPDFとimageの一部ファイルタイプで作られます。代替ファイルが作られるかどうかは image に分類されるファイルタイプをつぶさに調べれば答えが見つかりそうです。相対パスの取得にはその方法が有効かもしれません。

テストファイル

FileMaker Document テストファイルについてのメモを書き残しておきます。特に読まなくても大丈夫です。

GetAsTextについての誤解が元で、希に期待通りの値が得られずスクリプトや計算式がバグって作成中のFMファイルがしっちゃかめっちゃかになることがありました。長年謎でしたがようやくGetAsTextを誤解していたと気付いたので、意を決して徹底調査を行うことにしました。

さっそくテストファイルを作成。インポートする様々なファイルをフォルダに用意してテストすることにしました。

フォルダインポートはともかく「挿入」はファイル一個ずつの処理ですからファイルリストを作ってループでインポートします。これら多様なインポートスクリプトをさらに一個にまとめて一気にメディアファイルの登録を行いました。

インポート直後に GetAsTextを掛けて、その値をループで行ごとに処理して別テーブルにレコードとして分配します。キーと値を計算式で汎用的な言葉に置き換える作業です。

この後、さらにインポート種類のテーブルとGetAsText結果ごとのテーブルにレコードを分配しつつ、ここで示した表ができあがりました。

このテストファイルを作ること自体に手間取りました。最初はインポートの種類数を少なく見積もりすぎていました。テストというものは、実験主が仮説を立てられるレベルに到達していないと有効なものが作れません。

テストのためのテストを繰り返す中で仮説を立て実証テストを行い、最終的にテスト結果を前提にフィールドの計算式を作ってテストするというタイムループ物みたいなおかしな時系列状態にハマりつつテストファイルを育てていきました。

その結果はここで示した通りですが、まだ腑に落ちない点もなくはないですし、テスト条件もパーフェクトとは言えません。ただ、実践上は問題ないレベルに達したかなと思ったので深掘りせず、適当に切り上げました。

さて。これまでFileMakerの投稿を多くしてきましたが、特にメディア管理とかファイルをレコード化する話の中で間違ったことを書き綴ってきました。最大の間違いは「GetAsTextの戻り値の最後の行がパス」です。パスには違いないのですが、代替ファイルのパスを取得してしまう可能性があります。このせいで、一部ファイルタイプで不具合が出ます。

記事やFileMaker書類の修正に追われそうです💦

総じて

長くなったのでまとめます。

GetAsText ( オブジェクトフィールド ) の結果は、オブジェクトのインポート種類によって戻り値と行数が変わります。

目的の情報を取得したいとき、戻り値のキーを当てにできません。唯一当てにして良いのはキーが「size」の場合だけです。

オブジェクトのインポート種類を元に行数と戻り値を判断することはできますが、そんな手間をかけるより単に値から判断することが合理的です。

パスを取得したい場合、値がパスの書式(スラッシュがある、元ファイル名が含まれるなど)であるかどうかを見て、さらにスラッシュで始まるテキストなら絶対パスと判断できます。

相対パスの場合、他のデータ(元ファイル名、元拡張子、FM仕様の拡張子)との比較で判断します。比較が必要なのは、代替ファイルである可能性を排除するためです。

相対パスしか取得できない場合、管理 > オブジェクト で指定したフォルダパスを利用することで絶対パスを導けます。

GetAsTextの結果を効率良く取得するには、結果を行ごとにループして判定します。

行の処理

  1. セパレータ( : )で区切って、左がkey、右をvalueとする
  2. key が size なら value は幅,高さ(カンマ区切り)
  3. value に / が含まれていればパス
    • 開始が / なら絶対パス
    • 相対パスなら元ファイルのデータと比較して代替ファイルパスの可能性を除外

このような計算式で、パスとイメージサイズを取得すれば良いでしょう。ついでに posix や urlパスに変換する計算式を追加したり、それらをまとめて JSON で出力することで汎用的な利用ができるようになりますね。

 

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください