Ich habe eine Spaltenformel, die ein Produkt testet, das basierend auf Spezifikationsgrenzen entweder bestehen oder nicht bestehen kann. Ein assoziatives Array wird verwendet, um auf eine untere und obere Grenze verschiedener Spezifikationen des Produkts zu verweisen. Das Problem, das ich habe, ist, dass der Benutzer die Produktspezifikationen auswählt, die er in die Pass/Fail-Spalte importieren möchte. Sie sind jedes Mal anders, nachdem sie von einer anderen Datentabelle referenziert wurden. Das Ziel ist, dass die Formelspalte die Liste der angeforderten Spezifikationen durchläuft und prüft, ob jede innerhalb der Grenzen liegt. Wenn dies der Fall ist, wird eine Gesamtklassifikation bestanden/nicht bestanden vergeben. Ich würde dies außerhalb der Formelspalte tun lassen, aber ein späterer Teil des Skripts wird diese Formelspalte wiederholt aktualisieren, um die Analyse des Bestehens und Nichtbestehens fortzusetzen, indem die Spezifikationsgrenztoleranzen geändert werden. Ich glaube, die gesamte Berechnung müsste in der Spaltenformel selbst stehen
Ich habe zwei Datentabellen und das Work-in-Progress-Skript unten angehängt.
Names Default To Here(1);
//declare associative array for specs
specs = Associative Array();/*
//input limits file
LimitsCSV = Pick File(
"Select The Appropriate Spec Limit Table",
"filepath"//Insert file path here.
);
//open limits file in JMP
LimitsTable = open( LimitsCSV, invisible);
//Open Current Product Testing Data
DataTable = Pick File(
"Select The Current Product Testing Data",
"filepath"// Insert File Path Here
);
//set testing data to be able to manipulate in JMP
GraphingTable = open(DataTable);
//Select the Specs you want to compare by using a COL LIST BOX
ListNumericCols = GraphingTable << Get Column Names(numeric);
New Window("Select Wanted Specifications", << Modal,
clb = Col List Box (<< Set Items (ListNumericCols))
);
ListSpecNames = clb << Get Selected;
show(ListSpecNames); //Display for testing
//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);//14 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);//14 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);//14 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);//14 is the column for upper limit
MaxVal = 0;
if(ColLimit[m] > 0, MaxVal = ColLimit[m] *2, MaxVal = ColLimit[m] /2 );
InsertInto(LimitList, MaxVal );
break();
)
);
specs[ListSpecNames[i]] = LimitList
);
close(LimitsTable, no save);
PassBool = 1;
ColNameList = GraphingTable << get column names(string);
newcolumn = "Pass/Fail";
if (!contains(ColNameList, NewColumn),
GraphingTable << new column("Pass/Fail"));/*
if(((column("m1") >= specs["m1"][2]) & (column("m2") <= specs["m2"][3])),
show("Pass"),
show("Fail")
);*/
Column(GraphingTable, "Pass/Fail") << Set Formula(
//counter = 0;
for(i=1,i< (N Items(ListSpecNames) + 1), i++,
if((Column(ListSpecNames[i]) >= specs[ListSpecNames[i]][2]) & (Column(ListSpecNames[i]) <= specs[ListSpecNames[i]][3]),
show("Pass"),
show("Fail");
PassBool = 0;
break();
)
) ;
If(PassBool == 1, "Pass","Fail")
);
show(specs);und mein JSL-Skript unten.
Ich würde die Formel höchstwahrscheinlich als Zeichenfolge erstellen und dann in die Spalte auswerten (siehe Fügen Sie mit Eval Insert, Eval Expr, Parse und Substitute einen Ausdruck in einen anderen ein )
Dies ist nicht das am einfachsten zu verstehende Skript, aber führen Sie es in Teilen aus und fügen Sie hier und da debug show() hinzu, um es besser zu verstehen.
Names Default To Here(1);
//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"];
// https://www.jmp.com/support/help/en/16.2/#page/jmp/associative-arrays-in-set-operations.shtml
specs = Associative Array(LimitsTable[0, 1],
AsList(LimitsTable[0, 2::3])
);
close(LimitsTable, no save);
sel_specs = Associative Array(ListSpecNames);
specs << Intersect(sel_specs);
if(!contains(GraphingTable << Get Column Names("String"), "Pass/Fail"),
GraphingTable << new column("Pass/Fail", Character);
);
// as we have to have a formula and we have to build it dynamically, we will build it as expression
// which is based on specs associative array
// with JMP16 we can use For Each, otherwise we would have to use For
// I dont like using eval parse but in this case it is most likely easiest to build formula as string
f = "If(All(";
For Each({{spec, limits}}, specs,
f ||= Eval Insert("^limits[1]^ < :^spec^ < ^limits[2]^ & ");
);
//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));
)));
Sie könnten auch darüber nachdenken, die Spalteneigenschaften der Spezifikationsgrenzen zu verwenden, je nachdem, was Sie tun.