[JMP Pro 14.1.0, sistema operativo W7 de 64 bits]
Estimados,
Estoy trabajando en la automatización de una tabla de datos para algunos clientes. La tabla de datos contiene una columna de fecha y varias columnas de propiedades del producto, todas con límites de especificaciones.
Una de las cosas que intento hacer es agregar nuevos scripts a la tabla de datos para que el cliente pueda hacer clic fácilmente en el botón verde de la tabla de datos y obtener el gráfico de control de cualquier propiedad que le interese.
Tengo una lista llamada "SpecList" que contiene todos los nombres de columnas en la tabla de datos, y tengo una tabla de datos de especificaciones con los nombres de columnas habituales _LSL, _USL y _Target que se necesitan para la herramienta "administrar límites de especificaciones" para garantizar la calidad. y control de procesos.
Me gustaría generar los nuevos scripts con un bucle For dentro de la función New Script; al menos ese es el concepto. A continuación se muestra un ejemplo de lo que me gustaría enviar a la tabla, donde me gustaría que [1] eventualmente sea una [i] en un bucle 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 )}
)
)
)
);Algunas partes funcionan como pretendo, otras no. El nombre del nuevo script funciona como era de esperar. Tengo problemas, particularmente con la parte de Envío. Después de "Dispatch( {}, SpecList[1],...". y con las secciones Agregar línea de referencia().
Dispatch SpecList[1] envía literalmente SpecList[1] en lugar de insertar el texto de la lista. Luego, en la parte Agregar línea de referencia, también envía literalmente dtspecs:Name("_LSL")[1] en lugar del valor de la tabla de datos. El script que se guarda en la tabla de datos se encuentra a continuación:
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 )}
)
)
)Probé Char(), Num(), Try() y Eval() envolviendo las secciones de código relevante para ver si funcionaría, pero no funciona.
Además, la columna Y en Variables no funciona. Nuevamente envía exactamente lo que está escrito en lugar de la referencia a la que apunta. Sin embargo, cuando resalto la función Generador de gráficos de control en mi script original anterior (primer script), funciona bien.
Me gustaría encontrar una forma de resolver esto para que envíe los valores reales a los que se hace referencia al nuevo script en lugar del script JSL literal. La razón es que estoy tratando de escribir el script lo más genérico posible para que pueda aplicarse a otros productos y no sea necesario profundizar demasiado en el script para modificarlo/actualizarlo y poder implementarlo para el otro. productos.
Creo que parte del problema es que todos los nombres de mis variables se encuentran en mi secuencia de comandos principal (establecí los nombres predeterminados aquí (1)), y cuando envía una nueva secuencia de comandos a la tabla de datos, no sabe cómo evaluar una referencia a una variable que no está definida. Es posible que necesite enviar estas variables al script que se escribe en la tabla de datos, pero no estoy seguro de cómo. Preferiría no generar una variable global tampoco.
¡Gracias!,
DS
Hola @nathan-clark y @ian_jmp ,
Realmente aprecio sus comentarios e ideas. Algunas de las cosas utilizadas están más allá de mi nivel en este momento y no pude entender cómo implementarlas.
Por otro lado, basándome en sus comentarios, modifiqué mi código y lo hice funcionar de una manera que tenía sentido para mí. Puede que no sea muy elegante, pero funciona y hace exactamente lo que me propuse.
Una vez que me di cuenta de que el bucle For debía estar fuera de todo, funcionó muy bien. Tiene sentido ahora que necesito convertir CharList[i] en una expresión que luego debe ejecutarse a través de un EvalExpr, todo lo cual luego debe evaluarse para enviar a la tabla de datos el nuevo script con las entradas deseadas. .
A continuación se muestra mi código sobre cómo lo hice funcionar.
¡Gracias por la ayuda!
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, y probablemente preferencia personal, pero tiendo a usar 'SubstituteInto()' para este tipo de cosas:
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 mejor manera que he encontrado para hacer esto es usar Eval() y EvalExpr()... básicamente, las variables en el script son expresiones y la expresión eval las evalúa para que la evaluación final de su script de tabla tenga los valores reales, no los variables. A continuación se muestra un ejemplo rápido que tomé donde creé un script de tabla y insertará los nombres de las columnas específicas en lugar de la variable (parseUnique). parseUnique se crea insertando una cadena de texto para el nombre de la columna en la función :Name() para que los nombres de las columnas funcionen mejor.
No necesito preocuparme por las variables que creo dentro de la expresión (tblName), pero cualquier variable que provenga de fuentes externas se convierte en expresiones en la función.
parseUnique = EvalInsert(":Name(\!"^uniqueCol^\!")");Eval(
EvalExpr(
dt_algorithm << New Script("Make justResults",
tblName = currentdatatable()<<GETNAME></GETNAME>