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 について、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を置き換えることにはなりません。何とかフィールド名を指定してフルネームをゲットしたいです。そこでしばし考え、こうしました。
大雑把な流れは次のようになります。
- レイアウト上のフィールド名を全部ゲット
- ループして「::」があればそれ以降、指定フィールド名が同じものを見つける
- 見つけたフィールド名は、別テーブルなら最初から「::」のフルネームが付いているし、ついてなければレイアウトのテーブル名をくっつける
これを計算式にせこせこ書いて以下のようなものになりました。
// フィールド名からフルネームをゲットする関数。レイアウト上にあるフィールドのみ対応。 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 関数を置き換えることができました。
代替その3 それは不可能
GetFieldName のもう一つの使い道パターンがあります。長い間この関数を封印して使ったことがなかったのですが最近使うようになって、自分が想定していた以上の使い道があると知りました。
それが GetFieldName ( Self ) です。
条件付き書式や隠す設定、フィールド定義などでのみ「Self」が使えますが、GetFieldName でも使えます。これが非常に便利で、レイアウト上に配置したフィールドに条件付き書式を与え、さまざまな見栄えを表現できます。
しかし当然ながらバグのおかげで関連テーブルのフィールドでは”?”にしかならず使い物になりません。
そしてこれを代替する計算式や方法はありません。何をどう工夫しても GetFieldName(Slef) と同じ結果を返す関数を作ることは不可能でした。
「可能だよ」と、その方法を編み出した方は是非教えてください
ぜんぜん関係ないあとがき
こないだちょっとした腫瘍を摘出する手術をやって本日抜糸、最高の医療設備と技術を駆使し数人がかりですったもんだしていただいて命を救われ保険適用でお安く治療、医療費の負担が年々上がってきているとはいえ世界に誇る保険制度、カルト与党とその手下どもはこれをなきものにしようと謀略を練っていますが何としても維持しないといけません。