Querida comunidad JMP,
Tengo la tarea de escribir un script destinado a automatizar la importación de datos desde archivos de Excel "desordenados". Digo "desordenado" porque los datos reales que quiero extraer de los archivos de Excel no están organizados en columnas y filas ordenadas (están por todos lados), pero siempre están en el mismo lugar en cada archivo de Excel. Los archivos básicamente contienen información sobre nuestros lotes de producción y estoy tratando de extraer los datos de prueba de estos archivos de Excel y colocarlos en una tabla de datos JMP.
Hay varios archivos de Excel distribuidos en varios directorios. Para solucionar eso, genero una lista de todos los archivos de Excel que necesito abrir usando el comando Archivos en directorio(), con el indicador "recursivo", de modo que también tomo todos los subdirectorios al crear la lista. Esto crea una lista de varios cientos de elementos. Llame a la lista NLotFiles.
Primero tengo un bucle For que va desde i=1 hasta N elementos (NLotFiles) de largo, por lo que debe ejecutarse unos cientos de veces a través de este bucle For más grande.
Luego, necesito abrir el archivo MÚLTIPLES veces e importar información cada vez. Necesito hacer esto varias veces ya que la información no solo se distribuye en varias celdas, sino también en varias pestañas del archivo de Excel.
La primera apertura extrae la fecha y la información del lote. Luego necesito verificar si hay una entrada en la primera columna, primera fila (si existe una fecha). Si no, quiero cerrar esa tabla de datos y volver al primer bucle For, pasando a la siguiente iteración.
****Aquí es donde me quedo atascado.
Las siguientes aperturas múltiples extraen todos los datos en otras tablas que luego uno y convierto en una tabla de datos grande. Siempre que haya una entrada para la fecha en cada archivo, este método funciona. Pero no todos los archivos tienen una fecha; por ejemplo, no se fabricó ningún lote ese día. Si eso sucede, aún abre el archivo, pero el resto del código no funciona correctamente ya que se basa en la estructura del archivo de Excel y la presencia de la fecha.
Como no existe la opción GOTO en JSL, me resulta difícil probar el valor de fecha y cerrar la tabla si no hay ninguno y volver a la siguiente iteración en la lista NLotFiles. Estoy probando la existencia de una fecha usando la función Falta() e intentando usar Continuar(), pero no funciona como pensé.
La estructura básica de este código es algo como esto:
For( i= 1, i<=N Items( NLotFiles ), i++,
Open(
DataPath || "\"|| DataFiles[i],
Worksheets( "Coversheet" ),
Use for all sheets( 1 ),
Concatenate Worksheets( 0 ),
Create Concatenation Column( 0 ),
Worksheet Settings(
1,
Has Column Headers( 1 ),
Number of Rows in Headers( 1 ),
Headers Start on Row( 2 ),
Data Starts on Row( 3 ),
Data Starts on Column( 3 ),
Data Ends on Row( 3 ),
Data Ends on Column( 5 ),
Replicated Spanned Rows( 1 ),
Replicated Spanned Headers( 0 ),
Suppress Hidden Rows( 1 ),
Suppress Hidden Columns( 1 ),
Suppress Empty Columns( 1 ),
Import Cell Colors( 0 ),
Limit Column Detect( 0 ),
Column Separator String( "-" )
)
);
//This part tests if the date (first column, first row) is empty.
If(Is Missing(Column(Current Data Table(),1)[1])==1,
Close(Current Data Table(), no save),
Continue()
);
/////*****HERE IS WHERE I WANT IT TO GO BACK TO THE TOP IF NO DATE IS PRESENT BUT CONTINUE DOWN BELOW IF A DATE IS PRESENT*****
/////I don't think the Continue() is in the right place, but then if I don't have it present, the code just stops because all the stuff below can't be done.<BR /><BR /><BR />//This part ensures the date is Numeric and Continuous
datedt = Current Data Table();
datedt:Date << Data Type( Numeric, Format( "m/d/y" ) ) << Modeling Type( "Continuous" );
//Next steps would bring in the data from different tabs as the date information (again, I have to do multiple opens on the same file.)
//Then join all the data, clean things up in the new data tables<BR /><BR />); //This last ");" closes the big For loop that runs through a total of NLotFiles times.<BR /><BR />//Then I concatenate the multiple tables (each table represents a lot now) into my final data table and close all unwanted tables.Sería fantástico si pudiera decirle a JMP qué pestañas y celdas exactas importar, como usar una lista de números de pestañas y celdas, ya que siempre son los mismos en los archivos de Excel. Esto eliminaría los múltiples bucles necesarios para incorporar todo.
Cualquier ayuda es muy apreciada, especialmente si alguien tiene una mejor idea de cómo extraer la información importante y hacer que el código sea más fácil/simple de lo que es actualmente. El código real que tengo tiene un total de aproximadamente 300 líneas (incluidas las líneas vacías), por lo que no está tan mal. Pero un código más simple suele ser más fácil de solucionar o de que otra persona pueda codificar también.
¡Gracias!,
DS
Hola @gzmorgan0 ,
Gracias por tus comentarios. Creo que lo había intentado y todavía no funcionó. El problema no fue tanto el "pegamento" sino que el gran bucle For externo continúa después de salir de la parte "Si(Falta..." y no sabe qué hacer en partes posteriores del código porque la tabla de datos que se habría abierto ya no existe.
Ayer encontré una solución alternativa que probé esta mañana y funciona perfectamente. Funcionó exactamente como pensé que lo haría.
Descubrí que si cambiaba "Suprimir columnas vacías (1)" (que es el valor predeterminado al abrir archivos de Excel) a "Suprimir columnas vacías (0)", se abriría una tabla de datos vacía donde podría establecer la fecha. 1/1/1904 (es decir, 0), luego, después de haber creado la tabla de big data a partir de los cientos de archivos, busqué todas las filas donde fecha = 0 y simplemente las eliminé.
Puede que no sea la solución más elegante, pero como JSL no tiene ninguna opción GoTo, esto es lo mejor que puedo hacer, al menos lo que soy capaz de hacer. Por lo tanto, crea un montón de entradas vacías, pero son fáciles de buscar en lugar de cerrar una tabla en medio del bucle for.
¡Gracias!,
DS
@SDF1 ,
No he digerido completamente el problema descrito; sin embargo, detecté un error en su código que podría proporcionarle algún progreso.
Su JSL:
//This part tests if the date (first column, first row) is empty.
If(Is Missing(Column(Current Data Table(),1)[1])==1,
Close(Current Data Table(), no save),
Continue()
);
El error es la coma después del cierre. Creo que quieres cerrar Y continuar. Las comas deben ser punto y coma. El punto y coma sirve para cada comando/acción JSL que desee realizar, es decir, define el bloque de código que se ejecutará.
Reemplácelo con esto y su Continuar() debería funcionar:
//This part tests if the date (first column, first row) is empty.
If(Is Missing(Column(Current Data Table(),1)[1])==1,
Close(Current Data Table(), no save);
Continue()
);