JMP コミュニティの皆様
私には、「乱雑な」Excel ファイルからのデータのインポートを自動化するためのスクリプトを作成するというタスクがあります。 「乱雑」と言ったのは、Excel ファイルから取り出したい実際のデータがきちんとした列と行に整理されておらず、あちこちに散らばっているためですが、各 Excel ファイルでは常に同じ場所にあります。 ファイルには基本的に製造ロットに関するロット情報が含まれており、これらの Excel ファイルからテスト データを抽出して JMP データ テーブルに入力しようとしています。
複数のロットの Excel ファイルが複数のディレクトリに分散されています。 これに対処するために、Files In Directory() コマンドを使用して開く必要のあるすべての Excel ファイルのリストを生成し、「再帰」フラグを付けて、リストを作成するときにすべてのサブディレクトリも取得します。 これにより、数百項目の長さのリストが作成されます。 リストを NLotFiles と呼びます。
まず、i=1 から N Items(NLotFiles) までの長さで実行される For ループがあるため、このより大きな For ループを数百回実行する必要があります。
次に、ファイルを複数回開き、そのたびにいくつかの情報をインポートする必要があります。 情報は複数のセルにまたがるだけでなく、Excel ファイル内の複数のタブにもまたがるため、これを複数回行う必要があります。
最初に開くと、日付とロットの情報が取得されます。 次に、最初の列、最初の行にエントリがあるかどうか (日付が存在する場合) を確認する必要があります。 そうでない場合は、そのデータ テーブルを閉じて最初の For ループに戻り、次の反復に進みます。
****ここで行き詰まってしまいます。
次に複数回開くと、すべてのデータが他のテーブルに取り出され、それを結合して 1 つの大きなデータ テーブルを作成します。 各ファイルに日付のエントリがある限り、この方法は機能します。 ただし、すべてのファイルに日付があるわけではありません。たとえば、その日はロットが作成されなかったなどです。 その場合でも、ファイルは開きますが、コードの残りの部分はすべて、Excel ファイルの構造と日付の存在に基づいているため、正しく動作しません。
JSL には GOTO オプションがないため、日付値をテストし、ない場合はテーブルを閉じ、NLotFiles リストの次の反復に戻るのに苦労しています。 Is Missing() 関数を使用して日付の存在をテストし、Continue() を使用しようとしていますが、思ったように機能しません。
このコードの基本構造は次のようなものです。
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.Excel ファイルではタブとセル番号は常に同じであるため、タブとセル番号のリストを使用するなど、どの正確なタブとセルをインポートするかを JMP に指示できれば素晴らしいと思います。 これにより、すべてを取り込むために必要な複数のループが不要になります。
特に、誰かが重要な情報を抽出し、コードを現在よりも簡単/単純にする方法についてより良いアイデアを持っている場合は、助けていただければ幸いです。 実際に私が持っているコードは合計300行程度(空行含む)なので、それほど悪くはありません。 ただし、コードが単純であれば、トラブルシューティングが簡単で、他の人がコードを書き込むのも簡単です。
ありがとう!、
DS
こんにちは@gzmorgan0 、
ご意見ありがとうございます。 それを試してみましたが、それでもうまくいかなかったと思います。 問題は「接着剤」というよりも、外側の大きな For ループが「If(Is Missing...」部分を終了した後も継続しており、コードの後の部分で何をすべきかわからないということです。開かれていたはずですが、もう存在しません。
昨日回避策を見つけて今朝テストしたところ、完璧に機能しました。 まさに思った通りに動きました。
「空の列を抑制(1)」(Excel ファイルを開くときのデフォルト)を「空の列を抑制(0)」に変更すると、空のデータテーブルが開き、そこに日付を設定できることがわかりました。 1904 年 1 月 1 日 (つまり 0)、次に、数百のファイルからビッグ データ テーブルを構築した後、date=0 であるすべての行を検索し、それらを削除しました。
これは最もエレガントな解決策ではないかもしれませんが、JSL には GoTo オプションがないため、これが私にできる最善の方法です (少なくとも私にできること)。 そのため、空のエントリが多数作成されますが、for ループの途中でテーブルを閉じるよりも、これらのエントリを検索するのが簡単です。
ありがとう!、
DS
@SDF1 、
ご説明いただいた問題を完全には理解していませんが、コード内にエラーを発見しました。これにより、多少の進歩が得られるかもしれません。
あなたの 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()
);
エラーは閉じた後のカンマです。 閉じて続行したいと思います。 カンマはセミコロンにする必要があります。 セミコロンは、実行する各 JSL コマンド/アクションの接着剤です。つまり、実行されるコードのブロックを定義します。
これをこれに置き換えると、Continue() が機能するはずです。
//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()
);