Aidez-moi, mon script s'exécute correctement dans une fenêtre de script mais échoue lorsqu'il est exécuté dans une formule de colonneBonjour,
J'ai créé un script pour résumer un tableau de données en analysant l'impact statistique individuel de M facteurs sur N métriques.
Le tableau récapitulatif montre la matrice de N métriques (lignes) avec M facteurs (colonnes), avec l'impact spécifique : décalage moyen, dégradation du Cpk ou les deux)
Je souhaite ajouter une fonctionnalité pour tracer la distribution pour chaque ligne sélectionnée avec une formule de colonne.
J'ai été inspiré par ce post :
Lier une cellule (dans une table JMP) à un script ?
Le problème est que mon script fonctionne bien dans une nouvelle fenêtre de script avec une ligne sélectionnée fixe ([5] dans cet exemple), mais échoue ensuite lorsque j'inclus le script dans la formule de colonne :Graph. Je ne comprends pas pourquoi…
Pourriez-vous s'il vous plaît m'aider à déboguer cela ?
Ci-joint 2 tableaux : datatable_test.jmp avec les données brutes, Summary.jmp avec la formule de la colonne. L'idée est de cliquer sur la cellule que vous souhaitez tracer dans la colonne :Graph.
Actuellement, l'erreur indique : « Référence illégale (récursivité) à la ligne [ ] »

Lorsque j'exécute le script suivant avec les deux tables ouvertes, il fonctionne comme prévu (voir ci-dessous). Mais le script échoue lorsqu'il est exécuté directement à partir de la table (clic sur la cellule dans la colonne Graphique).

Merci beaucoup d'avance,
- Prédicateur
// 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 )}
)
)
) "
);
)
//)
);Automatisation et scriptsRe : Aide, mon script s'exécute correctement dans une fenêtre de script mais échoue lorsqu'il est exécuté dans une formule de colonneY a-t-il une raison spécifique de faire cela avec une formule de colonne ? Par exemple, avoir une fenêtre personnalisée avec une zone de tableau et un ou plusieurs boutons serait beaucoup plus facile à créer et à gérer. Ou peut-être utiliser un gestionnaire d'état de ligne sur le tableau récapitulatif (même si j'éviterais cela si possible).
Re : Aide, mon script s'exécute correctement dans une fenêtre de script mais échoue lorsqu'il est exécuté dans une formule de colonneSalut Jarmo,
Aucune raison particulière, j'ai juste créé mon script original de cette façon, en utilisant une table de données pour générer le résumé.
Je n'y avais pas pensé : ouvrir une boîte de table et ajouter des boutons semble une bonne idée, je pourrais modifier ma future version dans cet esprit.
Mais en attendant, pensez-vous que faire fonctionner la formule de colonne en vaut la peine ? Ainsi, je pourrai avoir une version fonctionnelle plus rapidement avant la prochaine version ? J'ai peur que changer la structure pour générer une boîte de tableau au lieu d'une table de données me prenne un certain temps, car je ne suis pas encore très familier avec l'affichage/la boîte de tableau.
Le morceau de script que je souhaite inclure dans la formule de colonne fonctionne tout seul, mais échoue lorsqu'il est exécuté dans la formule de colonne. Je dois faire quelque chose de mal mais je ne sais pas quoi...
Re : Aide, mon script s'exécute correctement dans une fenêtre de script mais échoue lorsqu'il est exécuté dans une formule de colonneModifier:
En fait, j'ai découvert que convertir une table en boîte d'affichage était facile :
nw = New Window("Report",
dt << Get As Report()
);Rapport généré ci-dessous

