[JMP Pro 14.1.0, OS W7 64-Bit]
Verehrte Gäste,
Ich arbeite an der Automatisierung einer Datentabelle für einige Kunden. Die Datentabelle enthält eine Datumsspalte und mehrere Produkteigenschaftenspalten, alle mit Spezifikationsgrenzen.
Ich versuche unter anderem, der Datentabelle neue Skripte hinzuzufügen, damit der Kunde einfach auf den grünen Hot-Button in der Datentabelle klicken und das Kontrolldiagramm für die Immobilie abrufen kann, an der er interessiert ist.
Ich habe eine Liste namens „SpecList“, die alle Spaltennamen in der Datentabelle enthält, und ich habe eine Spezifikationsdatentabelle mit den üblichen Spaltennamen _LSL, _USL und _Target, die für das Tool „Spezifikationsgrenzen verwalten“ für die Qualität benötigt werden und Prozesskontrolle.
Ich möchte die neuen Skripte mit einer For-Schleife innerhalb der Funktion „Neues Skript“ generieren – das ist zumindest das Konzept. Ein Beispiel dafür, was ich an die Tabelle senden möchte, ist unten, wobei ich möchte, dass [1] schließlich ein [i] in einer For-Schleife ist:
dtperf << New Script(
"Control Chart " || SpecList[1],
Control Chart Builder(
Size( 534, 454 ),
Show Control Panel( 0 ),
Variables( Subgroup( :Date ), Y( Column(dtperf, SpecList[1]) ) ),
Chart( Position( 1 ), Limits ),
Chart( Position( 2 ), Limits ),
SendToReport(
Dispatch(
{},
SpecList[1],
ScaleBox,
{Add Ref Line( dtspecs:Name( "_LSL" )[1], "Solid", "Blue", "LSL", 1 ), Add Ref Line(
dtspecs:Name( "_USL" )[1],
"Solid",
"Blue",
"USL",
1
), Add Ref Line( dtspecs:Name( "_Target" )[1], "Solid", "Blue", "USL", 1 )}
)
)
)
);Teile davon funktionieren wie ich es mir vorstelle, andere nicht. Der Name des neuen Skripts funktioniert wie erwartet. Ich habe Probleme, insbesondere mit dem Versandteil. Nach „Dispatch( {} , SpecList[1],....“ und mit den Abschnitten „Add Ref Line()“.
Der Dispatch SpecList[1] sendet buchstäblich SpecList[1], anstatt den Text aus der Liste einzufügen. Anschließend wird im Abschnitt „Referenzzeile hinzufügen“ auch buchstäblich dtspecs:Name("_LSL")[1] anstelle des Werts aus der Datentabelle gesendet. Das Skript, das in der Datentabelle gespeichert wird, ist unten:
Control Chart Builder(
Size( 534, 454 ),
Show Control Panel( 0 ),
Variables( Subgroup( :Date ), Y( Column(dtperf, SpecList[1]) ) ),
Chart( Position( 1 ), Limits ),
Chart( Position( 2 ), Limits ),
SendToReport(
Dispatch(
{},
SpecList[1],
ScaleBox,
{Add Ref Line( dtspecs:_LSL[1], "Solid", "Blue", "LSL", 1 ),
Add Ref Line( dtspecs:_USL[1], "Solid", "Blue", "USL", 1 ),
Add Ref Line( dtspecs:_Target[1], "Solid", "Blue", "USL", 1 )}
)
)
)Ich habe versucht, Char(), Num(), Try() und Eval() um die Abschnitte des relevanten Codes zu wickeln, um zu sehen, ob es funktionieren würde, aber das funktioniert nicht.
Außerdem funktioniert die Y-Spalte in den Variablen nicht. Es sendet erneut genau das, was geschrieben steht, und nicht die Referenz, auf die es verweist. Wenn ich jedoch die Control Chart Builder-Funktion in meinem ursprünglichen Skript oben (erstes Skript) hervorhebe, funktioniert sie einwandfrei.
Ich hätte gerne eine Möglichkeit, dieses Problem so zu lösen, dass die tatsächlichen Werte, auf die verwiesen wird, an das neue Skript anstelle des wörtlichen JSL-Skripts gesendet werden. Der Grund dafür ist, dass ich versuche, das Skript so allgemein wie möglich zu schreiben, damit es auf andere Produkte angewendet werden kann und das eine nicht zu tief in das Skript eintauchen muss, um es zu ändern/aktualisieren, um es für das andere einzuführen Produkte.
Ich denke, ein Teil des Problems besteht darin, dass meine Variablennamen alle in meinem primären Skript vorhanden sind (ich habe die Namen standardmäßig auf hier(1) gesetzt) und wenn es ein neues Skript an die Datentabelle sendet, weiß es nicht, wie es a auswerten soll Verweis auf eine Variable, die nicht definiert ist. Möglicherweise muss ich diese Variablen an das Skript senden, das in die Datentabelle geschrieben wird, bin mir aber nicht sicher, wie. Ich würde es auch vorziehen, keine globale Variable zu generieren.
Danke!,
DS
Hallo @nathan-clark Und @ian_jmp ,
Ich freue mich sehr über Ihr Feedback und Ihre Ideen. Einige der verwendeten Dinge übersteigen momentan mein Niveau und ich konnte nicht ganz herausfinden, wie ich sie umsetzen soll.
Andererseits habe ich aufgrund Ihres Feedbacks meinen Code geändert und ihn so zum Laufen gebracht, dass er für mich Sinn macht. Es ist vielleicht nicht sehr elegant, aber es funktioniert und macht genau das, was ich mir vorgenommen habe.
Als mir klar wurde, dass die For-Schleife außerhalb von allem sein musste, funktionierte es großartig. Es macht jetzt Sinn, dass ich die CharList[i] in einen Ausdruck umwandeln muss, der dann über einen EvalExpr ausgeführt werden muss, der dann alles ausgewertet werden muss, um das neue Skript mit den gewünschten Eingaben an die Datentabelle zu senden .
Unten ist mein Code, wie ich es zum Laufen gebracht habe.
Danke für die Hilfe!
DS
For( i = 1, i <= N Items( ChartList ), i++,
Eval(
Eval Expr(
dtperf << New Script(
"Control Chart " || Expr( ChartList[i] ),
Control Chart Builder(
Size( 534, 454 ),
Show Control Panel( 0 ),
Variables( Subgroup( :Date ), Y( Expr( Column( dtperf, ChartList[i] ) ) ) ),
Chart( Position( 1 ), Limits ),
Chart( Position( 2 ), Limits ),
SendToReport(
Dispatch(
{},
Expr( ChartList[i] ),
ScaleBox,
{Add Ref Line( Expr( dtspecs:Name( "_LSL" )[i] ), "Solid", "Blue", "LSL", 1 ),
Add Ref Line( Expr( dtspecs:Name( "_USL" )[i] ), "Solid", "Blue", "USL", 1 ), Add Ref Line(
Expr(
dtspecs:Name( "_Target" )[i]
),
"Solid",
"Blue",
"USL",
1
)}
)
)
)
)
)
)
);FWIW und wahrscheinlich persönliche Präferenz, aber ich neige dazu, „SubstituteInto()“ für solche Dinge zu verwenden:
NamesDefaultToHere(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
// Template script for Control Chart Builder
myCCB =
Expr(
Control Chart Builder(
Size( 529, 453 ),
Show Control Panel( 0 ),
Show Capability( 0 ),
Variables( Y( YTBD ) ),
Chart( Position( 1 ), Limits( Sigma( "Moving Range" ) ) ),
Chart( Position( 2 ), Limits( Sigma( "Moving Range" ) ) ),
SendToReport(
Dispatch(
{},
yNameTBD,
ScaleBox,
{Add Ref Line( HLineTBD, "Dashed", "Green", "", 1 )}
)
)
)
);
// Update the template script
SubstituteInto(myCCB,
Expr(yTBD), Column(dt, "height"),
Expr(yNameTBD), "height",
Expr(HLineTBD), 55
);
// Save the script in the table
CMD = Expr(dt << newScript("My Control Chart Builder", scriptTBD));
SubstituteInto(CMD,
Expr(scriptTBD), NameExpr(myCCB)
);
CMD;
Der beste Weg, den ich dafür gefunden habe, ist die Verwendung von Eval() und EvalExpr() ... im Grunde sind die Variablen im Skript Ausdrücke und eval expression wertet sie aus, sodass die endgültige Auswertung Ihres Tabellenskripts die tatsächlichen Werte hat, nicht die Variablen. Unten ist ein kurzes Beispiel, das ich mir geholt habe, wo ich ein Tabellenskript erstellt habe und es die spezifischen Spaltennamen im Gegensatz zur Variablen (parseUnique) einfügt. parseUnique wird erstellt, indem eine Textzeichenfolge für den Spaltennamen in die Funktion :Name() eingefügt wird, damit Spaltennamen besser funktionieren.
Ich muss mir keine Gedanken über Variablen machen, die ich innerhalb des Ausdrucks (tblName) erstelle, aber alle Variablen, die aus externen Quellen stammen, werden in der Funktion zu Ausdrücken.
parseUnique = EvalInsert(":Name(\!"^uniqueCol^\!")");Eval(
EvalExpr(
dt_algorithm << New Script("Make justResults",
tblName = currentdatatable()<<GETNAME></GETNAME>