スクリプトはスクリプト エディターでは機能しますが、メニュー項目では機能しません (Get Column Names の動作が異なります)スクリプト エディターから次のスクリプトを実行すると、問題なく動作します。しかし、[表示] -> [カスタマイズ] で作成したカスタム メニュー項目から実行すると、機能しません。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( "Spec limits" ) /*###*/
一体何が起こっているのか分かりますか?スクリプト エディタから呼び出した場合とメニュー ショートカットから呼び出した場合で、[列名を取得] 関数の動作が異なるのはなぜですか?
以下のコード。はい、一部はごちゃごちゃしています。
//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: スクリプトはスクリプト エディターでは機能しますが、メニュー項目では機能しません (Get Column Names が同じように動作しない)1. コードを JSL として表示するには、入力ウィンドウの上部にある ツールを使用してテキストを入力する必要があります。
2. 私のコードがあなたの方法よりも速く動作すると私が信じる主な理由は、2 つの項目に基づいています。
を。 はい、式は最適化されています。
b. dt << Select Where を使用すると、検索されたすべての行に一度に割り当てることができるため、非常に高速です。コードに含まれるすべての "IF" ステートメントを使用してデータ テーブルをループすると、非常に遅くなります。
3.キャラクタースペックの限界値について。仕様制限をどのように割り当てていますか?Spec Limits カラム プロパティは、数値のみを許可する必要があります。Substr() などの文字関数を使用して Spec Limits リストにアクセスしている場合は、文字列が返されます。JSL リストの操作方法については、スクリプト ガイドを参照してください。
Re: スクリプトはスクリプト エディターでは機能しますが、メニュー項目では機能しません (Get Column Names が同じように動作しない)ジムのスクリプトをありがとう! おっしゃるとおり、変数のスコープ設定が JMP スクリプトでどのように機能するかはわかりませんが、宣言された変数のデフォルトがローカル変数であることを示唆する証拠を見たことがあります。
これらのフォーラムでスクリプトが正しく表示されるようにするにはどうすればよいですか?これらのフォーラムのコード ウィンドウにコードを貼り付けると、書式設定が台無しになり、すべてのタブと空白のインデントが削除されます。Python コードを共有しようとしていないのは良いことです。
とにかく、私はあなたの要素を使用するようにスクリプトを調整していますが、最終的にはすでに機能しています。スクリプトを dt= current data table(); で直接使用してみました。もう1つか2つ編集しましたが、うまくいきませんでした。スクリプトが非効率的であることはわかっていますが、たとえば、USL と LSL を数値に変換する試みはすべて失敗したため、文字列に変換して部分文字列を使用する必要がありました。コメントに記載されている調整を行って、すべての仕様制限を一度だけ抽出する場合、それはあまり問題にはなりません。開いているファイルの例を見ることも役に立ちます。なぜなら、私が本当にやりたいのは、分析しているファイルとは異なるファイルからテスト制限を引き出すオプションがあるからです!
私にとって奇妙なのは、2 つの入れ子になった For ループよりも列を追加して削除する方が効率的であるというあなたの暗示です (スクリプトの方が高速であると言ったため)。コンピューターは、データ テーブル内のすべてのセルを分析する必要があります。JMP は、式の設定と実行がより効率的になるように最適化されていますか?あなたのアプローチが実際に機能して見つけようとすることができません。おそらく、フォローアップのポーザーが示唆することを試してみるべきです.
ところで、私のデータ テーブルには 600 列程度のものがあり、何万行もある可能性があるため、実行効率を考慮する必要があるかもしれません。
とにかく、スクリプトを機能させるために必要な最小限の変更は、すべてを置き換えることでした
colNames[colInd]
と
列( dt, colNames[colInd] ) .
私のデータ ファイルで動作させることはできませんが、スクリプトの要素をさらにいくつか調整してみます。
Re: スクリプトはスクリプト エディターでは機能しますが、メニュー項目では機能しません (Get Column Names が同じように動作しない)ジム、
良くやった。追加する必要がありました
dt << Run Formulas;
Eval(Parse(theExpr)) の後、delete 式ステートメントの前に、適切に作成されたスクリプトの 2 つの場所で。
Re: スクリプトはスクリプト エディターでは機能しますが、メニュー項目では機能しません (Get Column Names が同じように動作しない)私の推測では、変数 (:) を具体的にスコープしていないため、2 つの異なる環境で実行しようとすると問題が発生するということです。私が観察したもう1つの項目は、あなたのメソッドが非常に遅いコードになるということです.そのため、両方の環境で機能し、はるかに高速に実行されると思われるいくつかの方法を使用して、スクリプトを書き直しました。以下のスクリプトは、JMP で分配解除された半導体機能データ テーブルに対して実行されます。ただし、そのテーブルを開くことへの参照を取り除き、データ テーブルの 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)));