Das Skript funktioniert im Skripteditor, aber nicht im Menüelement (Spaltennamen abrufen verhält sich nicht gleich).Wenn ich das folgende Skript im Skripteditor ausführe, funktioniert es einwandfrei.Aber wenn ich es über einen benutzerdefinierten Menüpunkt ausführe, den ich unter „Ansicht->Anpassen“ erstellt habe, funktioniert es nicht.Ich habe es darauf zurückgeführt, dass sich die Funktion „Spaltennamen abrufen“ nicht gleich verhält.Wenn ich eine print-Anweisung einfüge, um den Wert jedes Spaltennamens und seines Typs auszugeben, bevor ich Get Property darauf verwende, sehe ich Folgendes (zum Beispiel), wenn ich es im Skripteditor ausführe:
:exec_typ
"Name"
Wenn ich es jedoch über meinen Menüpunkt ausführe, erhalte ich Folgendes:
exec_typ
"Name"
Beachten Sie das Fehlen des Dickdarms.(Was auch immer der Doppelpunkt macht, ich weiß es nicht.)
Letztendlich stürzt das Skript ab, weil JMP sie nicht als Spaltennamen oder ähnliches erkennt, wenn ich versuche, die Funktion „Eigenschaft abrufen“ für die Spalte „exec_typ“ auszuführen:
Send erwartet ein skriptfähiges Objekt{7} beim Zugriff oder bei der Auswertung von 'Send', colNames[colInd] << /*###*/Get Property( "Spec limits" ) /*###*/
Irgendeine Idee, was zum Teufel los ist?Warum verhält sich die Funktion „Spaltennamen abrufen“ anders, wenn sie über den Skripteditor aufgerufen wird, als über eine Menüverknüpfung?
Code unten.Ja, einiges davon 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 (Spaltennamen abrufen verhält sich nicht gleich)1. Damit Code als JSL angezeigt wird, müssen Sie das -Tool oben im Eingabefenster zum Eingeben Ihres Textes verwenden.
2. Der Hauptgrund dafür, dass ich glaube, dass mein Code schneller funktioniert als Ihre Methode, basiert auf zwei Punkten.
A. Ja, Formeln sind optimiert.
B. Die Verwendung des dt << Select Where in Verbindung mit der Möglichkeit, alle ausgewählten Zeilen gleichzeitig zuzuweisen, ist extrem schnell.Das Durchlaufen einer Datentabelle mit allen „IF“-Anweisungen Ihres Codes ist sehr langsam.
3. Bezüglich der Grenzwerte Ihrer Charakterspezifikationen.Wie weisen Sie die Spezifikationsgrenzen zu?Die Spalteneigenschaft „Spezifikationsgrenzen“ sollte nur numerische Werte zulassen.Wenn Sie über Zeichenfunktionen wie Substr() auf die Liste der Spezifikationsgrenzen zugreifen, erhalten Sie Zeichenketten zurück.Sehen Sie sich im Scripting Guide an, wie Sie JSL-Listen bearbeiten
Betreff: Skript funktioniert im Skripteditor, aber nicht im Menüelement (Spaltennamen abrufen verhält sich nicht gleich)Danke für das Drehbuch, Jim! Sie haben Recht, ich habe keine Ahnung, wie der Variablenbereich in JMP-Skripten funktioniert, außer dass ich Hinweise darauf gesehen habe, dass deklarierte Variablen standardmäßig lokale Variablen sind.
Wie haben Sie dafür gesorgt, dass Ihr Skript in diesen Foren korrekt angezeigt wird?Wenn ich in diesen Foren Code in das Codefenster einfüge, verfälscht es die Formatierung und löscht alle Tabulatoren und Leerzeicheneinrückungen.Gut, dass wir nicht versuchen, Python-Code zu teilen!
Wie auch immer, ich passe mein Skript an, um Elemente von Ihrem zu verwenden, und endlich funktioniert es bereits.Ich habe versucht, Ihr Skript direkt mit dt= current data table(); und noch ein oder zwei Änderungen, aber es hat nicht funktioniert.Ich weiß, dass mein Skript ineffizient ist, aber zum Beispiel schlugen alle meine Versuche, die USL und LSL in Zahlen umzuwandeln, fehl, also musste ich es einfach in einen String umwandeln und einen Teilstring verwenden.Wenn ich die in den Kommentaren notierte Anpassung vornehme, um alle Spezifikationsgrenzen nur einmal zu extrahieren, spielt das allerdings keine große Rolle.Es ist sogar nützlich, auch ein Beispiel für eine geöffnete Datei zu sehen, denn was ich wirklich gerne tun würde, ist die Möglichkeit, Testgrenzen aus anderen Dateien als der, die ich analysiere, abzurufen!
Was mich seltsam macht, ist Ihre Schlussfolgerung (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 immer noch jede einzelne Zelle in Ihrer Datentabelle analysieren.Ist JMP so optimiert, dass das Festlegen und Ausführen von Formeln effizienter ist?Ich verstehe Ihren Ansatz nicht wirklich und versuche es herauszufinden. Vielleicht sollte ich versuchen, was der nachfolgende Poser vorschlägt.
Übrigens haben meine Datentabellen etwa 600 Spalten und können Zehntausende Zeilen enthalten, daher muss dies möglicherweise in Überlegungen zur Ausführungseffizienz einbezogen werden.
Wie auch immer, die minimale Änderung, die ich vornehmen musste, damit mein Skript funktionierte, war, alles zu ersetzen
colNames[colInd]
mit
Column( dt, colNames[colInd] ) .
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 (Spaltennamen abrufen verhält sich nicht gleich)Jim,
Gut gemacht.Ich musste hinzufügen
dt << Run Formulas;
nach Eval(Parse(theExpr)) und vor der Anweisung zum Löschen der Formel, an zwei Stellen Ihres gut geschriebenen Skripts.
Betreff: Skript funktioniert im Skripteditor, aber nicht im Menüelement (Spaltennamen abrufen verhält sich nicht gleich)Ich gehe davon aus, dass Sie beim Versuch, in den beiden verschiedenen Umgebungen auszuführen, auf Probleme stoßen, da Sie Ihre Variablen nicht speziell festlegen (:).Der andere Punkt, den ich beobachtet habe, ist, dass Ihre Methode zu einem sehr langsamen Code führen wird.Vor diesem Hintergrund habe ich Ihr Skript umgeschrieben und dabei einige Methoden verwendet, von denen ich glaube, dass sie in beiden Umgebungen funktionieren und auch viel schneller laufen.Das folgende Skript wird für die Datentabelle „Semiconductor Capability“ ausgeführt, die mit JMP verteilt wird.Aber wenn Sie einfach den Verweis auf das Öffnen dieser Tabelle sowie die Anweisung nach dem Öffnen der Datentabelle entfernen und durch Ihre ersetzen
dt = aktuelle Datentabelle();
Der Code sollte mit Ihren Daten funktionieren.
Ich habe den Code unten mit Anmerkungen versehen, daher denke ich, dass Sie ihm folgen können.Außerdem empfehle ich Ihnen dringend, den Skriptleitfaden zu lesen, der mit Ihrer JMP-Installation geliefert wird.
Hilfe==>Bücher==>Skripthandbuch
Hier erfahren Sie alles darüber, 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)));