Hilfe, mein Skript läuft in einem Skriptfenster einwandfrei, schlägt aber fehl, wenn es in einer Spaltenformel ausgeführt wirdHallo,
Ich habe ein Skript erstellt, um eine Datentabelle zusammenzufassen, indem ich die einzelnen statistischen Auswirkungen von M Faktoren auf N Metriken analysiert habe.
Die Übersichtstabelle zeigt die Matrix aus N Kennzahlen (Zeilen) und M Faktoren (Spalten) mit den spezifischen Auswirkungen: Mittelwertverschiebung, Cpk-Verschlechterung oder beides.
Ich möchte eine Funktion hinzufügen, um die Verteilung für jede ausgewählte Zeile mit einer Spaltenformel darzustellen.
Inspiriert hat mich dieser Beitrag:
Eine Zelle (in einer JMP-Tabelle) mit einem Skript verknüpfen?
Das Problem ist, dass mein Skript in einem neuen Skriptfenster mit einer fest ausgewählten Zeile ([5] in diesem Beispiel) gut funktioniert, dann aber fehlschlägt, wenn ich das Skript in die Formel für die Spalte :Graph einbinde. Ich verstehe nicht, warum …
Können Sie mir bitte beim Debuggen helfen?
Anbei 2 Tabellen: datatable_test.jmp mit den Rohdaten, Summary.jmp mit der Spaltenformel. Die Idee besteht darin, auf die Zelle zu klicken, die Sie in der Spalte :Graph darstellen möchten.
Derzeit wird der Fehler angezeigt: „Unzulässige Referenz (Rekursion) in Zeile [ ]“

Wenn ich das folgende Skript ausführe und beide Tabellen geöffnet habe, funktioniert es wie erwartet (siehe unten). Das Skript schlägt jedoch fehl, wenn es direkt aus der Tabelle ausgeführt wird (klicken Sie auf die Zelle in der Spalte „Graph“).

