[JMP Pro 14.1.0, système d'exploitation W7 64 bits]
Chers tous,
Je travaille sur l'automatisation d'un tableau de données pour certains clients. Le tableau de données contient une colonne de date et plusieurs colonnes de propriétés de produit, toutes avec des limites de spécifications.
L'une des choses que j'essaie de faire est d'ajouter de nouveaux scripts à la table de données afin que le client puisse facilement cliquer sur le bouton vert de la table de données et obtenir la carte de contrôle pour la propriété qui l'intéresse.
J'ai une liste appelée "SpecList" qui contient tous les noms de colonnes dans la table de données, et j'ai une table de données de spécifications avec les noms de colonnes habituels _LSL, _USL et _Target qui sont nécessaires pour l'outil "gérer les limites des spécifications" pour la qualité. et le contrôle des processus.
J'aimerais générer les nouveaux scripts avec une boucle For dans la fonction New Script - c'est du moins le concept. Un exemple de ce que j'aimerais envoyer à la table est ci-dessous, où j'aimerais que le [1] soit éventuellement un [i] dans une boucle For :
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 )}
)
)
)
);Certaines parties fonctionnent comme je le souhaite, d'autres non. Le nom du nouveau script fonctionne comme prévu. J'ai des problèmes, notamment avec la partie Dispatch. Après "Dispatch( {} , SpecList[1],....". et avec les sections Add Ref Line().
Le Dispatch SpecList[1] envoie littéralement SpecList[1] au lieu d'insérer le texte de la liste. Ensuite, dans la partie Ajouter une ligne de référence, il envoie également littéralement dtspecs:Name("_LSL")[1] au lieu de la valeur de la table de données. Le script enregistré dans la table de données est ci-dessous :
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 )}
)
)
)J'ai essayé Char(), Num(), Try() et Eval() enroulés autour des sections de code pertinentes pour voir si cela fonctionnerait, mais ce n'est pas le cas.
De plus, la colonne Y des variables ne fonctionne pas. Il envoie à nouveau exactement ce qui est écrit au lieu de la référence vers laquelle il pointe. Cependant, lorsque je mets en évidence la fonction Control Chart Builder dans mon script d'origine ci-dessus (premier script), cela fonctionne très bien.
J'aimerais un moyen de résoudre ce problème afin qu'il envoie les valeurs réelles référencées au nouveau script au lieu du script JSL littéral. La raison est que j'essaie d'écrire le script aussi générique que possible afin qu'il puisse être appliqué à d'autres produits et que l'on n'ait pas besoin de creuser trop profondément dans le script pour le modifier/mettre à jour afin de le déployer pour l'autre. des produits.
Je pense qu'une partie du problème est que mes noms de variables résident tous dans mon script principal (je définis les noms par défaut ici (1)), et lorsqu'il envoie un nouveau script à la table de données, il ne sait pas comment évaluer un référence à une variable qui n’est pas définie. Je devrai peut-être envoyer ces variables au script en cours d'écriture dans la table de données, mais je ne sais pas comment. Je préférerais ne pas non plus générer de variable globale.
Merci!,
DS
Salut @nathan-clark et @ian_jmp ,
J’apprécie vraiment vos commentaires et vos idées. Certaines des choses utilisées dépassent mon niveau en ce moment et je n'arrivais pas à comprendre comment les mettre en œuvre.
D'un autre côté, sur la base de vos commentaires, j'ai modifié mon code et l'ai fait fonctionner d'une manière qui me paraissait logique. Ce n'est peut-être pas très élégant, mais cela fonctionne et fait exactement ce que je voulais faire.
Une fois que j’ai réalisé que la boucle For devait être à l’extérieur de tout, cela a très bien fonctionné. Il est logique maintenant que je doive transformer CharList[i] en une expression qui doit ensuite être exécutée via un EvalExpr, qui doit ensuite être évaluée afin d'envoyer à la table de données le nouveau script avec les entrées souhaitées. .
Vous trouverez ci-dessous mon code expliquant comment je l'ai fait fonctionner.
Merci pour l'aide!
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, et probablement préférence personnelle, mais j'ai tendance à utiliser 'SubstituteInto()' pour ce genre de chose :
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;
La meilleure façon que j'ai trouvée pour ce faire est d'utiliser Eval() et EvalExpr()... en gros, les variables du script sont des expressions et l'expression eval les évalue afin que l'évaluation finale de votre script de table ait les valeurs réelles, pas les variables. Vous trouverez ci-dessous un exemple rapide que j'ai saisi où j'ai créé un script de table et qui insérera les noms de colonnes spécifiques par opposition à la variable (parseUnique). parseUnique est créé en insérant une chaîne de texte pour le nom de la colonne dans la fonction :Name() afin que les noms de colonnes fonctionnent mieux.
Je n'ai pas besoin de m'inquiéter des variables que je crée dans l'expression (tblName), mais toutes les variables provenant de sources extérieures deviennent des expressions dans la fonction.
parseUnique = EvalInsert(":Name(\!"^uniqueCol^\!")");Eval(
EvalExpr(
dt_algorithm << New Script("Make justResults",
tblName = currentdatatable()<<GETNAME></GETNAME>