Je ne m'attendais pas à ce que la formule fonctionne dans le rapport, lorsque l'on clique sur la ligne (et ce n'est pas le cas...).
Mais maintenant, je ne suis pas sûr de la manière dont vous proposeriez de procéder avec votre suggestion.
(encore une fois, je ne suis pas encore familier avec la manipulation de la boîte d'affichage)
Merci d'avance
Re : Aide, mon script s'exécute correctement dans une fenêtre de script mais échoue lorsqu'il est exécuté dans une formule de colonneÉdition 2:
J'ai finalement réussi à faire fonctionner le script, en suivant la recommandation de Jarmo et ce post :
Aide JSL avec : Obtenir un rapport et une boîte de tableau
Maintenant, lorsque je clique sur une ligne du rapport, il exécute le script en fonction de la ligne sélectionnée, ce qui est exactement ce dont j'avais besoin:)

Script ci-dessous, il faut que les 2 tables que j'ai rejointes dans mon premier message soient ouvertes
Merci
- le prédicateur
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 )}
)
)
) "
)))
)
));Re : Aide, mon script s'exécute correctement dans une fenêtre de script mais échoue lorsqu'il est exécuté dans une formule de colonneUne autre amélioration que j'aimerais essayer de faire est de me débarrasser de Eval(Parse()) (cela rend généralement le script plus facile à déboguer et vous n'apprenez pas de mauvaises habitudes). Mais cela demandera des efforts et des techniques différentes, vous pourrez donc y travailler lentement.
Je peux également y jeter un œil dans environ 12 heures afin que vous puissiez avoir une idée de ce que vous pourriez potentiellement faire.
Re : Aide, mon script s'exécute correctement dans une fenêtre de script mais échoue lorsqu'il est exécuté dans une formule de colonneJe suis d'accord. J'irais encore plus loin et remplacerais également Eval Insert() .
Concernant Eval(Parse()) - vous pouvez simplement l'ignorer :

Parse attend une chaîne comme argument.
Une expression sera évaluée et la chaîne résultante sera analysée et renvoyée sous forme d'expression.
Parse(Print(1);"a"||"b")
Donc,
Parse(Print(1);Eval Insert(Graph Builder());"a")
imprimera 1, créera le graphique et renverra a comme expression. Si vous êtes uniquement intéressé par la partie centrale, vous pouvez ignorer l' analyse .
L'encapsulation de Parse(Eval Insert()) avec Eval() l'évaluera toujours.
D'autre part, Eval(Eval Expr()) est juste nécessaire pour évaluer un Expr() qui est à l'intérieur.
Sans Expr() , vous pouvez le supprimer du code sans dommage.
En général, je proposerais de publier un code basé sur un ensemble de données du dossier Aide/Exemple de données.
Le code peut alors être exécuté immédiatement sans avoir besoin de télécharger des fichiers via Internet.
L’avantage supplémentaire : adapter le code à différentes entrées aide souvent à comprendre le problème.
Souvent, lorsque j'ai le bon code pour poster la question, la question disparaît : )

Re : Aide, mon script s'exécute correctement dans une fenêtre de script mais échoue lorsqu'il est exécuté dans une formule de colonneCela semble compliqué (et ça l'est), mais c'est probablement ainsi que j'aborderais cela (ce n'est pas la seule façon, vous pouvez également utiliser << ajouter des variables/<< ajouter des éléments)
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();
Une fois que cela fonctionne, je commencerais peut-être à réfléchir à l'expérience utilisateur :
- Peut-être devrais-je utiliser un bouton qui créerait des rapports pour les lignes sélectionnées lorsqu'il est enfoncé ?
- Puis-je laisser l’utilisateur sélectionner plus d’une ligne ?
- Dois-je créer tous les rapports dans la même fenêtre dans ce cas ?
- Si le graphique a déjà été créé, dois-je le recréer ?
- Lorsque l'utilisateur ferme la fenêtre, dois-je également fermer les tables de données ?
- ..
Voir plus...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


Re : Aide, mon script s'exécute correctement dans une fenêtre de script mais échoue lorsqu'il est exécuté dans une formule de colonneMerci beaucoup Jarmo et Hogi.
Je réponds très tard, désolé pour mon silence, j'ai dû me concentrer sur d'autres priorités ces derniers mois mais maintenant je peux m'y remettre !
Je vais réfléchir à cela et essayer vos suggestions.
Meilleur,
-Prédicateur