Vielen Dank im Voraus,
- Prediger
// this script works from a Script window
// All features related to the column formula are commented
// here the row selected is row 5 : rn1 = [5]
Names Default To Here( 1 );
dt = Data Table( "datatable_test" );
dt2 = Data Table( "Summary" );
//If( Selected( Row State() ),
Eval(
Parse(
rn1 = [5]/*dt2 << get selected rows*/;
rn = rn1[1];
Factors = dt2 << get column names( "string" );
show(rn1, rn);
Eval(
Eval Expr(
For( i = N Items( Factors ), i >= 1, i--,
CurrCol = Column( dt2, Factors[i] );
If(Char( CurrCol[ rn ] ) == "Ok" | Factors[i] == "Metric"| Factors[i] == "Graph",
Remove From( Factors, i, 1 )
);
)
)
);
FactorA = "X( :" || Char( Factors[1] ) || ", Position( 1 ))";
FactorB = "X(1)";
For( j = 2, j <= N Items( Factors ), j++,
FactorA = Char( FactorA ) || ",X( :" || Char( Factors[j] ) ||
", Position( 1 ))";
FactorB = Char( FactorB ) || ",X( " || Char( j ) || " ) ";
);
Show( dt2:Metric[rn], FactorA, FactorB );
Key = dt2:Metric[rn];
Eval Insert(
" dt << Graph Builder(
Size( 534, 464 ),
Show Control Panel( 0 ),
Show Legend( 0 ),
Variables(
Y( ^Key^ ), ^FactorA^),
Elements( Box Plot( Y, Legend( 18 ), ^FactorB^ ) ),
SendToReport(
Dispatch(
{},
ScaleBox,
{Min( -0.485125992718803 ), Max( 5.53364268893602 ), Inc( 1 ),
Minor Ticks( 0 )}
)
)
) "
);
)
//)
);Automatisierung und SkriptingBetreff: Hilfe, mein Skript läuft in einem Skriptfenster einwandfrei, schlägt aber fehl, wenn es in einer Spaltenformel ausgeführt wirdGibt es einen bestimmten Grund, dies mit einer Spaltenformel zu tun? Beispielsweise wäre es viel einfacher, ein benutzerdefiniertes Fenster mit Tabellenfeld und Schaltfläche(n) zu erstellen und zu verwalten. Oder vielleicht die Verwendung eines Zeilenstatushandlers für die Übersichtstabelle (obwohl ich das nach Möglichkeit vermeiden würde).
Betreff: Hilfe, mein Skript läuft in einem Skriptfenster einwandfrei, schlägt aber fehl, wenn es in einer Spaltenformel ausgeführt wirdHallo Jarmo,
Es gibt keinen besonderen Grund, ich habe mein Originalskript einfach auf diese Weise erstellt und dabei eine Datentabelle zum Generieren der Zusammenfassung verwendet.
Daran habe ich nicht gedacht: Eine Tabellenbox zu öffnen und Schaltflächen hinzuzufügen scheint eine gute Idee zu sein. Ich könnte meine zukünftige Version in Anbetracht dessen ändern.
Aber glauben Sie, dass es sich in der Zwischenzeit lohnt, die Spaltenformel zum Laufen zu bringen? So kann ich schneller eine funktionierende Version haben, bevor die nächste Version herauskommt? Ich fürchte, die Änderung der Struktur zum Generieren eines Tabellenfelds anstelle einer Datentabelle wird einige Zeit in Anspruch nehmen, da ich mit Anzeige/Tabellenfeld noch nicht sehr vertraut bin.
Das Skriptstück, das ich in die Spaltenformel aufnehmen möchte, funktioniert zwar von selbst, schlägt aber fehl, wenn es in der Spaltenformel ausgeführt wird. Ich muss etwas falsch gemacht haben, bin mir aber nicht sicher, was ...
Betreff: Hilfe, mein Skript läuft in einem Skriptfenster einwandfrei, schlägt aber fehl, wenn es in einer Spaltenformel ausgeführt wirdBearbeiten:
Ich habe festgestellt, dass es eigentlich ganz einfach ist, eine Tabelle in eine Anzeigebox umzuwandeln:
nw = New Window("Report",
dt << Get As Report()
);Unten generierter Bericht

Ich habe nicht erwartet, dass die Formel im Bericht funktioniert, wenn ich auf die Zeile klicke (und das tut sie nicht ...).
Aber jetzt bin ich mir nicht sicher, wie Sie mit Ihrem Vorschlag weiter vorgehen möchten.
(auch hier bin ich mit der Anzeigefeldmanipulation noch nicht vertraut)
Dank im Voraus
Betreff: Hilfe, mein Skript läuft in einem Skriptfenster einwandfrei, schlägt aber fehl, wenn es in einer Spaltenformel ausgeführt wirdBearbeitung 2:
Ich habe das Skript schließlich zum Laufen gebracht, indem ich der Empfehlung von Jarmo und diesem Beitrag gefolgt bin:
JSL-Hilfe zu: „Als Bericht abrufen“ und „Tabellenfeld“
Wenn ich jetzt auf eine Zeile im Bericht klicke, wird das Skript basierend auf der ausgewählten Zeile ausgeführt. Und das ist genau das, was ich brauchte.:)

