[FileMaker] GetFieldNameを無視してフィールド名からフルフィールド名をゲット

GetFieldName という関数がありまして、フィールド名からフルフィールド名を返す関数ですが、未だかつてこれがまともに動作したことがない。GetFieldName は封印して別のやり方でゲットします。

動かないGetFieldName 関数

昔 GetFieldName 関数を初めて知ったときは「なんと便利な関数があるもんだ」と小躍りして喜びましたが、この関数、ただの一度もまともに動作したことがありません。

説明では「参照されているフィールドの完全修飾名を返します」ということですが、常に結果が「?」になります。

ヘルプでは次のような例が掲載されています。

例1. GetFieldName (x) は、引数 x としてカスタム関数に渡されたフィールド参照の名前を返します。

例2.GetFieldName (Evaluate (<フィールド名>)) は、<フィールド名> に保存されているデータに基づいてフィールドの名前を返します。

例3.GetFieldName (Evaluate (Get (アクティブフィールド名))) は、実行された場合にフォーカスの対象となるフィールドの完全修飾名を返します。

https://help.claris.com/ja/pro-help/content/getfieldname.html?Highlight=getfieldname

イミフ日本語。最大関門であるEvaluateと組み合わされているもんだからますますイミフ。がんばって何度も読んで試してみましたが、やはり期待通りに動作せず結果は「?」になります。

データビューで試しても動きません。

 

getFieldname 関数は真面目に動かない
これはわざとですが、GetFieldName 関数は evaluate(“説明”)と書かないと駄目なんですよ。evaluate と書くとフィールドの中身を取得しそうに思えて、直感に反しているように思いますがわかりません。
evaluate を用いた正しい書き方
Evaluate の理屈がさっぱりわからん

これはまあいいとして、関連テーブルのフィールドだとエラーになります。

配置した関連テーブルのフィールド
配置した関連テーブルのフィールドではまともに動かない

腑に落ちないし意味わからないしちゃんと動かないという。それで、フィールド名からフルフィールド名をゲットする方法として GetFieldName をなかったものとして封印し、別のやり方で凌いできました。

 

カスタム関数 GetFieldFullName
カスタム関数で直感的かつ期待通りの結果を得ております

 

その方法は後ほど記しますが、その前に謎の GetFieldName について、Claris の記述を発見したのでスッキリしたという話をしておきます。

どうやら関数の不出来でした。

たまたま偶然めぐりあったページがこれです。すべての謎が解けました。

アクティブフィールドが関連テーブルからのものである場合、計算式 GetFieldName (Evaluate (Get (アクティブフィールド名))) は “?” を返す – Claris

このページが何なのかよくわかりませんが、「問題」としてこう書かれています。

アクティブフィールドが関連テーブルからのものである場合、計算式 GetFieldName (Evaluate (Get (アクティブフィールド名))) は “?” を返します。

はい。そうなりますね。データビューで試してもエラー出ます。

問題に対する「説明」はこうなっています。

Claris International Inc. はこの問題を認識しています。

おおっ。問題として認識しておられますよ。ただし「説明」は以上で、解決策はありません。そうだったのか、ただの問題だったのか。

別テーブルのフィールドでは機能しない

私はこれまで、GetFieldName関数を使おうとするとき、100%の確率で別テーブルのフィールドを対象にしてきました。同テーブル内ならわざわざ関数でゲットする必要なんかないですしね。したがって、この関数の不具合に100%ぶち当たっていたというわけです。

これまで、GetFieldName関数の理解が足りていないからだ、Evaluate関数の理解が足りていないからだ、と自分のあほさが原因であろうと思っていましたがそうではなく、ただの関数の不出来でした。己のあほさが原因ではなかったことに少し喜び、そしてスッキリしました。スッキリしたのでこのポスト書いてます。ここが本日メインの話題でした。

GetFieldName関数の代替 – カスタム関数を作った話

代替その1 アクティブフィールドの場合

そんなわけで、特定フィールドのフルフィールド名が欲しいときどうやって凌いできたかという話ですが。

大抵、フィールド名からフルフィールド名が欲しいのは汎用的なスクリプトを作っていく中で、「アクティブなフィールド」に対してだったりします。

アクティブフィールドの名前を変数に仕込んでフルネームを得ます。Let関数で書くとこうなりました。

// アクティブフィールドのフルネームをゲットする関数

Let ( [
	fldname = Get(アクティブフィールド名)  ;
	table = Get(アクティブフィールドテーブル名) ;
	fullname = table & "::" & fldname
] ; fullname )

フィールド名とテーブル名をゲットして繋げただけです。実に単純な話で失礼しました。GetFieldNameActiveという名前のカスタム関数に仕込んでますが、わざわざカスタム関数として保存するまでもないという話でもあります。

代替その2 フィールド名指定の場合

上記その1みたいにアクティブなフィールドなら簡単な話ですが、真のGetFieldNameを置き換えることにはなりません。何とかフィールド名を指定してフルネームをゲットしたいです。そこでしばし考え、こうしました。

大雑把な流れは次のようになります。

  1. レイアウト上のフィールド名を全部ゲット
  2. ループして「::」があればそれ以降、指定フィールド名が同じものを見つける
  3. 見つけたフィールド名は、別テーブルなら最初から「::」のフルネームが付いているし、ついてなければレイアウトのテーブル名をくっつける

これを計算式にせこせこ書いて以下のようなものになりました。

// フィールド名からフルネームをゲットする関数。レイアウト上にあるフィールドのみ対応。

While ( [ 
 fldname = fieldName ;
 table = Get(レイアウトテーブル名) ;
 fldFullName = "" ;
 fldFullNameList = "" ;
 flds = FieldNames ( Get(ファイル名) ; Get(レイアウト名) ) ;
 vc = ValueCount ( flds );
 c = 0
 ] ; c < vc ; [ 
 c = c + 1 ;
 fld = GetValue ( flds ; c );
 fldFullName = 
	If ( PatternCount ( fld ; "::" ) ; 
		// "::" が含まれる
		If ( GetValue ( Substitute ( fld ; "::" ; ¶ ) ; 2 ) = fldname ; fld ; fldFullName ) ;
		// "::" が含まれない
		If ( fld = fldname ; table & "::" & fldname ; fldFullName ) 
	 ) ;
fldFullNameList = List ( fldFullNameList; fldFullName ) ;
fldFullNameList = UniqueValues ( fldFullNameList ) ;
fldFullNameList = If ( Right ( fldFullNameList ; 1 ) = ¶ ; Left ( fldFullNameList ; Length ( fldFullNameList ) - 1 ) )

 ] ; 
fldFullName
 )

この計算式を GetFieldFullName と名付けてカスタム関数化しました。指定フィールド名を変数fieldNameに設定しています。

GetFieldFullName( フィールド名 ) で別テーブルであっても「テーブル名::フィールド名」がバッチリ得られます。

この関数の弱点は現在のレイアウト上に配置してあるフィールドにのみ対応する点ですが、不出来な GetFieldName 関数を置き換えることができました。

 

Penguin icon

ぜんぜん関係ないあとがき

こないだちょっとした腫瘍を摘出する手術をやって本日抜糸、最高の医療設備と技術を駆使し数人がかりですったもんだしていただいて命を救われ保険適用でお安く治療、医療費の負担が年々上がってきているとはいえ世界に誇る保険制度、カルト与党とその手下どもはこれをなきものにしようと謀略を練っていますが何としても維持しないといけません。

 

コメントを残す

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

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