Chère communauté JMP,
J'ai pour tâche d'écrire un script destiné à automatiser l'importation de données à partir de fichiers Excel « désordonnés ». Je dis « désordonné » parce que les données réelles que je souhaite extraire des fichiers Excel ne sont pas organisées en colonnes et en lignes soignées – elles sont partout – mais elles sont toujours au même endroit dans chaque fichier Excel. Les fichiers contiennent essentiellement des informations sur nos lots de production et j'essaie d'extraire les données de test de ces fichiers Excel et de les placer dans un tableau de données JMP.
Il existe plusieurs lots de fichiers Excel répartis dans plusieurs répertoires. Pour résoudre ce problème, je génère une liste de tous les fichiers Excel que je dois ouvrir à l'aide de la commande Files In Directory(), avec l'indicateur "récursif", donc je récupère également tous les sous-répertoires lors de la création de la liste. Cela crée une liste de plusieurs centaines d’éléments. Appelez la liste NLotFiles.
J'ai d'abord une boucle For qui s'étend de i = 1 à N Items (NLotFiles), elle doit donc être exécutée plusieurs centaines de fois dans cette plus grande boucle For.
Ensuite, je dois ouvrir le fichier PLUSIEURS fois et importer des informations à chaque fois. Je dois le faire plusieurs fois car les informations sont non seulement réparties sur plusieurs cellules, mais également sur plusieurs onglets du fichier Excel.
La première ouverture extrait la date et les informations sur le lot. Je dois ensuite vérifier s'il y a une entrée dans la première colonne, première ligne (si une date existe). Sinon, je souhaite fermer cette table de données et revenir à la première boucle For pour passer à l'itération suivante.
****C'est là que je suis coincé.
Le multiple suivant s'ouvre et extrait toutes les données dans d'autres tables que je réunis ensuite pour former une grande table de données. Tant qu'il y a une entrée pour la date dans chaque fichier, cette méthode fonctionne. Mais tous les fichiers n'ont pas de date -- par exemple, aucun dossier n'a été créé ce jour-là. Si cela se produit, le fichier s'ouvre quand même, mais tout le reste du code ne fonctionne pas correctement car il est basé sur la structure du fichier Excel et la présence de la date.
Puisqu'il n'y a pas d'option GOTO dans JSL, j'ai du mal à tester la valeur de la date, à fermer la table si aucune et à revenir à l'itération suivante dans la liste NLotFiles. Je teste l'existence d'une date en utilisant la fonction Is Missing() et en essayant d'utiliser Continue(), mais cela ne fonctionne pas comme je le pensais.
La structure de base de ce code ressemble à ceci :
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.Ce serait formidable si je pouvais indiquer à JMP quels onglets et cellules exacts importer, par exemple en utilisant une liste de numéros d'onglets et de cellules, car ceux-ci sont toujours les mêmes dans les fichiers Excel. Cela éliminerait les multiples boucles nécessaires pour tout intégrer.
Toute aide est grandement appréciée, surtout si quelqu'un a une meilleure idée de la façon d'extraire les informations importantes et de rendre le code plus facile/simple qu'il ne l'est actuellement. Le code réel que j'ai fait un total d'environ 300 lignes (y compris les lignes vides), donc ce n'est pas trop mal. Mais un code plus simple est souvent plus facile à dépanner ou à coder dans quelqu'un d'autre.
Merci!,
DS
Salut @gzmorgan0 ,
Merci pour vos commentaires. Je pense que j'avais essayé et ça n'a toujours pas fonctionné. Le problème n'était pas tant la "colle" que la grande boucle For externe qui continue après avoir quitté la partie "If (Is Missing...") et ne sait pas quoi faire dans les parties ultérieures du code car la table de données qui qui aurait été ouvert n'existe plus.
Je viens de trouver hier une solution de contournement que j'ai testée ce matin, et elle fonctionne parfaitement. Il s'est déroulé exactement comme je le pensais.
J'ai découvert que si je changeais "Supress Empty Columns (1)" (qui est la valeur par défaut lors de l'ouverture de fichiers Excel) en "Supress Empty Columns (0)", cela ouvrirait une table de données vide où je pourrais définir la date sur 1/1/1904 (c'est-à-dire 0), puis, après avoir construit la table Big Data à partir de plusieurs centaines de fichiers, j'ai recherché toutes les lignes où date=0 et je les ai simplement supprimées.
Ce n'est peut-être pas la solution la plus élégante, mais comme JSL n'a pas d'option GoTo, c'est le mieux que je puisse faire – du moins ce que je suis capable de faire. Cela crée donc un tas d'entrées vides, mais celles-ci sont faciles à rechercher plutôt que de fermer une table au milieu d'une boucle.
Merci!,
DS
@SDF1 ,
Je n'ai pas complètement digéré votre problème décrit, cependant, j'ai repéré une erreur dans votre code, qui pourrait vous permettre de progresser.
Votre 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'erreur est la virgule après la fermeture. Je pense que vous voulez fermer ET continuer. Les virgules doivent être des points-virgules. Le point-virgule colle à chaque commande/action JSL que vous souhaitez effectuer, c'est-à-dire qu'il définit le bloc de code à exécuter.
Remplacez-le par ceci et votre Continue() devrait fonctionner :
//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()
);