Das Skript funktioniert im Skripteditor, aber nicht im Menüelement (Get Column Names verhält sich nicht gleich).Wenn ich das folgende Skript im Skripteditor ausführe, funktioniert es einwandfrei.Aber wenn ich es über ein benutzerdefiniertes Menüelement ausführe, das ich in Ansicht->Anpassen erstellt habe, funktioniert es nicht.Ich habe es auf die Funktion Get Column Names zurückgeführt, die sich nicht gleich verhält.Wenn ich eine Druckanweisung setze, um den Wert jedes Spaltennamens und seines Typs auszugeben, bevor ich Get Property darauf verwende, sehe ich dies (zum Beispiel), wenn ich vom Skripteditor aus laufe:
:exec_typ
"Name"
Wenn ich es jedoch über meinen Menüpunkt ausführe, bekomme ich Folgendes:
exec_typ
"Name"
Beachten Sie das Fehlen des Doppelpunkts.(Was auch immer der Doppelpunkt tut, ich weiß es nicht.)
Letztendlich stürzt das Skript ab, denn wenn ich versuche, die Get Property-Funktion für die Spalte mit dem Namen exec_typ auszuführen, erkennt JMP sie nicht als Spaltennamen oder ähnliches:
Send erwartet skriptfähiges Objekt{7} beim Zugriff oder Auswertung von 'Send' , colNames[colInd] << /*###*/Get Property( "Spec limits" ) /*###*/
Irgendeine Ahnung, was zum Teufel los ist?Warum verhält sich die Funktion „Spaltennamen abrufen“ anders, wenn sie vom Skripteditor aus aufgerufen wird, und nicht über eine Menüverknüpfung?
Code unten.Ja, manches ist chaotisch.
//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;
);
Betreff: Skript funktioniert im Skripteditor, aber nicht im Menüelement (Get Column Names verhält sich nicht gleich)1. Damit Code als JSL angezeigt wird, müssen Sie das -Tool oben im Eingabefenster verwenden, um Ihren Text einzugeben.
2. Der Hauptgrund, warum ich glaube, dass mein Code schneller funktioniert als Ihre Methode, basiert auf 2 Elementen.
a. Ja, Formeln sind optimiert.
b. Die Verwendung von dt << Select Where in Verbindung mit der Möglichkeit, allen ausgewählten Zeilen gleichzeitig zuzuweisen, ist extrem schnell.Das Durchlaufen einer Datentabelle mit allen "IF"-Anweisungen Ihres Codes ist sehr langsam.
3. In Bezug auf Ihre Zeichenspezifikations-Grenzwerte.Wie weisen Sie die Spezifikationsgrenzen zu?Die Spalteneigenschaft Spezifikationsgrenzen sollte nur numerische Werte zulassen.Wenn Sie mit Zeichenfunktionen wie Substr() auf die Liste der Spezifikationsgrenzen zugreifen, erhalten Sie Zeichenketten zurück.Schauen Sie im Scripting Guide nach, wie man JSL-Listen manipuliert
Betreff: Skript funktioniert im Skripteditor, aber nicht im Menüelement (Get Column Names verhält sich nicht gleich)Danke für das Skript Jim! Sie haben Recht, ich habe keine Ahnung, wie der Variablenbereich in JMP-Skripten funktioniert, außer dass ich einige Hinweise darauf gesehen habe, dass deklarierte Variablen standardmäßig lokale Variablen sind.
Wie haben Sie Ihr Skript dazu gebracht, in diesen Foren richtig angezeigt zu werden?Wenn ich in diesen Foren Code in das Codefenster einfüge, wird die Formatierung vermasselt und alle Tabulatoren und Leerzeicheneinzüge gelöscht.Gut, dass wir nicht versuchen, Python-Code zu teilen!
Wie auch immer, ich passe mein Skript an, um Elemente von Ihnen zu verwenden, und es funktioniert bereits endlich.Ich habe versucht, Ihr Skript direkt mit dt = aktuelle Datentabelle (); und ein oder zwei weitere Änderungen, aber es hat nicht funktioniert.Ich weiß, dass mein Skript ineffizient ist, aber zum Beispiel sind alle meine Versuche, die USL und LSL in Zahlen umzuwandeln, fehlgeschlagen, also musste ich es einfach in eine Zeichenfolge konvertieren und eine Teilzeichenfolge verwenden.Wenn ich die Anpassung mache, die ich in den Kommentaren vermerke, um alle Spezifikationsgrenzen nur einmal zu extrahieren, spielt das jedoch keine Rolle.Es ist sogar nützlich, auch ein Beispiel für eine offene Datei zu sehen, denn was ich wirklich gerne tun würde, ist die Option, Testlimits aus anderen Dateien als der, die ich analysiere, abzurufen!
Was für mich seltsam ist, ist Ihre Implikation (weil Sie sagten, Ihr Skript sei schneller), dass das Hinzufügen und Löschen von Spalten effizienter wäre als zwei verschachtelte For-Schleifen.Der Computer muss noch jede einzelne Zelle in Ihrer Datentabelle analysieren.Ist JMP so optimiert, dass das Festlegen und Ausführen von Formeln effizienter ist?Ich kann Ihren Ansatz nicht dazu bringen, tatsächlich zu arbeiten, um herauszufinden, vielleicht sollte ich versuchen, was der Follow-up-Poser vorschlägt.
Übrigens haben meine Datentabellen ungefähr 600 Spalten und können Zehntausende von Zeilen enthalten, sodass möglicherweise Überlegungen zur Ausführungseffizienz angestellt werden müssen.
Wie auch immer, die minimale Änderung, die ich vornehmen musste, damit mein Skript funktioniert, war das Ersetzen aller
colNames[colInd]
mit
Spalte( dt, Spaltennamen[Spalte] ) .
Auch wenn ich es mit meinen Datendateien nicht zum Laufen bekomme, werde ich versuchen, einige weitere Elemente aus Ihrem Skript anzupassen.
Betreff: Skript funktioniert im Skripteditor, aber nicht im Menüelement (Get Column Names verhält sich nicht gleich)Jim,
Gut gemacht.musste ich hinzufügen
dt << Run Formulas;
nach Eval(Parse(theExpr)) und vor der delete formula-Anweisung an zwei Stellen Ihres schön geschriebenen Skripts.
Betreff: Skript funktioniert im Skripteditor, aber nicht im Menüelement (Get Column Names verhält sich nicht gleich)Ich gehe davon aus, dass Sie, da Sie Ihre Variablen nicht speziell festlegen (:), auf Probleme stoßen, wenn Sie versuchen, in den beiden verschiedenen Umgebungen zu laufen.Der andere Punkt, den ich beobachtet habe, ist, dass Ihre Methode zu einem sehr langsamen Code führen wird.Angesichts dessen habe ich Ihr Skript neu geschrieben und einige Methoden verwendet, von denen ich glaube, dass sie in beiden Umgebungen funktionieren und auch viel schneller ausgeführt werden.Das folgende Skript wird mit der Semiconductor Capability-Datentabelle ausgeführt, die mit JMP verteilt wird.Aber wenn Sie einfach den Verweis auf das Öffnen dieser Tabelle zusammen mit der Anweisung nach dem Öffnen der Datentabelle entfernen und sie durch Ihre ersetzen
dt = aktuelle Datentabelle ();
Der Code sollte mit Ihren Daten funktionieren.
Ich habe den Code unten kommentiert, also denke ich, dass Sie ihm folgen können sollten.Außerdem EMPFEHLE ICH SEHR DRINGEND, dass Sie den Scripting Guide lesen, der mit Ihrer Installation von JMP mitgeliefert wird.
Hilfe==>Bücher==>Scripting Guide
Es wird Ihnen alles darüber erzählen, worum es bei diesen verrückten Doppelpunkten geht
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)));