Cara comunità JMP,
Ho il compito di scrivere uno script destinato ad automatizzare l'importazione di dati da file Excel "disordinati". Dico "disordinato" perché i dati effettivi che voglio estrarre dai file Excel non sono organizzati in colonne e righe ordinate - sono ovunque - ma sono sempre nello stesso posto in ogni file Excel. I file contengono fondamentalmente informazioni sui nostri lotti di produzione e sto cercando di estrarre i dati dei test da questi file Excel e inserirli in una tabella dati JMP.
Sono presenti più file Excel lotti distribuiti in più directory. Per risolvere questo problema, genero un elenco di tutti i file Excel che devo aprire utilizzando il comando File nella directory(), con il flag "ricorsivo", quindi prendo anche tutte le sottodirectory durante la creazione dell'elenco. Ciò crea un elenco lungo diverse centinaia di elementi. Chiama l'elenco NLotFiles.
Per prima cosa ho un ciclo For che va da i=1 a N Items (NLotFiles), quindi deve essere eseguito alcune centinaia di volte attraverso questo ciclo For più grande.
Quindi, devo aprire il file PIÙ volte e importare alcune informazioni ogni volta. Devo farlo più volte poiché le informazioni non sono distribuite solo su più celle, ma anche su più schede nel file Excel.
La prima apertura estrae la data e le informazioni sul lotto. Devo quindi verificare se è presente una voce nella prima colonna, prima riga (se esiste una data). In caso contrario, voglio chiudere la tabella dati e tornare al primo ciclo For, passando all'iterazione successiva.
****È qui che mi blocco.
La successiva apertura multipla estrae tutti i dati in altre tabelle che poi unisco e trasformo in un'unica tabella di dati di grandi dimensioni. Finché in ciascun file è presente una voce per la data, questo metodo funziona. Ma non tutti i file hanno una data: ad esempio, quel giorno non è stato creato alcun lotto. Se ciò accade, il file viene comunque aperto, ma tutto il resto del codice non funziona correttamente poiché si basa sulla struttura del file Excel e sulla presenza della data.
Poiché non esiste un'opzione GOTO in JSL, ho difficoltà a testare il valore della data e a chiudere la tabella se non ce n'è e tornare all'iterazione successiva nell'elenco NLotFiles. Sto verificando l'esistenza di una data utilizzando la funzione Is Missing() e provando a utilizzare Continue(), ma non funziona come pensavo.
La struttura di base di questo codice è qualcosa del genere:
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.Sarebbe fantastico se potessi dire a JMP quali schede e celle esatte importare, ad esempio utilizzando un elenco di numeri di schede e celle poiché sono sempre gli stessi nei file Excel. Ciò eliminerebbe i molteplici loop necessari per inserire tutto.
Qualsiasi aiuto è molto apprezzato, soprattutto se qualcuno ha un'idea migliore su come estrarre le informazioni importanti e rendere il codice più facile/più semplice di quanto non sia attualmente. Il codice effettivo che ho è di un totale di circa 300 righe (comprese le righe vuote), quindi non è poi così male. Ma il codice più semplice è spesso più facile da risolvere o anche qualcun altro può codificarlo.
Grazie!,
DS
CIAO @gzmorgan0 ,
Grazie per il tuo feedback Penso di averlo provato e ancora non ha funzionato. Il problema non era tanto il "collante" quanto il grande ciclo For esterno continua dopo essere uscito dalla parte "If(Is Missing..." e non sa cosa fare nelle parti successive del codice perché la tabella dati che sarebbe stato aperto non esiste più.
Ieri ho trovato una soluzione alternativa che ho testato stamattina e funziona perfettamente. Ha funzionato esattamente come pensavo.
Ho scoperto che se modificassi "Sopprimi colonne vuote (1)" (che è l'impostazione predefinita quando si aprono file Excel) in "Sopprimi colonne vuote (0)", si aprirebbe una tabella dati vuota in cui potrei impostare la data su 1/1/1904 (cioè 0), quindi, dopo aver creato la tabella Big Data da più centinaia di file, ho cercato tutte le righe in cui data=0 e le ho semplicemente cancellate.
Potrebbe non essere la soluzione più elegante, ma poiché JSL non dispone di alcuna opzione GoTo, questa è la cosa migliore che potrei fare, almeno quello che sono in grado di fare. Quindi, crea un sacco di voci vuote, ma queste sono facili da cercare piuttosto che chiudere una tabella a metà del ciclo for.
Grazie!,
DS
@SDF1 ,
Non ho assimilato a fondo il problema descritto, tuttavia, ho individuato un errore nel tuo codice, che potrebbe fornirti alcuni progressi.
Il tuo 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()
);
L'errore è la virgola dopo la chiusura. Penso che tu voglia chiudere E continuare. Le virgole dovrebbero essere un punto e virgola. Il punto e virgola fa da collante per ogni comando/azione JSL che si desidera eseguire, ovvero definisce il blocco di codice da eseguire.
Sostituiscilo con questo e il tuo Continue() dovrebbe funzionare:
//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()
);