スクリプト作成者は、変数を JSL 関数またはメッセージの引数として使用しようとして、期待どおりの結果が得られないと、困惑することがよくあります。JSL ではスクリプト作成者がこの状況に遭遇する状況は数多くありますが、ユーザーが頻繁に遭遇するのは、仕様制限列プロパティを設定しようとするときです。仕様制限として使用する値は、多くの場合、前の手順で参照テーブルから抽出され、変数に割り当てられます。すべての制限値を収集して変数に割り当てた後、次の論理的な手順は、これらの変数を使用して分析テーブルの列プロパティを設定することです。スクリプト作成者が試す可能性のある代表的な例を次に示します。この JSL をスクリプト ウィンドウにコピーして実行し、手順に従うことができます。
Names Default to Here(1);
// Open a sample data table
dt = Open("$SAMPLE_DATA/Cleansing.jmp");
// Values previously obtained from a lookup table and assigned to variables as:
myLSL = 6;
myUSL = 8;
myTarget = 7;
// Use the variables to set the spec limits column property
Column(dt, "pH") << Set Property(
"Spec Limits",
{LSL( myLSL ), USL( myUSL ), Target( myTarget ), Show Limits( 1 )}
);
このスクリプトを実行すると、列プロパティが設定されていることを示すアイコンが pH 列の横に表示され、アイコンをクリックすると、それが仕様制限プロパティであることが確認されます。

ただし、仕様制限の値を確認するために列情報ダイアログ ウィンドウを開くと、値が表示されません。