Das folgende Skript erfordert die Öffnung der beiden Tabellen, die ich in meiner ersten Nachricht hinzugefügt habe
Danke
- der Prediger
Names Default To Here( 1 );
dt7 = Data Table("Summary");
dt = Data Table("datatable_test");
dt7 << clear select;
dt7 << Clear Column Selection();
RptWin = New Window( "Data Table as report",
Outline Box("Data Table as Report",
dt7_Rpt = dt7 << Get as Report();
)
);
tb = dt7_Rpt[Table Box( 1 )];
tb << Set Heading Column Borders( 1 );
tb << Set Selectable Rows( 1 );
tb << Set Row Change Function(
Function( {this},
{SelRows},
SelRows = this << Get Selected Rows;
If(
N Items( SelRows ) > 1, Throw( "Too many items selected!\!rOnly one selection possible." ),
N Items( SelRows ) == 1,
SelRows = this << Get Selected Rows;
);
dt7 << Clear Select;
rn = dt7 << Select rows( SelRows ) << get selected rows;
show (rn[1], dt7:Metric[rn]);
Factors = dt7 << get column names( "string" );
Eval(
Eval Expr(
For( i = N Items( Factors ), i >= 1, i--,
CurrCol = Column( dt7, Factors[i] );
If(Char( CurrCol[ rn[1] ] ) == "Ok" | Factors[i] == "Metric"| Factors[i] == "Graph",
Remove From( Factors, i, 1 )
);
)
)
);
show (Factors);
Try(FactorA = "X( :" || Char( Factors[1] ) || ", Position( 1 ))");
FactorB = "X(1)";
For( j = 2, j <= N Items( Factors ), j++,
Try(FactorA = Char( FactorA ) || ",X( :" || Char( Factors[j] ) || ", Position( 1 ))");
FactorB = Char( FactorB ) || ",X( " || Char( j ) || " ) ";
);
Show( dt7:Metric[rn], FactorA, FactorB );
Key = dt7:Metric[rn];
If (Factors != {},
Eval(Parse(Eval Insert(
" dt << Graph Builder(
Size( 534, 464 ),
Show Control Panel( 0 ),
Show Legend( 0 ),
Variables(Y( ^Key^ ), ^FactorA^),
Elements(
Box Plot( Y, Legend( 18 ), ^FactorB^ ),
Caption Box(X, Y, Legend(20), Summary Statistic( \!"N\!" ),Location( \!"Graph per factor\!" ))),
SendToReport(
Dispatch(
{},
ScaleBox,
{Min( -0.485125992718803 ), Max( 5.53364268893602 ), Inc( 1 ),
Minor Ticks( 0 )}
)
)
) "
))),
Eval(Parse(Eval Insert(
" dt << Graph Builder(
Size( 534, 464 ),
Show Control Panel( 0 ),
Show Legend( 0 ),
Variables(Y( ^Key^ )),
Elements(
Box Plot( Y, Legend( 18 )),
Caption Box(Y, Legend(20), Summary Statistic( \!"N\!" ))),
SendToReport(
Dispatch(
{},
ScaleBox,
{Min( -7.06199976676385 ), Max( 26.8097086791615 ), Inc( 5 ),
Minor Ticks( 0 )}
)
)
) "
)))
)
));Betreff: Hilfe, mein Skript läuft in einem Skriptfenster einwandfrei, schlägt aber fehl, wenn es in einer Spaltenformel ausgeführt wirdEine weitere Verbesserung, die ich versuchen würde, wäre, Eval(Parse()) loszuwerden (das macht das Skript normalerweise einfacher zu debuggen und man gewöhnt sich keine schlechten Angewohnheiten an). Aber das wird einige Mühe und verschiedene Techniken erfordern, also können Sie langsam daran arbeiten.
Ich kann auch in ca. 12 Stunden einen Blick darauf werfen, damit Sie sich ein Bild davon machen können, was Sie möglicherweise tun könnten.
Betreff: Hilfe, mein Skript läuft in einem Skriptfenster einwandfrei, schlägt aber fehl, wenn es in einer Spaltenformel ausgeführt wirdEinverstanden. Ich würde noch einen Schritt weiter gehen und auch Eval Insert() ersetzen.
Was Eval(Parse()) betrifft, können Sie es einfach überspringen:

