親愛的 JMP 社群:
我的任務是編寫一個腳本,旨在自動從「混亂」的 Excel 文件中匯入資料。 我說「混亂」是因為我想要從 Excel 文件中提取的實際資料沒有以整齊的列和行的形式組織 - 它遍布各處 - 但它始終位於每個 Excel 文件中的相同位置。 這些文件基本上包含我們生產批次的批次信息,我正在嘗試從這些 Excel 文件中提取測試數據並將其放入 JMP 數據表中。
有多個批次 Excel 檔案分佈在多個目錄中。 為了解決這個問題,我使用 Files In Directory() 命令來產生需要開啟的所有 Excel 檔案的列表,並帶有「遞歸」標誌,因此在建置列表時我還會取得所有子目錄。 這將創建一個長達數百項的清單。 將該清單命名為 NLotFiles。
我首先有一個從 i=1 到 N Items(NLotFiles) 長的 For 循環,因此它需要通過這個更大的 For 循環運行幾百次。
然後,我需要多次打開該文件並每次導入一些資訊。 我需要多次執行此操作,因為資訊不僅分佈在多個單元格中,而且還分佈在 Excel 文件中的多個選項卡中。
第一次開啟會提取日期和批次資訊。 然後我需要檢查第一列第一行中是否有條目(如果存在日期)。 如果沒有,我想關閉該資料表並返回第一個 For 循環,進入下一次迭代。
****這就是我陷入困境的地方。
接下來的多次開啟將所有資料拉出到其他表中,然後將它們連接在一起並形成一個大資料表。 只要每個文件中都有日期條目,此方法就有效。 但是,並非所有文件都有日期——例如,當天沒有進行任何批次。 如果發生這種情況,它仍然會開啟該文件,但所有其餘程式碼都無法正常工作,因為它基於 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.如果我能夠告訴 JMP 要導入哪些確切的選項卡和單元格(例如使用選項卡和單元格編號列表,因為這些選項卡和單元格編號在 Excel 文件中始終相同),那就太好了。 這將消除引入所有內容所需的多重循環。
非常感謝任何幫助,特別是如果有人更好地了解如何提取重要資訊並使程式碼比當前更容易/更簡單。 我的實際程式碼總共大約有 300 行(包括空行),所以還不錯。 但更簡單的程式碼通常更容易排除故障,也更容易讓其他人編寫程式碼。
謝謝!,
DS
你好@gzmorgan0 ,
感謝您的回饋意見。 我想我已經嘗試過了,但仍然沒有成功。 問題不在於“粘合劑”,而是退出“If(Is Missing...”部分後,大的外部 For 循環繼續,並且不知道在代碼的後續部分要做什麼,因為數據表本來打開的已經不存在了。
我昨天剛找到了一個解決方法,今天早上測試過,效果非常好。 它的運作完全像我想像的那樣。
我發現如果我將“禁止空列(1)”(這是打開Excel 文件時的預設)更改為“禁止空列(0)”,它將打開空資料表,我可以在其中將日期設置為1/1/1904(即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()
);