スクリプトはスクリプト エディターでは機能しますが、メニュー項目では機能しません (列名の取得が同じように動作しません)スクリプトエディタから次のスクリプトを実行すると、正常に動作します。しかし、「表示」→「カスタマイズ」で作成したカスタムメニュー項目から実行すると、機能しません。追跡したところ、Get Column Names 関数が同じように動作しないことがわかりました。Get Property を使用する前に、各列の名前とその Type の値を出力する print ステートメントを配置すると、(たとえば) スクリプト エディターから実行すると次のようになります。
:exec_typ
"名前"
ただし、メニュー項目から実行すると、次のようになります。
exec_typ
"名前"
コロンがないことに注目してください。(結腸が何をするかはわかりません。)
最終的に、exec_typ という名前の列に対して Get Property 関数を実行しようとすると、JMP がそれを列名などとして認識しないため、スクリプトがクラッシュします。
Send は、 'Send' のアクセスまたは評価で Scriptable Object{7} を期待します、colNames[colInd] << /*###*/Get Property( "Speclimits" ) /*###*/
一体何が起こっているのかわかりますか?Get Column Names 関数がスクリプト エディターから呼び出された場合とメニュー ショートカットから呼び出された場合で動作が異なるのはなぜですか?
以下のコード。はい、一部が汚いです。
//Reports all failing tests for a unit. Not temperature-smart (yet!)
dt = Current Data Table();
colNames = dt << get column names(Numeric);
//I need to clean up the add columns scripts... once I understand how it works.
dt << add multiple columns(
"Num Tests Failing",
1,
After( "20:Neg_Contact:Cont_int2[1]" ),
numeric( 10 )
);
colf = Column( "Num Tests Failing" );
colf << Modeling Type ( Nominal );
dt << add multiple columns(
"Failing Tests",
1,
After( "20:Neg_Contact:Cont_int2[1]" ),
numeric( 10 )
);
colf = Column( "Failing Tests" );
colf << Data type( Character );
For (i = 1, i <= N Rows(dt), i++,
Row() = i;
failingTests = "";
NumOfFailingTests = 0;
If (:Name("HBIN_NAM") != "Good" & :Name("HBIN_NAM") != "1:Good" , //It's a fail
//Efficiency could be improved by extracting all spec limits first.
For (colInd = 1, colInd <= N Items(colNames), colInd++,
//print statements for debugging.
print(colNames[colInd]);
print(Type(colNames[colInd]));
//THIS IS WHERE IT KEEPS CRASHING
specLimits = colNames[colInd] << Get Property ("Spec limits");
LSL_Char = Char(specLimits[1]);
USL_Char = Char(specLimits[2]);
LSL_Char = SubStr(LSL_Char, 5, (Length(LSL_Char) - 5));
USL_Char = SubStr(USL_Char, 5, (Length(USL_Char) - 5));
LSL_Num = 0; //initializing value to set its scope; is this necessary? Donno.
USL_Num = 0;
If(LSL_Char == "." | LSL_Char == "",
LSL_Char = "NO LIMIT",
//else
LSL_Num = Num(LSL_Char);
);
If(USL_Char == "." | USL_Char == "",
USL_Char = "NO LIMIT",
//else
USL_Num = Num(USL_Char);
);
failedTest = 0;
If(LSL_Char != "NO LIMIT",
If( colNames[colInd][i] < LSL_Num,
failedTest = 1;
NumOfFailingTests = NumOfFailingTests + 1;
);
);
If(USL_Char != "NO LIMIT",
If( colNames[colInd][i] > USL_Num,
failedTest = 1;
NumOfFailingTests = NumOfFailingTests + 1;
);
);
If(failedTest == 1,
failingTests = failingTests || Char(colNames[colInd]) || "; ";
);
);
);
:Name( "Failing Tests" )[i] = failingTests;
:Name( "Num Tests Failing" )[i] = NumOfFailingTests;
);
Re: スクリプトはスクリプト エディターでは機能しますが、メニュー項目では機能しません (列名の取得が同じように動作しません)1. コードを JSL として表示するには、テキストを入力するために入力ウィンドウの上部にある ツールを使用する必要があります。
2. 私のコードがあなたの方法よりも速く動作すると信じている主な理由は、2 つの項目に基づいています。
a. はい、数式は最適化されています。
b. dt << Select Where を使用すると、選択されたすべての行に一度に割り当てることができるため、非常に高速です。コードに含まれるすべての「IF」ステートメントを含むデータ テーブルをループすると、非常に時間がかかります。
3. キャラクターのスペック限界値について。スペック制限はどのように割り当てていますか?[仕様制限] 列プロパティでは数値のみを許可する必要があります。Substr() などの文字関数を使用して仕様制限リストにアクセスすると、文字列が返されます。JSL リストの操作方法については、スクリプト ガイドを参照してください。
Re: スクリプトはスクリプト エディターでは機能しますが、メニュー項目では機能しません (列名の取得が同じように動作しません)ジムの脚本をありがとう! おっしゃるとおりです。JMP スクリプトで変数のスコープがどのように機能するのかはわかりませんが、宣言された変数がデフォルトでローカル変数であることを示唆する証拠をいくつか見たことがあります。
これらのフォーラムでスクリプトを正しく表示するにはどうすればよいですか?これらのフォーラムのコード ウィンドウにコードを貼り付けると、書式設定が台無しになり、すべてのタブと空白のインデントが削除されます。Python コードを共有しようとしていないのは良いことです。
とにかく、私はあなたのスクリプトの要素を使用するようにスクリプトを調整しており、すでに最終的に動作しています。dt= current data table(); を使用してスクリプトを直接使用してみました。さらに 1 ~ 2 回編集しましたが、うまくいきませんでした。私のスクリプトが非効率であることは承知していますが、たとえば、USL と LSL を数値に変換する試みはすべて失敗したため、文字列に変換して部分文字列を使用する必要がありました。ただし、コメントに記載した調整を行って、すべての仕様制限を一度だけ抽出する場合は、それほど問題にはなりません。開いているファイルの例も確認すると便利です。なぜなら、私が本当にやりたいのは、分析しているファイルとは別のファイルからテスト制限を取得するオプションがあることだからです。
私にとって奇妙なのは、列の追加と削除の方が、入れ子になった 2 つの For ループよりも効率的であるというあなたの暗示 (スクリプトの方が速いと言ったため) です。コンピューターは依然として、データ テーブル内のすべてのセルを分析する必要があります。JMP は、式の設定と実行がより効率的になるように最適化されていますか?あなたのアプローチが実際に機能するかどうかを確認することはできません。フォローアップのポーズで提案されたことを試してみた方がよいかもしれません。
ちなみに、私のデータ テーブルには 600 列程度があり、数万行が含まれる可能性があるため、実行効率を考慮する必要があるかもしれません。
とにかく、スクリプトを機能させるために必要な最小限の変更は、すべてのスクリプトを置き換えることです。
列名[列番号]
と
列( dt,colNames[colInd] ) 。
データ ファイルで動作させることはできませんが、スクリプトからさらにいくつかの要素を調整してみます。
Re: スクリプトはスクリプト エディターでは機能しますが、メニュー項目では機能しません (列名の取得が同じように動作しません)ジム、
良くやった。追加する必要がありました
dt << Run Formulas;
Eval(Parse(theExpr)) の後と、式ステートメントの削除の前、うまく書かれたスクリプトの 2 か所。
Re: スクリプトはスクリプト エディターでは機能しますが、メニュー項目では機能しません (列名の取得が同じように動作しません)私の推測では、変数 (:) のスコープを具体的に設定していないため、2 つの異なる環境で実行しようとすると問題が発生すると考えられます。私が観察したもう 1 つの点は、あなたのメソッドではコードが非常に遅くなるということです。それを考慮して、両方の環境で機能し、実行速度もはるかに高速になると思われるいくつかのメソッドを使用してスクリプトを書き直しました。以下のスクリプトは、JMP で配布される Semiconductor Capability データ テーブルに対して実行されます。しかし、そのテーブルを開くための参照と、データテーブルの Open に続くステートメントを削除し、それらをあなたのものに置き換えると、
dt = 現在のデータテーブル();
コードはデータに対して機能するはずです。
以下のコードに注釈を付けましたので、それに従っていただけると思います。また、JMP のインストール時に配布されるスクリプト ガイドを読むことを強くお勧めします。
ヘルプ==>書籍==>スクリプトガイド
クレイジーなコロンが何なのかをすべて教えてくれる
Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/semiconductor capability.jmp" );
dt << delete columns( {2, 3, 4} );
// Get the numeric column names as strings
colNames = dt << get column names( Numeric, string );
// Create the new calculated columns
// They will be populated later
dt << New Column( "Num Tests Failing", numeric );
dt << New Column( "Failing Tests", character );
// Create a new column for each column in the colNames list
// and populate the colNames name, if it does NOT pass
For( i = 1, i <= N Items( colNames ), i++,
// Create the new colum
dt << New Column( "PassFail " || Char( i ), character );
// Get the Spec Limits for the first column
specLimits = Column( dt, colNames[i] ) << get property( "Spec Limits" );
// If no Spec Limits are found, do not process
If( Is Empty( specLimits ) == 0,
// Get the USL and LSL and if not present set to missing
LSL = Try( specLimits["LSL"], . );
USL = Try( specLimits["USL"], . );
// If the LSL is not missing process
If( Is Missing( LSL ) == 0,
// Find all rows where the colNames column is less than
// the LSL
dt << select where( As Column( dt, colNames[i] ) < LSL );
// If any rows are selected, then process
If( N Rows( dt << get selected rows ) > 0,
// Set the value in the PassFail column to the name of
// the colNames being processed. This will allow for
// the counting and the concatenating for the new
// calculation columns
Column( dt, "PassFail " || Char( i ) )[dt << get selected rows] = colNames[i]
|| "; "
);
);
// See above comments for LSL
If( Is Missing( USL ) == 0,
dt << select where( As Column( dt, colNames[i] ) > USL );
If( N Rows( dt << get selected rows ) > 0,
Column( dt, "PassFail " || Char( i ) )[dt << get selected rows] = colNames[i]
|| "; "
);
);
);
);
// Clean up and selected columns
dt << clear select;
// Create the command string required for the formula for the
// Failing Tests, which is a concatenated string of all of the
// PassFail columns.
theExpr = "dt:Failing Tests << set formula(Concat(:PassFail 1";
For( i = 2, i <= N Items( colNames ), i++,
theExpr = theExpr || ",:PassFail " || Char( i )
);
theExpr = theExpr || "))";
// Execute the command string
Eval( Parse( theExpr ) );
// Delete the formula, which will remove the formula, but not
// the calculated values
dt:Failing Tests << delete formula;
// Create the command string for the Num Tests Failing column
// The count is the sum of the "True" Boolean comparisions.
// That is, if PassFail 1 != "", it will be "True" and therefore
// will have the value of 1. If the cell is blank, it will have a
// value of 0. The sum of all of these comparisons will be equal to
// the number of non passing parameters(tests)
theExpr = "dt:Num Tests Failing << set formula(sum(:PassFail 1 != \!"\!"";
For( i = 2, i <= N Items( colNames ), i++,
theExpr = theExpr || ",:PassFail " || Char( I ) || " != \!"\!""
);
theExpr = theExpr || "));";
Eval( Parse( theExpr ) );
dt:Num Tests Failing << delete formula;
// Delete all of the PassFail columns, just to clean up the data table
dt << delete columns(index(n cols(dt)-N items(colNames)+1,ncols(dt)));