使用交互式滑块框创建交互式帕累托图以更新列公式我有一套生产中的产品需要通过的规范。 我有一个包含公式的列,该公式指定每个规范所需的值(限制),并创建二进制通过/失败。 该公式用于创建通过次数和百分比的帕累托图。 我想创建一个带有滑块框的交互式帕累托图来调整测试限制,并了解更改这些限制将如何改变通过/未通过测试的项目数量。
我的主要问题有以下两个:
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);
);
在您的代码中,您似乎可能缺少 ^ 测试以更新限制关联数组中的值。