使用交互式滑塊框創建交互式帕累托圖以更新列公式我有一套生產中的產品需要通過的規範。 我有一個包含公式的列,該公式指定每個規範所需的值(限制),並創建二進制通過/失敗。 該公式用於創建通過次數和百分比的帕累托圖。 我想創建一個帶有滑塊框的交互式帕累托圖來調整測試限制,並了解更改這些限制將如何改變通過/未通過測試的項目數量。
我的主要問題有以下兩個:
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));質量和工藝工程視窗回复:使用交互式滑塊框創建交互式帕累托圖以更新列公式它似乎沒有改變規格數組。 我一開始也是這麼想的。 不過,我能夠引用 V 列錶框中的各個框。我一如既往地感謝您的幫助。
回复:使用交互式滑塊框創建交互式帕累托圖以更新列公式謝謝! 好例子。
回复:使用交互式滑塊框創建交互式帕累托圖以更新列公式我認為當您更改這些值時,應該將它們保存到規格關聯數組中。 但您也可以嘗試將對數字編輯框的引用保存到列表或其他關聯數組中。 或者,也許您可以使用 XPath(或其他一些方式來遍歷樹結構)來在需要時獲取這些引用。
回复:使用交互式滑塊框創建交互式帕累托圖以更新列公式我遇到了這個腳本的另一個問題,我希望得到你的想法。 如果我在規格的數字編輯框中手動輸入一個數字,我想添加一個按鈕以便能夠將規格保存到另一個表中。 添加按鈕不是問題,但我不知道如何能夠引用數字編輯框的當前值。 在 foreach 函數之後,它們被添加到 V 列錶框,並且這些值在公式列中更新。 但是,如果沒有辦法引用各個數字編輯框的值,或者無法存儲這些數字並參考規範將它們輸入到單獨的數據結構中,我不知道如何在腳本中保存這些新限制。 引用 new_control H 列錶框將僅顯示經過 foreach 循環的最後一個框。 任何想法或建議都會很棒。
回复:使用交互式滑塊框創建交互式帕累托圖以更新列公式根據 JMP 支持,JMP 開發認為這是意外行為,將在未來版本中解決。
回复:使用交互式滑塊框創建交互式帕累托圖以更新列公式謝謝。 如果您聽到有關範圍滑塊框問題的任何反饋,我將非常有興趣查看。
回复:使用交互式滑塊框創建交互式帕累托圖以更新列公式我會使用範圍滑塊框,但它似乎無法與關聯數組和列表作為第四個參數正常工作(我明天將發送電子郵件來支持這一點)。 所以我會回到滑塊盒。
現在使用公式表達式和雙滑塊框(很容易破壞這樣的腳本,這些腳本依賴於窗口中的變量名稱,因此您可能需要添加命名空間或其他內容)
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);
回复:使用交互式滑塊框創建交互式帕累托圖以更新列公式您認為使用兩個滑塊框(一個用於每個規範的上限,一個用於下限)與處理範圍滑塊框的參數相比,效果會更好嗎? 昨天的測試在範圍滑塊框方面產生了更多問題,而有關框類型參數的文檔卻少得多。 我認為這會解決範圍框問題,但可能會使公式部分複雜化。
回复:使用交互式滑塊框創建交互式帕累托圖以更新列公式對於公式,您至少有兩個選擇:您可以使用表達式來更新每次更新規格時運行的公式中的值,或者修改公式以使用規格關聯數組
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\!"
)";
Range Slider Box 比 Slider Box 更混亂,因此解決這個問題是更大的挑戰。 我很可能不會為 Eval(EvalExpr()) 煩惱,我只會使用 Eval(Parse()) 並嘗試在那裡獲取正確的引用。 我會從僅 Ranger Slider Box 開始,在這些工作完成後,我會一次添加一個數字編輯框(Range Slider Boxes 第四個參數可能有點問題......)
回复:使用交互式滑塊框創建交互式帕累托圖以更新列公式我非常感謝您過去幾天給予的幫助。 我一直在研究你的解決方案以及我的其他帖子,根據列表引用的關聯數組更新列公式。
我已經仔細研究並嘗試計算出 parse 和 eval 表達式,並且了解了它在 jsl 中的工作原理。 我在結合這兩個想法時遇到問題。 我意識到最好在關聯數組中有 4 個索引來存儲規格。格式為 "spec" => {<允許的最低容差>, <規格下限>, <規格上限>, <最大允許的公差>} 。 感謝您在解析方面的幫助,下面的腳本現在創建了此數組和“通過/失敗”列,以查看是否滿足所有規格。 目標是放寬限制公差,直至最低或最大公差,以獲得新的所需產品合格率,並更新上面修復的帕累托圖。 我嘗試實現範圍滑塊框,因為這對於放寬限制公差會更直觀,但遇到了麻煩。 它還像以前一樣打破了帕累托圖自動更新。
我相信一個問題可能是,因為“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);
);
回复:使用交互式滑塊框創建交互式帕累托圖以更新列公式太感謝了! 這是我使用 JSL 編寫腳本的第二週,您不知道您幫了我多大的忙。
回复:使用交互式滑塊框創建交互式帕累托圖以更新列公式代碼經過相當多的修改,我不能 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);
);
在您的代碼中,您似乎可能缺少 ^ 測試以更新限制關聯數組中的值。