Ho una formula di colonna che testa un prodotto che può essere superato o meno in base ai limiti delle specifiche. Un array associativo viene utilizzato per fare riferimento a un limite inferiore e superiore di diverse specifiche del prodotto. Il problema che sto riscontrando è che l'utente seleziona le specifiche del prodotto che desidera importare nella colonna pass/fail. Sono diversi ogni volta, dopo essere stati referenziati da una tabella di dati diversa. L'obiettivo è fare in modo che la colonna della formula esegua un'iterazione nell'elenco delle specifiche richieste, controllando se ognuna rientra nei limiti. In tal caso, verrà attribuita una classifica generale Pass/Fallito. Lo farei al di fuori della colonna della formula, ma una parte successiva dello script aggiornerà ripetutamente quella colonna della formula per continuare l'analisi del passaggio e del fallimento modificando le tolleranze limite delle specifiche. Credo che l'intero calcolo dovrebbe essere nella formula della colonna stessa
Ho allegato due tabelle di dati e lo script di lavoro in corso di seguito.
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);e il mio script jsl di seguito.
Molto probabilmente costruirei la formula come una stringa e poi valuterei nella colonna (vedi Inserisci un'espressione in un'altra usando Eval Insert, Eval Expr, Parse e Substitute )
Questo non è lo script più semplice da capire, ma eseguilo in parti e aggiungi debug show() qua e là per capirlo meglio.
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));
)));
Potresti anche pensare di utilizzare le proprietà della colonna Limiti spec a seconda di ciò che stai facendo.