Parse erwartet einen String als Argument.
Ein Ausdruck wird ausgewertet und der resultierende String wird analysiert und als Ausdruck zurückgegeben.
Parse(Print(1);"a"||"b")
Also,
Parse(Print(1);Eval Insert(Graph Builder());"a")
gibt 1 aus, erstellt das Diagramm und gibt a als Ausdruck zurück. Wenn Sie nur am mittleren Teil interessiert sind, können Sie das Parsen überspringen.
Das Umschließen von Parse(Eval Insert()) mit Eval() führt weiterhin zur Auswertung.
Andererseits wird Eval(Eval Expr()) nur benötigt, um einen darin enthaltenen Expr() auszuwerten.
Ohne Expr() können Sie es problemlos aus dem Code entfernen.
Generell würde ich vorschlagen, einen Code zu posten, der auf einem Datensatz aus dem Ordner „Hilfe/Beispieldaten“ basiert.
Dann kann der Code sofort ausgeführt werden, ohne dass Dateien über das Internet heruntergeladen werden müssen.
Der zusätzliche Vorteil: Die Anpassung des Codes an unterschiedliche Eingaben trägt häufig zum Verständnis des Problems bei.
Wenn ich den richtigen Code zum Posten der Frage habe, ist die Frage oft weg : )

