インタラクティブなスライダー ボックスを使用してインタラクティブなパレート プロットを作成し、列の式を更新する生産中の製品が通過する必要がある一連の仕様があります。 各仕様で必要な値 (制限) を指定し、バイナリの合格/不合格を作成する式を含む列があります。 この式は、合格数とパーセンテージのパレート グラフを作成するために使用されます。 スライダー ボックスを使用してインタラクティブなパレート グラフを作成してテスト制限を調整し、これらの制限を変更するとテストに合格/不合格となる項目の量がどのように変化するかを確認したいと考えています。
私の主な問題は次の 2 つです。
1) テストされる製品タイプは複数あります。 製品ごとに一貫した数の仕様が存在するわけではないので、これらの仕様をリストに挿入し (添付のコードでは「仕様」になります)、外部データ テーブルを使用して目的の製品の仕様を記入する予定です。 これは私が助けを必要とするものではありませんが、変数を直接参照せずに for ループ内でスライダー ボックスやナンバー ボックスなどを入力する必要があるため、考慮すべき点です。
2) テスト目的で式を更新できるように、変数の配列 (仕様制限) が必要です。 これも for ループ内に置く必要があります。 現時点でのスクリプトでは、合格/不合格列の式で仕様制限の値が更新されていないようです。 スライダー ボックスが << inval コマンドを受け取り、グラフが更新されても、実際の合格/不合格列は更新されないため、何も起こりません。 現在、仕様制限を格納するために連想配列を使用しています。 これは正しい方法ではない可能性があります。
現在使用しているサンプル データ テーブルと現在のスクリプトを添付しました。 ありがとう!
Names default to here(1);
RangeMin = Associative array(["m1" => 0,
"m2" => 0,
"m3" => 0,
"thickness" => 0]);
RangeMax = Associative array(["m1" => 1,
"m2" =>1,
"m3" => 1,
"thickness" => 20]);
limit = Associative array(["m1" => 0.5,
"m2" => 0.5,
"m3" => 0,
"thickness" => 4]);
SliderVars = {0.5,0.5,0.5,10};
spec = {"m1","m2","m3","thickness"};
GraphingTable = current data table();
finalDisplay = New Window ("test", testlist = h list box());
:name("Pass/Fail") << Set Formula(
if((:thickness >= limit["thickness"] & :m3 >= limit["m3"] & m2 >= limit["m2"] & m1 >= limit["m1"]), "Pass", "Fail" )
);
PP= Graphing Table << Pareto Plot( Cause( :"Pass/Fail"n ) );
ValuesOutlineBox = Outline Box ( "Values", SliderList = v list box());
For(i=1, i<= n items(spec),i++,
SliderList << append(
h list box(
Text box(spec[i]),
testing = spec[i];
eval(
parse(
eval insert(
"Var^char(i)^ = ^SliderVars[i]^;
SB^char(i)^ = Slider Box(
^RangeMin << get value(spec[i])^,
^RangeMax << get value(spec[i])^,
Var^char(i)^,
NEB^char(i)^ << set( Var^char(i)^ );
limit[testing] = Var^char(i)^;
testlist[2] << Delete Box();
wait(0.1);
testlist << append(report(PP));
);"
);
);
),
testing = spec[i];
eval(
parse(
eval insert(
"NEB^char(i)^ = Number Edit Box( Var^char(i)^,
<< set function(
Function( {this},
Var^char(i)^ = this << get;
SB^char(i)^ << inval;
limit[testing] = Var^char(i)^;
testlist[2] << Delete Box();
wait(0.1);
testlist << append(report(PP));
)
)
);"
);
);
),
)
)
);
testlist << append(ValuesOutlineBox);
testlist << append(report(PP));品質およびプロセスエンジニアリングウィンドウズRe: インタラクティブなスライダー ボックスを使用してインタラクティブなパレート プロットを作成して列の式を更新するスペック配列は変更されていないようです。 私も最初はそう思っていました。 ただし、V リスト ボックス内の個々のボックスを参照することはできました。いつもお世話になっております。
Re: インタラクティブなスライダー ボックスを使用してインタラクティブなパレート プロットを作成して列の式を更新するありがとう! 良い例え。
Re: インタラクティブなスライダー ボックスを使用してインタラクティブなパレート プロットを作成して列の式を更新する値を変更するときは、スペック連想配列に保存する必要があると思います。 ただし、数値編集ボックスへの参照をリストまたは他の連想配列に保存してみることもできます。 あるいは、XPath (またはツリー構造を移動する他の手段) を使用して、必要なときにそれらの参照を取得することもできます。
Re: インタラクティブなスライダー ボックスを使用してインタラクティブなパレート プロットを作成して列の式を更新するこのスクリプトで別の問題が発生したので、ご意見を伺いたいと思いました。 仕様の数値編集ボックスに手動で数値を入力する場合、仕様を別のテーブルに保存できるボタンを追加したいと考えています。 ボタンを追加することは問題ありませんが、数値編集ボックスの現在の値をどのように参照できるかわかりません。 各関数の後に、それらは V リスト ボックスに追加され、それらの値は数式列で更新されます。 しかし、個々の数値編集ボックスの値を参照する方法や、それらの数値を保存して仕様を参照して別のデータ構造に入力する機能がない場合、これらの新しい制限をスクリプトに保存する方法がわかりません。 new_control H リスト ボックスを参照すると、for each ループを通過した最後のボックスのみが表示されます。 ご意見やご提案は何でも結構です。
Re: インタラクティブなスライダー ボックスを使用してインタラクティブなパレート プロットを作成して列の式を更新するJMP サポートによると、JMP 開発ではこれが意図しない動作であるとみなしたため、将来のリリースで対処される予定です。
Re: インタラクティブなスライダー ボックスを使用してインタラクティブなパレート プロットを作成して列の式を更新するありがとう。 レンジ スライダー ボックスの問題について何か連絡があれば、ぜひ知りたいと思います。
Re: インタラクティブなスライダー ボックスを使用してインタラクティブなパレート プロットを作成して列の式を更新するRange Slider Boxを使用したいのですが、4番目の引数として連想配列とリストを使用すると正しく動作しないようです(これについては明日サポートにメールを送信します)。 そこで、スライダー ボックスに戻ります。
これは、数式とダブル スライダー ボックスを使用するようになりました (Windows の変数名に依存するこのようなスクリプトを中断するのは非常に簡単です。そのため、名前空間などを追加する必要があるかもしれません)。
Names Default To Here(1);
//declare associative array for specs
specs = Associative Array();
//open limits file in JMP
LimitsTable = open("vinyl data limits.jmp", invisible);
//set testing data to be able to manipulate in JMP
GraphingTable = open("Vinyl Data.jmp");
//Select the Specs you want to compare by using a COL LIST BOX
ListNumericCols = GraphingTable << Get Column Names(numeric);
nw = New Window("Select Wanted Specifications", << Modal, << return result,
clb = Col List Box (<< Set Items (ListNumericCols))
);
ListSpecNames = nw["clb"];
show(ListSpecNames);
//insert spec names into associative array
for (i=1,i< (N Items(ListSpecNames) + 1), i++,
Insert Into(specs, ListSpecNames[i]);
ColSpec = Column(LimitsTable, 1); //1 is the coolumn for spec name
LimitList= {};
//Insert Lower Limit onto
for(j=1, j < (nrows(LimitsTable)+1), j++,
if (ColSpec[j] == ListSpecNames[i],
ColLimit = Column(LimitsTable, 2);//2 is the column for lower limit
MinVal = 0;
if(ColLimit[j] > 0, MinVal = ColLimit[j] / 2, MinVal = ColLimit[j]*2);
InsertInto(LimitList, MinVal );
break();
));
for(k=1, k < (nrows(LimitsTable)+1), k++,
if (ColSpec[k] == ListSpecNames[i],
ColLimit = Column(LimitsTable, 2);//2 is the column for lower limit
InsertInto(LimitList, ColLimit[k]);
break();
));
for(l=1, l < (nrows(LimitsTable)+1), l++,
if (ColSpec[l] == ListSpecNames[i],
ColLimit = Column(LimitsTable, 3);//3 is the column for lower limit
InsertInto(LimitList, ColLimit[l]);
break();
));
for(m = 1, m < (nrows(LimitsTable)+1), m++,
if (ColSpec[m] == ListSpecNames[i],
ColLimit = Column(LimitsTable, 3);//3 is the column for upper limit
MaxVal = 0;
if(ColLimit[m] > 0, MaxVal = ColLimit[m] *2, MaxVal = ColLimit[m] /2 );
InsertInto(LimitList, MaxVal );
break();
)
);
show (LimitList);
specs[ListSpecNames[i]] = LimitList
);
//show(specs); for debugging and making sure specs array is being populated
//sel_specs = Associative Array(ListSpecNames);
//specs << Intersect(sel_specs);
//*******************************************************************
//Create Pass Fail column if not existing.
if(!contains(GraphingTable << Get Column Names("String"), "Pass/Fail"),
GraphingTable << new column("Pass/Fail", Character);
);
//using a string to insert a formula into the row that can be called upon dynamically
formula_expr = Expr(
f = "If(All(";
For Each({{spec, limits}}, specs,
f ||= Eval Insert("^limits[2]^ < :^spec^ < ^limits[3]^ & ");
);
//drop last &
f = Left(f, Length(f) - 3);
f ||= "),"; // close all
f ||= "\!N\!t\!"PASS\!",\!"FAIL\!"
)";
Eval(EvalExpr(Column(GraphingTable, "Pass/Fail") << Set Formula(
Expr(Parse(f));
)));
);
formula_expr;
nw2 = New Window("test", testlist = H List Box(
ValuesOutlineBox = Outline Box("Values", SliderList = V List Box()),
Graphing Table << Pareto Plot(Cause(:"Pass/Fail"n))
));
For Each({{spec_name, spec_list, idx}}, specs,
new_control = H List Box(
Text Box(spec_name),
rsb = Slider Box(spec_list[1], spec_list[4]),
Number Edit Box(spec_list[2], << Set Minimum(spec_list[1]), << Set Maximum(spec_list[4]), << Set Function(function({this},
(this << Prev Sib) << Set(this << get);
formula_expr;
)))
);
Eval(EvalExpr(rsb << Set Var(specs[Expr(spec_name)][2])));
rsb << Set Function(function({this},
(this << sib) << Set(this << Get, Run Script(1));
));
SliderList << Append(new_control);
);
For Each({{spec_name, spec_list, idx}}, specs,
new_control = H List Box(
Text Box(spec_name),
rsb = Slider Box(spec_list[1], spec_list[4]),
Number Edit Box(spec_list[2], << Set Minimum(spec_list[1]), << Set Maximum(spec_list[4]), << Set Function(function({this},
(this << Prev Sib) << Set(this << get);
formula_expr;
)))
);
Eval(EvalExpr(rsb << Set Var(specs[Expr(spec_name)][3])));
rsb << Set Function(function({this},
(this << sib) << Set(this << Get, Run Script(1));
));
SliderList << Append(new_control);
);
問題の例:
Names Default To Here(1);
var1 = 1;
var2 = 2;
var3 = 2;
var4 = 1;
aa = ["low" => 1, "up" => 2];
l = {};
l[1] = 1;
l[2] = 2;
nw = New window("test",
rsb1 = Range Slider Box(1, 2, var1, var2, Show(1)),
rsb2 = Range Slider Box(1, 2, aa["low"], aa["up"]),
rsb2_1 = Range Slider Box(1, 2, aa["low"], var3),
rsb1_2 = Range Slider Box(1, 2, var4, aa["up"]),
rsb3 = Range Slider Box(1, 2, l[1], l[2]),
);
Show(rsb1 << Get Lower Var, rsb1 << Get Upper Var);
Show(rsb2 << Get Lower Var, rsb2 << Get Upper Var);
Show(rsb2_1 << Get Lower Var, rsb2_1 << Get Upper Var);
Show(rsb1_2 << Get Lower Var, rsb1_2 << Get Upper Var);
Show(rsb3 << Get Lower Var, rsb3 << Get Upper Var);
Eval(EvalExpr(rsb3 << Set Lower Var(Expr(Expr(l[1])))));
Eval(EvalExpr(rsb3 << Set Upper Var(Expr(Expr(l[2])))));
Show(rsb3 << Get Lower Var, rsb3 << Get Upper Var);
Re: インタラクティブなスライダー ボックスを使用してインタラクティブなパレート プロットを作成して列の式を更新する範囲スライダー ボックスの引数を処理するのではなく、各仕様の上限と下限に 1 つずつ、2 つのスライダー ボックスを用意したほうがうまく機能すると思いますか? 昨日のテストでは、レンジ スライダー ボックスに関してさらに多くの問題が発生しましたが、ボックス タイプの引数に関するドキュメントははるかに少なくなっています。 範囲ボックスの問題は解決すると思いますが、数式部分が複雑になる可能性があります。
Re: インタラクティブなスライダー ボックスを使用してインタラクティブなパレート プロットを作成して列の式を更新する式には少なくとも 2 つのオプションがあります。式を使用してスペックが更新されるたびに実行する式の値を更新するか、スペック連想配列を使用するように式を変更することができます。
f = "If(All(";
For Each({{spec, limits}}, specs,
f ||= Eval Insert("specs[\!"^spec^\!"][2] < :^spec^ < specs[\!"^spec^\!"][3] & ");
);
//drop last &
f = Left(f, Length(f) - 3);
f ||= "),"; // close all
f ||= "\!N\!t\!"PASS\!",\!"FAIL\!"
)";
レンジ スライダー ボックスはスライダー ボックスよりもさらに厄介なので、この問題を回避するのは大きな課題です。 おそらく Eval(EvalExpr()) を使用することはほとんどなく、単に Eval(Parse()) を使用して、そこで正しい参照を取得しようとするでしょう。 まずはレンジャー スライダー ボックスのみから始めて、それらが機能するようになったら、数値編集ボックスを 1 つずつ追加します (レンジ スライダー ボックスの 4 番目の引数は少しバグがあるかもしれません...)
Re: インタラクティブなスライダー ボックスを使用してインタラクティブなパレート プロットを作成して列の式を更新するここ数日間、皆様のご支援に大変感謝しております。 私はこれに対するあなたの解決策と私の他の投稿に取り組んできました。リストによって参照される連想配列に基づいて列の式を更新します。
私は parse 式と eval 式を調べて理解しようとし、それが JSL でどのように機能するかを理解しています。 2 つのアイデアを組み合わせるのに問題があります。 仕様を格納するには、連想配列に 4 つのインデックスを含めたほうがよいことに気づきました。「spec」という形式で => {<最低許容許容値>, <仕様の下限>, <仕様の上限>, <最大値許容誤差>}。 解析にご協力いただいたおかげで、以下のスクリプトはこの配列と合格/失敗列を作成して、すべての仕様が満たされているかどうかを確認できるようになりました。 目標は、製品の新たな望ましい合格歩留まりを得るために、限界内の公差を最小公差または最大公差まで緩めることと、上で修正したようにパレート図を更新することです。 制限の許容値を緩和するのにより直感的であるため、範囲スライダー ボックスを実装しようとしましたが、問題が発生しました。 また、以前のようにパレート図の自動更新も中断されます。
問題の 1 つは、"f" 文字列が最初に定義されているため、合格/不合格列の式を設定する将来の実行では更新されないと思われることだと思います。 何らかの方法でご協力いただければ幸いです。
Names Default To Here(1);
//declare associative array for specs
specs = Associative Array();
//open limits file in JMP
LimitsTable = open("vinyl data limits.jmp", invisible);
//set testing data to be able to manipulate in JMP
GraphingTable = open("Vinyl Data.jmp");
//Select the Specs you want to compare by using a COL LIST BOX
ListNumericCols = GraphingTable << Get Column Names(numeric);
nw = New Window("Select Wanted Specifications", << Modal, << return result,
clb = Col List Box (<< Set Items (ListNumericCols))
);
ListSpecNames = nw["clb"];
show(ListSpecNames);
//insert spec names into associative array
for (i=1,i< (N Items(ListSpecNames) + 1), i++,
Insert Into(specs, ListSpecNames[i]);
ColSpec = Column(LimitsTable, 1); //1 is the coolumn for spec name
LimitList= {};
//Insert Lower Limit onto
for(j=1, j < (nrows(LimitsTable)+1), j++,
if (ColSpec[j] == ListSpecNames[i],
ColLimit = Column(LimitsTable, 2);//2 is the column for lower limit
MinVal = 0;
if(ColLimit[j] > 0, MinVal = ColLimit[j] / 2, MinVal = ColLimit[j]*2);
InsertInto(LimitList, MinVal );
break();
));
for(k=1, k < (nrows(LimitsTable)+1), k++,
if (ColSpec[k] == ListSpecNames[i],
ColLimit = Column(LimitsTable, 2);//2 is the column for lower limit
InsertInto(LimitList, ColLimit[k]);
break();
));
for(l=1, l < (nrows(LimitsTable)+1), l++,
if (ColSpec[l] == ListSpecNames[i],
ColLimit = Column(LimitsTable, 3);//3 is the column for lower limit
InsertInto(LimitList, ColLimit[l]);
break();
));
for(m = 1, m < (nrows(LimitsTable)+1), m++,
if (ColSpec[m] == ListSpecNames[i],
ColLimit = Column(LimitsTable, 3);//3 is the column for upper limit
MaxVal = 0;
if(ColLimit[m] > 0, MaxVal = ColLimit[m] *2, MaxVal = ColLimit[m] /2 );
InsertInto(LimitList, MaxVal );
break();
)
);
show (LimitList);
specs[ListSpecNames[i]] = LimitList
);
//show(specs); for debugging and making sure specs array is being populated
//sel_specs = Associative Array(ListSpecNames);
//specs << Intersect(sel_specs);
//*******************************************************************
//Create Pass Fail column if not existing.
if(!contains(GraphingTable << Get Column Names("String"), "Pass/Fail"),
GraphingTable << new column("Pass/Fail", Character);
);
//using a string to insert a formula into the row that can be called upon dynamically
f = "If(All(";
For Each({{spec, limits}}, specs,
f ||= Eval Insert("^limits[2]^ < :^spec^ < ^limits[3]^ & ");
);
//drop last &
f = Left(f, Length(f) - 3);
f ||= "),"; // close all
f ||= "\!N\!t\!"PASS\!",\!"FAIL\!"
)";
Eval(EvalExpr(Column(GraphingTable, "Pass/Fail") << Set Formula(
Expr(Parse(f));
)));
nw2 = New Window("test", testlist = H List Box(
ValuesOutlineBox = Outline Box("Values", SliderList = V List Box()),
Graphing Table << Pareto Plot(Cause(:"Pass/Fail"n))
));
filler = {};
For Each({{spec_name, spec_list, idx}}, specs,
new_control = H List Box(
Text Box(spec_name),
Range Slider Box(spec_list[1], spec_list[4] , spec_list[2], spec_list[3], << Set Function(function({this},
(this << Sib) << Set(this << get, run Script(1));
))) ,
Number Edit Box(spec_list[2], << Set Minimum(spec_list[1]), << Set Maximum(spec_list[4]), << Set Function(function({this},
(this << Prev Sib) << Set(this << get);
specs[((this << parent) << child) << get text][2] = this << get;
Column(GraphingTable, "Pass/Fail") << Eval Formula;
))),
Number Edit Box(spec_list[3], << Set Minimum(spec_list[1]), << Set Maximum(spec_list[4]), << Set Function(function({this},
(this << Prev Sib) << Set(this << get);
specs[((this << parent) << child) << get text][3] = this << get;
Column(GraphingTable, "Pass/Fail") << Eval Formula;
)))
);
SliderList << Append(new_control);
);
Re: インタラクティブなスライダー ボックスを使用してインタラクティブなパレート プロットを作成して列の式を更新するどうもありがとうございます! JSL でスクリプトを作成するのはこれで 2 週間目ですが、どれだけ私を助けてくれたかわかりません。
Re: インタラクティブなスライダー ボックスを使用してインタラクティブなパレート プロットを作成して列の式を更新するコードはかなり大幅に変更されており、これがどの程度信頼できるかは 100% わかりませんが、スライダー ボックスに関連する正しい参照を取得するには、set 関数と child/sib/parent を使用します。 また、式の値が更新されるとパレートも更新されるようです。 これには、Eval(EvalExpr()) を使用すると利点があるかもしれません。
Names Default To Here(1);
specs = Associative Array();
specs["m1"] = {0, 0.5, 1};
specs["m2"] = {0, 0.5, 1};
specs["m3"] = {0, 0, 1};
specs["thickness"] = {0, 4, 20};
GraphingTable = Current Data Table();
Column(GraphingTable, "Pass/Fail") << Set Formula(
If((:thickness >= specs["thickness"][2] & :m3 >= specs["m3"][2] & m2 >= specs["m2"][2] & m1 >= specs["m1"][2]),
"Pass",
"Fail"
)
);
nw = New Window("test", testlist = H List Box(
ValuesOutlineBox = Outline Box("Values", SliderList = V List Box()),
Graphing Table << Pareto Plot(Cause(:"Pass/Fail"n))
));
filler = {};
For Each({{spec_name, spec_list, idx}}, specs,
new_control = H List Box(
Text Box(spec_name),
Slider Box(spec_list[1], spec_list[3], 0, << Set Function(function({this},
(this << Sib) << Set(this << get, run Script(1));
))),
Number Edit Box(spec_list[2], << Set Minimum(spec_list[1]), << Set Maximum(spec_list[3]), << Set Function(function({this},
(this << Prev Sib) << Set(this << get);
specs[((this << parent) << child) << get text][2] = this << get;
Column(GraphingTable, "Pass/Fail") << Eval Formula;
)));
);
SliderList << Append(new_control);
);
コードでは、更新された制限連想配列の値を取得するテストの周りで ^ が欠落している可能性があるようです。