JMP は何をしましたか? 機能しているように見えましたが、部分的にしか機能しませんでした。なぜですか?!?
調査するには、JSLを使用してプロパティ設定を確認します。これを行うと、手がかりが得られるかもしれません。次の式を評価します。
Column(dt, "pH") << Get Property("Spec Limits");
次の情報がログに書き込まれます。
{LSL( myLSL ), USL( myUSL ), Target( myTarget ), Show Limits( 1 )}
まあ、まさに私が指定したとおりですが、変数自体ではなく、変数に割り当てられた値が表示されないのはなぜでしょうか。この質問に対する答えは、混乱の核心に迫るものです。JSLは、割り当てられた値を解決するのに十分な回数引数を評価するとは限らず、引数が評価される回数は、変数が使用される状況によって異なります。たとえば、現在のコンテキストでは、JMP はリスト引数を「解析」して、Spec Limits プロパティのさまざまな側面を指定する項目があることを理解します。これは 1 つの評価です。別の評価では、JMP はリストの項目を確認して、Spec Limits プロパティに設定する制限 (LSL、USL、Target など) を決定します。JMP は、リスト項目内に提供された引数 (myLSL、myUSL、myTarget) をまったく評価しません。JMP は、LSL、USL、および Target の引数として数値を期待しています。変数が提供されても、JMP はそれを認識せず、変数を解決して関連する値を決定することを試みません。
では、特定の状況で引数が何回評価されるかを知ることはできるでしょうか? 上記の例のように、さらに評価が必要な場合はどうすればよいでしょうか? JMP のソース コードにアクセスできないため、特定の状況で評価が何回実行されるかを知ることは非常に困難です。ただし、現在の用途に十分かどうかを知ることの方が重要です。まず最初に試して検証します。
仕様制限メッセージで期待される値に関する事前知識がないため、最初に上記に示したとおりにスクリプトを記述します。次に、仕様制限が設定されているかどうかを確認します。そのためには、[列情報] ダイアログで確認するか、列を使用してグラフを作成し、グラフ参照線が正しく表示されるかどうかを確認します。この場合のように検証が失敗した場合は、式を編集して変数を削除し、代わりに数値をハードコードする必要があります。
Column( dt, "pH" ) << Set Property(
"Spec Limits",
{LSL( 6 ), USL( 8 ), Target( 7 ), Show Limits( 1 )}
)
次に、式を実行して、問題が変数の使用によるものであり、他の構文の問題ではないことを確認します。式がハードコードされた値で期待どおりの結果を提供することを確認したので、変数が十分に評価されずに割り当てられた値に到達できない状況に遭遇したことがわかります。したがって、式を評価する前に、JMP で実行時に式を動的に作成して、変数値を式に埋め込む必要があります。
変数を事前評価する方法は複数ありますが、私が好むのは Eval Expr() 関数を使用することです。その他の方法としては、Substitute() 関数を使用するか、文字列を連結して JSL 式を作成し、最終的な文字列を解析して評価する方法があります。私が最も好まない方法は、式を文字列として作成することです。コードは単色なので非常に読みにくく、JSL エディターが提供する便利なセマンティック フォーマットが失われ、埋め込まれた引用符をエスケープする必要があります。さらに悪いことに、コードの選択した部分を評価できなくなるため、コードのデバッグやトラブルシューティングが困難になります。
// An example of concatenating strings to dynamically write a JSL expression.
Parse(
"Column( dt, \!"pH\!" ) << Set Property(
\!"Spec Limits\!",
{LSL( " || Char(myLSL) || " ), USL( " || Char(myUSL) || " ), Target( " || Char(myTarget) || " ), Show Limits( 1 )}
)"
)
この点では Substitute() 関数を使用する方が優れていますが、式が長い場合、置換の内容と場所を指定する後の引数を確認しながら式を読むのは困難です。
// An example of using Substitute() to dynamically write a JSL expression.
Substitute(
Expr(Column(dt, "pH") << Set Property(
"Spec Limits",
{LSL( lll ), USL( uuu ), Target( ttt), Show Limits( 1 )}
))
,
Expr(lll), myLSL,
Expr(uuu), myUSL,
Expr(ttt), myTarget
)
対照的に、Eval Expr() 関数ではインライン置換指定が可能であり、関数の引数は式であるため、JSL エディターはそれをセマンティック形式で表示できます。
では、Eval Expr() はどのように動作するのでしょうか。これは、式を唯一の引数として受け取り、式を返す関数です。指定された式でトークン Expr() を検索します。次に、JMP は Expr() の括弧内の内容を評価し、トークン全体を戻り値に置き換えます。仕様の制限を設定するために上記の例に戻ると、変数を Expr() で「ラップ」し、式全体を Eval Expr() 呼び出し内に配置すると、JMP は実行時に変数 (および Expr() トークン) を変数値に置き換え、変更された式を返します。つまり、
// An example of using Eval Expr() to dynamically write a JSL expression.
Eval Expr(
Column(dt, "pH") << Set Property(
"Spec Limits",
{LSL( Expr(myLSL) ), USL( Expr(myUSL) ), Target( Expr(myTarget) ), Show Limits( 1 )} );
);
戻り値:
Column( dt, "pH" ) << Set Property(
"Spec Limits",
{LSL( 6 ), USL( 8 ), Target( 7 ), Show Limits( 1 )}
)
すばらしいですね。これで、必要なハードコードされた値を含む Spec Limits プロパティを設定する式ができました。JSL コードを動的に記述しました。これで、変更した式を評価するだけです。これには、Eval() 関数が役立ちます。Eval Expr() をラップして、Eval() 呼び出しを呼び出すと、Eval Expr() によって返された式がすぐに評価されます。実行時にのみ判明する制限値を使用して Spec Limits プロパティを正しく設定する完全なサンプル スクリプトを次に示します。
Names Default to Here(1);
// Open a sample data table
dt = Open("$SAMPLE_DATA/Cleansing.jmp");
// Values previously obtained from a lookup table and assigned to variables as:
myLSL = 6;
myUSL = 8;
myTarget = 7;
// Use the variables to set the spec limits column property
Eval(Eval Expr(
Column(dt, "pH") << Set Property(
"Spec Limits",
{LSL( Expr(myLSL) ), USL( Expr(myUSL) ), Target( Expr(myTarget) ), Show Limits( 1 )}
);
));
このスクリプトを検証すると、列情報ダイアログに仕様制限の値が表示されます。

さらに、この式を評価すると
Column(dt, "pH") << Get Property("Spec Limits");
次の情報がログに書き込まれます。
{LSL( 6 ), USL( 8 ), Target( 7 ), Show Limits( 1 )}
最後に、列を使用してグラフを作成すると、予想される場所に仕様制限参照線が表示されます。

JSL コードを動的に記述することは、スクリプト作成者が習得しておくと役立つスキルです。JMP が式の引数を十分な回数評価せず、実際に必要な値に到達できない状況は数多くあります。JSL コードを動的に記述する方法は複数ありますが、私が好むのは Eval(EvalExpr(Expr())) メソッドです。このメソッドでは、インライン置換とセマンティック フォーマットが可能で、コードの読み取りとデバッグが比較的容易になります。