Lo script funziona nell'editor di script ma non sulla voce di menu (Ottieni nomi di colonna che non si comportano allo stesso modo)Quando eseguo il seguente script dall'editor di script, funziona correttamente.Ma quando lo eseguo da una voce di menu personalizzata che ho creato in Visualizza-> Personalizza, non funziona.L'ho rintracciato fino alla funzione Ottieni nomi colonna che non si comporta allo stesso modo.Quando inserisco un'istruzione print per emettere il valore di ogni nome di colonna e il relativo tipo prima di utilizzare Ottieni proprietà su di essa, vedo questo (ad esempio) durante l'esecuzione dall'editor di script:
:exec_typ
"Nome"
TUTTAVIA, quando lo eseguo dalla mia voce di menu, ottengo questo:
exec_typ
"Nome"
Notare la mancanza del colon.(Qualunque cosa facciano i due punti, non lo so.)
Alla fine, lo script si arresta in modo anomalo perché quando provo a eseguire la funzione Ottieni proprietà sulla colonna denominata exec_typ, JMP non lo riconosce come nome di colonna o qualcosa del genere:
Send Expects Scriptable Object{7} nell'accesso o nella valutazione di 'Send' , colNames[colInd] << /*###*/Get Property( "Spec limit" ) /*###*/
Qualche idea su cosa diavolo sta succedendo?Perché la funzione Ottieni nomi colonna si comporta in modo diverso se chiamata dall'editor di script rispetto a un collegamento di menu?
Codice qui sotto.Sì, in parte è disordinato.
//Reports all failing tests for a unit. Not temperature-smart (yet!)
dt = Current Data Table();
colNames = dt << get column names(Numeric);
//I need to clean up the add columns scripts... once I understand how it works.
dt << add multiple columns(
"Num Tests Failing",
1,
After( "20:Neg_Contact:Cont_int2[1]" ),
numeric( 10 )
);
colf = Column( "Num Tests Failing" );
colf << Modeling Type ( Nominal );
dt << add multiple columns(
"Failing Tests",
1,
After( "20:Neg_Contact:Cont_int2[1]" ),
numeric( 10 )
);
colf = Column( "Failing Tests" );
colf << Data type( Character );
For (i = 1, i <= N Rows(dt), i++,
Row() = i;
failingTests = "";
NumOfFailingTests = 0;
If (:Name("HBIN_NAM") != "Good" & :Name("HBIN_NAM") != "1:Good" , //It's a fail
//Efficiency could be improved by extracting all spec limits first.
For (colInd = 1, colInd <= N Items(colNames), colInd++,
//print statements for debugging.
print(colNames[colInd]);
print(Type(colNames[colInd]));
//THIS IS WHERE IT KEEPS CRASHING
specLimits = colNames[colInd] << Get Property ("Spec limits");
LSL_Char = Char(specLimits[1]);
USL_Char = Char(specLimits[2]);
LSL_Char = SubStr(LSL_Char, 5, (Length(LSL_Char) - 5));
USL_Char = SubStr(USL_Char, 5, (Length(USL_Char) - 5));
LSL_Num = 0; //initializing value to set its scope; is this necessary? Donno.
USL_Num = 0;
If(LSL_Char == "." | LSL_Char == "",
LSL_Char = "NO LIMIT",
//else
LSL_Num = Num(LSL_Char);
);
If(USL_Char == "." | USL_Char == "",
USL_Char = "NO LIMIT",
//else
USL_Num = Num(USL_Char);
);
failedTest = 0;
If(LSL_Char != "NO LIMIT",
If( colNames[colInd][i] < LSL_Num,
failedTest = 1;
NumOfFailingTests = NumOfFailingTests + 1;
);
);
If(USL_Char != "NO LIMIT",
If( colNames[colInd][i] > USL_Num,
failedTest = 1;
NumOfFailingTests = NumOfFailingTests + 1;
);
);
If(failedTest == 1,
failingTests = failingTests || Char(colNames[colInd]) || "; ";
);
);
);
:Name( "Failing Tests" )[i] = failingTests;
:Name( "Num Tests Failing" )[i] = NumOfFailingTests;
);
Re: Script funziona nell'editor di scripting ma non sulla voce di menu (Ottieni i nomi delle colonne che non si comportano allo stesso modo)1. Per visualizzare il codice come JSL, è necessario utilizzare lo strumento nella parte superiore della finestra di immissione per l'immissione del testo.
2. Il motivo principale per cui credo che il mio codice funzionerà più velocemente del tuo metodo è basato su 2 elementi.
un. Sì, le formule sono ottimizzate.
b. L'uso del dt << Select Where accoppiato con la possibilità di assegnare a tutte le righe selezionate contemporaneamente è estremamente veloce.Il ciclo di una tabella di dati con tutte le istruzioni "IF" del codice è molto lento.
3. Per quanto riguarda i valori limite delle specifiche del tuo personaggio.Come stai assegnando i limiti delle specifiche?La proprietà della colonna Limiti delle specifiche dovrebbe consentire solo valori numerici.Se stai accedendo all'elenco dei limiti delle specifiche utilizzando funzioni di carattere come Substr(), otterrai le stringhe di caratteri.Dai un'occhiata alla Guida agli script su come manipolare le liste JSL
Re: Script funziona nell'editor di scripting ma non sulla voce di menu (Ottieni i nomi delle colonne che non si comportano allo stesso modo)Grazie per la sceneggiatura Jim! Hai ragione, non ho idea di come funzioni l'ambito delle variabili nello script JMP, tranne per il fatto che ho visto alcune prove che suggeriscono che le variabili dichiarate per impostazione predefinita siano variabili locali.
Come hai fatto a visualizzare correttamente il tuo script su questi forum?Quando incollo il codice nella finestra del codice su questi forum, rovina la formattazione ed elimina tutte le schede e il rientro degli spazi bianchi.Meno male che non stiamo cercando di condividere il codice Python!
Ad ogni modo, sto adattando il mio script per utilizzare elementi del tuo e finalmente sta già funzionando.Ho provato a usare il tuo script direttamente con dt= current data table(); e un'altra modifica o due, ma non ha funzionato.Conosco il mio script inefficiente, ma, ad esempio, tutti i miei tentativi di convertire USL e LSL in numeri sono falliti, quindi ho dovuto semplicemente convertirlo in una stringa e utilizzare una sottostringa.Se effettuo la regolazione, noto nei commenti di estrarre tutti i limiti delle specifiche una sola volta, non importa troppo.È anche utile vedere anche un esempio di file aperto, perché quello che mi piacerebbe davvero fare è avere la possibilità di estrarre i limiti di test da file diversi da quello che sto analizzando!
La cosa strana per me è la tua implicazione (perché hai detto che il tuo script era più veloce) che aggiungere colonne ed eliminarle sarebbe più efficiente di due cicli For nidificati.Il computer deve ancora analizzare ogni singola cella nella tabella dei dati.JMP è ottimizzato in modo tale che l'impostazione e l'esecuzione delle formule sia più efficiente?Non riesco a convincere il tuo approccio a lavorare davvero per cercare di scoprirlo, forse dovrei provare quello che suggerisce il posatore di follow-up.
A proposito, le mie tabelle di dati hanno qualcosa come 600 colonne e possono avere decine di migliaia di righe, quindi potrebbe essere necessario esaminare considerazioni sull'efficienza dell'esecuzione.
Ad ogni modo, la modifica minima che dovevo apportare per far funzionare il mio script era sostituire tutti i file
colNames[colInd]
insieme a
Colonna( dt, colNames[colInd] ) .
Anche se non riesco a farlo funzionare con i miei file di dati, proverò ad adattare alcuni elementi in più dal tuo script.
Re: Script funziona nell'editor di scripting ma non sulla voce di menu (Ottieni i nomi delle colonne che non si comportano allo stesso modo)Jim,
Bel lavoro.avevo bisogno di aggiungere
dt << Run Formulas;
dopo Eval(Parse(theExpr)) e prima dell'istruzione della formula delete, in due punti del tuo script ben scritto.
Re: Script funziona nell'editor di scripting ma non sulla voce di menu (Ottieni i nomi delle colonne che non si comportano allo stesso modo)La mia ipotesi è che dal momento che non stai specificando l'ambito delle tue variabili (:), stai riscontrando problemi quando provi a eseguire nei 2 diversi ambienti.L'altro elemento che ho osservato è che il tuo metodo risulterà in un pezzo di codice molto lento.Detto questo, ho riscritto il tuo script, usando alcuni metodi che credo funzioneranno in entrambi gli ambienti e funzioneranno anche molto più velocemente.Lo script seguente viene eseguito sulla tabella di dati Semiconductor Capability che è deistribuita con JMP.Ma se togli semplicemente il riferimento all'apertura di quella tabella, insieme all'istruzione che segue l'Apri della tabella dei dati e li sostituisci con il tuo
dt = tabella dati corrente();
il codice dovrebbe funzionare sui tuoi dati.
Ho annotato il codice qui sotto, quindi penso che dovresti essere in grado di seguirlo.Inoltre, TI CONSIGLIO VIVAMENTE di leggere la Guida agli script distribuita con la tua installazione di JMP.
Aiuto==>Libri==>Guida agli script
Ti dirà tutto su cosa sono quei due punti pazzi
Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/semiconductor capability.jmp" );
dt << delete columns( {2, 3, 4} );
// Get the numeric column names as strings
colNames = dt << get column names( Numeric, string );
// Create the new calculated columns
// They will be populated later
dt << New Column( "Num Tests Failing", numeric );
dt << New Column( "Failing Tests", character );
// Create a new column for each column in the colNames list
// and populate the colNames name, if it does NOT pass
For( i = 1, i <= N Items( colNames ), i++,
// Create the new colum
dt << New Column( "PassFail " || Char( i ), character );
// Get the Spec Limits for the first column
specLimits = Column( dt, colNames[i] ) << get property( "Spec Limits" );
// If no Spec Limits are found, do not process
If( Is Empty( specLimits ) == 0,
// Get the USL and LSL and if not present set to missing
LSL = Try( specLimits["LSL"], . );
USL = Try( specLimits["USL"], . );
// If the LSL is not missing process
If( Is Missing( LSL ) == 0,
// Find all rows where the colNames column is less than
// the LSL
dt << select where( As Column( dt, colNames[i] ) < LSL );
// If any rows are selected, then process
If( N Rows( dt << get selected rows ) > 0,
// Set the value in the PassFail column to the name of
// the colNames being processed. This will allow for
// the counting and the concatenating for the new
// calculation columns
Column( dt, "PassFail " || Char( i ) )[dt << get selected rows] = colNames[i]
|| "; "
);
);
// See above comments for LSL
If( Is Missing( USL ) == 0,
dt << select where( As Column( dt, colNames[i] ) > USL );
If( N Rows( dt << get selected rows ) > 0,
Column( dt, "PassFail " || Char( i ) )[dt << get selected rows] = colNames[i]
|| "; "
);
);
);
);
// Clean up and selected columns
dt << clear select;
// Create the command string required for the formula for the
// Failing Tests, which is a concatenated string of all of the
// PassFail columns.
theExpr = "dt:Failing Tests << set formula(Concat(:PassFail 1";
For( i = 2, i <= N Items( colNames ), i++,
theExpr = theExpr || ",:PassFail " || Char( i )
);
theExpr = theExpr || "))";
// Execute the command string
Eval( Parse( theExpr ) );
// Delete the formula, which will remove the formula, but not
// the calculated values
dt:Failing Tests << delete formula;
// Create the command string for the Num Tests Failing column
// The count is the sum of the "True" Boolean comparisions.
// That is, if PassFail 1 != "", it will be "True" and therefore
// will have the value of 1. If the cell is blank, it will have a
// value of 0. The sum of all of these comparisons will be equal to
// the number of non passing parameters(tests)
theExpr = "dt:Num Tests Failing << set formula(sum(:PassFail 1 != \!"\!"";
For( i = 2, i <= N Items( colNames ), i++,
theExpr = theExpr || ",:PassFail " || Char( I ) || " != \!"\!""
);
theExpr = theExpr || "));";
Eval( Parse( theExpr ) );
dt:Num Tests Failing << delete formula;
// Delete all of the PassFail columns, just to clean up the data table
dt << delete columns(index(n cols(dt)-N items(colNames)+1,ncols(dt)));