Betreff: Hilfe, mein Skript läuft in einem Skriptfenster einwandfrei, schlägt aber fehl, wenn es in einer Spaltenformel ausgeführt wirdDas sieht kompliziert aus (und das ist es auch), aber so würde ich es wahrscheinlich angehen (das ist nicht die einzige Möglichkeit, Sie können auch << Variablen hinzufügen/<< Elemente hinzufügen) verwenden.
Names Default To Here(1);
dt_summary = Open("$DOWNLOADS/Summary.jmp");
dt = Open("$DOWNLOADS/datatable_test.jmp");
dt << New Column("Ones", Numeric, Nominal, Set Each Value(1));
dt_summary << clear select;
dt_summary << Clear Column Selection();
possible_factors = dt_summary << get column names("string");
Remove From(possible_factors, Contains(possible_factors, "Metric"));
Remove From(possible_factors, Contains(possible_factors, "Graph"));
create_report = function({sel_row}, {Default Local},
valid_factor_idx = Loc(dt_summary[sel_row, possible_factors], "Ok");
valid_factors = possible_factors[valid_factor_idx];
key = dt_summary[sel_row, "Metric"];
If(N Items(valid_factors) == 0,
valid_factors = {"Ones"};
);
variables_expr = Expr(Variables());
bp_expr = Expr(Box Plot(Y, Legend(18)));
dt = dt; // JMP being JMP
For Each({valid_factor, idx}, valid_factors,
x_expr = EvalExpr(X(Expr(Name Expr(AsColumn(dt, valid_factor))), Position(1)));
Insert Into(variables_expr, Name Expr(x_expr));
Insert Into(bp_expr, Eval Expr(X(Expr(idx))));
);
y_expr = EvalExpr(Y(Expr(Name Expr(AsColumn(dt, key)))));
Insert Into(variables_expr, Name Expr(y_expr));
gb_expr = Substitute(
Expr(dt << Graph Builder(
Size(534, 464),
Show Control Panel(0),
Show Legend(0),
_variables_,
Elements(
_boxplot_,
Caption Box(X, Y, Legend(20), Summary Statistic("N"), Location("Graph per factor"))
),
SendToReport(
Dispatch({}, ScaleBox, {Min(-7.06199976676385), Max(26.8097086791615), Inc(5), Minor Ticks(0)})
)
)),
Expr(_variables_), Name Expr(variables_expr),
Expr(_boxplot_), Name Expr(bp_expr)
);
gb = Eval(gb_expr);
return();
);
nw = New Window("Data Table as report",
Outline Box("Data Table as Report",
summary_report = dt_summary << Get as Report();
)
);
report_tb = summary_report[Table Box(1)];
report_tb << Set Heading Column Borders(1);
report_tb << Set Selectable Rows(1);
report_tb << Set Row Change Function(Function({this},
selrows = this << Get Selected Rows;
If(N Items(selrows) > 1,
Throw("Too many items selected!\!rOnly one selection possible.")
);
create_report(selrows[1]);
));
Write();
Wenn das funktioniert, würde ich vielleicht anfangen, über die Benutzererfahrung nachzudenken:
- Vielleicht sollte ich eine Schaltfläche verwenden, die beim Drücken Berichte für ausgewählte Zeilen erstellt?
- Kann ich den Benutzer mehr als eine Zeile auswählen lassen?
- Sollte ich in diesem Fall alle Berichte im selben Fenster erstellen?
- Wenn das Diagramm bereits erstellt wurde, muss ich es neu erstellen?
- Wenn der Benutzer das Fenster schließt, soll ich auch die Datentabellen schließen?
- ..
Mehr anzeigen...Names Default To Here(1);
dt_summary = Open("$DOWNLOADS/Summary.jmp");
dt = Open("$DOWNLOADS/datatable_test.jmp");
dt << New Column("Ones", Numeric, Nominal, Set Each Value(1));
dt_summary << clear select;
dt_summary << Clear Column Selection();
possible_factors = dt_summary << get column names("string");
Remove From(possible_factors, Contains(possible_factors, "Metric"));
Remove From(possible_factors, Contains(possible_factors, "Graph"));
create_report = function({sel_row}, {Default Local},
valid_factor_idx = Loc(dt_summary[sel_row, possible_factors], "Ok");
valid_factors = possible_factors[valid_factor_idx];
key = dt_summary[sel_row, "Metric"];
If(N Items(valid_factors) == 0,
valid_factors = {"Ones"};
);
variables_expr = Expr(Variables());
bp_expr = Expr(Box Plot(Y, Legend(18)));
dt = dt; // JMP being JMP
For Each({valid_factor, idx}, valid_factors,
x_expr = EvalExpr(X(Expr(Name Expr(AsColumn(dt, valid_factor))), Position(1)));
Insert Into(variables_expr, Name Expr(x_expr));
Insert Into(bp_expr, Eval Expr(X(Expr(idx))));
);
y_expr = EvalExpr(Y(Expr(Name Expr(AsColumn(dt, key)))));
Insert Into(variables_expr, Name Expr(y_expr));
gb_expr = Substitute(
Expr(dt << Graph Builder(
Size(534, 464),
Show Control Panel(0),
Show Legend(0),
_variables_,
Elements(
_boxplot_,
Caption Box(X, Y, Legend(20), Summary Statistic("N"), Location("Graph per factor"))
),
SendToReport(
Dispatch({}, ScaleBox, {Min(-7.06199976676385), Max(26.8097086791615), Inc(5), Minor Ticks(0)})
)
)),
Expr(_variables_), Name Expr(variables_expr),
Expr(_boxplot_), Name Expr(bp_expr)
);
return(gb_expr);
);
nw = New Window("Data Table as report",
H List Box(
Outline Box("Data Table as Report",
summary_report = dt_summary << Get as Report();
),
Outline Box("Actions",
Button Box("Create Reports",
sel_rows = report_tb << Get Selected Rows;
lub_collector = Lineup Box(N Col(2));
For Each({selrow}, sel_rows,
lub_collector << Append(create_report(selrow));
);
nw_graphs = New Window("Graphs",
lub_collector
);
wait(0);
),
Button Box("Close Window", summary_report << close window);
)
)
);
report_tb = summary_report[Table Box(1)];
report_tb << Set Heading Column Borders(1);
report_tb << Set Selectable Rows(1);
I will edit and add images here if JMP Community ever lets me do it...
Edit: Images


Betreff: Hilfe, mein Skript läuft in einem Skriptfenster einwandfrei, schlägt aber fehl, wenn es in einer Spaltenformel ausgeführt wirdVielen Dank, Jarmo und Hogi.
Ich antworte sehr spät. Entschuldigen Sie mein Schweigen. Ich musste mich in den letzten Monaten auf andere Prioritäten konzentrieren, aber jetzt kann ich mich wieder darauf konzentrieren!
Ich werde darüber nachdenken und Ihre Vorschläge ausprobieren.
Am besten,
-Prediger