친애하는 JMP 커뮤니티 여러분,
나는 "지저분한" Excel 파일에서 데이터 가져오기를 자동화하기 위한 스크립트를 작성하는 임무를 맡고 있습니다. 내가 "지저분하다"고 말한 이유는 Excel 파일에서 꺼내려는 실제 데이터가 깔끔한 열과 행으로 구성되어 있지 않고 여기저기 흩어져 있지만 각 Excel 파일에서 항상 같은 위치에 있기 때문입니다. 파일에는 기본적으로 생산 로트에 대한 로트 정보가 포함되어 있으며 이러한 Excel 파일에서 테스트 데이터를 가져와 JMP 데이터 테이블에 넣으려고 합니다.
여러 디렉터리에 걸쳐 여러 로트 Excel 파일이 분산되어 있습니다. 이 문제를 해결하기 위해 "recursive" 플래그를 사용하여 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.Excel 파일에서 항상 동일하기 때문에 탭과 셀 번호 목록을 사용하는 등 가져올 정확한 탭과 셀을 JMP에 알릴 수 있다면 좋을 것입니다. 이렇게 하면 모든 것을 가져오는 데 필요한 다중 루핑이 제거됩니다.
어떤 도움이라도 대단히 감사하겠습니다. 특히 중요한 정보를 추출하고 코드를 현재보다 더 쉽고/간단하게 만드는 방법에 대한 더 나은 아이디어가 있는 경우 더욱 그렇습니다. 제가 실제로 가지고 있는 코드는 총 300줄 정도(빈 줄 포함) 정도이므로 나쁘지 않습니다. 그러나 간단한 코드는 문제를 해결하기가 더 쉬우며 다른 사람이 코드를 작성하기도 더 쉽습니다.
감사해요!,
DS
안녕 @gzmorgan0 ,
피드백을 보내주셔서 감사합니다. 제 생각엔 그걸 시도해 보았으나 여전히 효과가 없었습니다. 문제는 큰 외부 For 루프가 "If(Is Missing..." 부분을 종료한 후 계속되고 코드의 후반부에서 무엇을 해야 할지 알지 못하는 것보다 "접착제"가 별로 없었습니다. 열렸을 텐데 더 이상 존재하지 않습니다.
어제 아침에 테스트한 해결 방법을 찾았는데 완벽하게 작동합니다. 제가 생각했던 것과 정확히 일치하게 실행되었습니다.
"빈 열 억제(1)"(Excel 파일을 열 때 기본값)를 "빈 열 억제(0)"로 변경하면 날짜를 설정할 수 있는 빈 데이터 테이블이 열리는 것을 발견했습니다. 1904년 1월 1일(즉 0), 수백 개의 파일로 빅데이터 테이블을 구축한 후 날짜=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()
);