스크립트는 스크립팅 편집기에서 작동하지만 메뉴 항목에서는 작동하지 않습니다(열 이름 가져오기가 동일하게 작동하지 않음).스크립팅 편집기에서 다음 스크립트를 실행하면 제대로 작동합니다.그런데 View->Customize에서 만든 커스텀 메뉴 항목에서 실행하면 작동하지 않습니다.동일하게 작동하지 않는 Get Column Names 함수까지 추적했습니다.Get Property를 사용하기 전에 각 열 이름과 해당 유형의 값을 출력하는 인쇄 문을 입력하면 스크립팅 편집기에서 실행할 때(예를 들어) 다음과 같은 내용이 표시됩니다.
:exec_typ
"이름"
그러나 내 메뉴 항목에서 실행하면 다음과 같이 표시됩니다.
exec_typ
"이름"
콜론의 부족에 주목하십시오.(콜론이 무엇을 하든 나는 모른다.)
궁극적으로 exec_typ이라는 열에서 Get Property 함수를 실행하려고 할 때 JMP가 이를 열 이름 또는 이와 유사한 이름으로 인식하지 못하기 때문에 스크립트가 충돌합니다.
Send Expects Scriptable Object{7} 액세스 또는 'Send' , colNames[colInd] << /*###*/Get Property( "Spec limits" ) /*###*/
도대체 무슨 일이 일어나고 있는지 아십니까?Get Column Names 함수가 스크립팅 편집기에서 호출할 때와 메뉴 바로 가기에서 호출할 때 다르게 동작하는 이유는 무엇입니까?
아래 코드.예, 일부는 지저분합니다.
//Reports all failing tests for a unit. Not temperature-smart (yet!)
dt = Current Data Table();
colNames = dt << get column names(Numeric);
//I need to clean up the add columns scripts... once I understand how it works.
dt << add multiple columns(
"Num Tests Failing",
1,
After( "20:Neg_Contact:Cont_int2[1]" ),
numeric( 10 )
);
colf = Column( "Num Tests Failing" );
colf << Modeling Type ( Nominal );
dt << add multiple columns(
"Failing Tests",
1,
After( "20:Neg_Contact:Cont_int2[1]" ),
numeric( 10 )
);
colf = Column( "Failing Tests" );
colf << Data type( Character );
For (i = 1, i <= N Rows(dt), i++,
Row() = i;
failingTests = "";
NumOfFailingTests = 0;
If (:Name("HBIN_NAM") != "Good" & :Name("HBIN_NAM") != "1:Good" , //It's a fail
//Efficiency could be improved by extracting all spec limits first.
For (colInd = 1, colInd <= N Items(colNames), colInd++,
//print statements for debugging.
print(colNames[colInd]);
print(Type(colNames[colInd]));
//THIS IS WHERE IT KEEPS CRASHING
specLimits = colNames[colInd] << Get Property ("Spec limits");
LSL_Char = Char(specLimits[1]);
USL_Char = Char(specLimits[2]);
LSL_Char = SubStr(LSL_Char, 5, (Length(LSL_Char) - 5));
USL_Char = SubStr(USL_Char, 5, (Length(USL_Char) - 5));
LSL_Num = 0; //initializing value to set its scope; is this necessary? Donno.
USL_Num = 0;
If(LSL_Char == "." | LSL_Char == "",
LSL_Char = "NO LIMIT",
//else
LSL_Num = Num(LSL_Char);
);
If(USL_Char == "." | USL_Char == "",
USL_Char = "NO LIMIT",
//else
USL_Num = Num(USL_Char);
);
failedTest = 0;
If(LSL_Char != "NO LIMIT",
If( colNames[colInd][i] < LSL_Num,
failedTest = 1;
NumOfFailingTests = NumOfFailingTests + 1;
);
);
If(USL_Char != "NO LIMIT",
If( colNames[colInd][i] > USL_Num,
failedTest = 1;
NumOfFailingTests = NumOfFailingTests + 1;
);
);
If(failedTest == 1,
failingTests = failingTests || Char(colNames[colInd]) || "; ";
);
);
);
:Name( "Failing Tests" )[i] = failingTests;
:Name( "Num Tests Failing" )[i] = NumOfFailingTests;
);
Re: 스크립트는 스크립팅 편집기에서 작동하지만 메뉴 항목에서는 작동하지 않습니다(열 이름 가져오기가 동일하게 작동하지 않음).1. 코드를 JSL로 표시하려면 입력 창 상단의 도구를 사용하여 텍스트를 입력해야 합니다.
2. 내 코드가 귀하의 방법보다 더 빨리 작동할 것이라고 믿는 주된 이유는 2개의 항목을 기반으로 합니다.
ㅏ. 예, 수식이 최적화되었습니다.
비. 선택한 모든 행에 한 번에 할당할 수 있는 기능과 결합된 dt << Select Where를 사용하면 매우 빠릅니다.코드에 있는 모든 "IF" 문을 사용하여 데이터 테이블을 반복하는 것은 매우 느립니다.
3. 캐릭터 사양 제한 값에 대해.사양 제한을 어떻게 지정합니까?사양 제한 열 속성은 숫자 값만 허용해야 합니다.Substr()과 같은 문자 함수를 사용하여 Spec Limits 목록에 액세스하는 경우 문자열을 다시 얻게 됩니다.JSL 목록을 조작하는 방법에 대한 스크립팅 가이드를 살펴보십시오.
Re: 스크립트는 스크립팅 편집기에서 작동하지만 메뉴 항목에서는 작동하지 않습니다(열 이름 가져오기가 동일하게 작동하지 않음).스크립트 Jim에 감사드립니다! 당신 말이 맞아요. JMP 스크립트에서 변수 범위 지정이 어떻게 작동하는지 모르겠습니다. 단, 선언된 변수가 기본적으로 지역 변수임을 시사하는 몇 가지 증거를 본 것 외에는요.
이 포럼에서 스크립트를 올바르게 표시하려면 어떻게 했습니까?이 포럼의 코드 창에 코드를 붙여 넣으면 형식이 엉망이 되고 모든 탭과 공백 들여쓰기가 삭제됩니다.우리가 Python 코드를 공유하려고 하지 않는 것이 좋습니다!
어쨌든, 나는 당신의 요소를 사용하기 위해 내 스크립트를 조정하고 있으며 이미 마침내 작동하고 있습니다.dt= current data table(); 을 사용하여 스크립트를 직접 사용해 보았습니다. 한두 번 더 수정했지만 작동하지 않았습니다.내 스크립트가 비효율적으로 알고 있지만 예를 들어 USL과 LSL을 숫자로 변환하려는 모든 시도가 실패했기 때문에 문자열로 변환하고 하위 문자열을 사용해야 했습니다.모든 사양 제한을 한 번만 추출하도록 주석에 메모한 조정을 수행하면 그다지 중요하지 않습니다.열려 있는 파일 예제를 보는 것도 유용합니다. 왜냐면 제가 정말 하고 싶은 것은 제가 분석하고 있는 파일이 아닌 다른 파일에서 테스트 제한을 가져오는 옵션이 있기 때문입니다!
나에게 이상한 점은 열을 추가하고 삭제하는 것이 두 개의 중첩된 For 루프보다 더 효율적이라는 당신의 의미입니다(당신이 당신의 스크립트가 더 빠르다고 말했기 때문입니다).컴퓨터는 여전히 데이터 테이블의 모든 셀을 분석해야 합니다.JMP는 수식을 보다 효율적으로 설정하고 실행할 수 있도록 최적화되어 있습니까?나는 당신의 접근 방식이 실제로 작동하는지 확인할 수 없습니다. 아마도 후속 포저가 제안하는 것을 시도해야 할 것입니다.
그건 그렇고, 내 데이터 테이블에는 600개 정도의 열이 있고 수만 개의 행이 있을 수 있으므로 실행 효율성을 고려해야 할 수도 있습니다.
어쨌든 내 스크립트를 작동시키기 위해 필요한 최소한의 변경은 모든
colNames[colInd]
~와 함께
열( dt, colNames[colInd] ) .
내 데이터 파일과 함께 작동하도록 할 수는 없지만 스크립트에서 더 많은 요소를 적용해 보겠습니다.
Re: 스크립트는 스크립팅 편집기에서 작동하지만 메뉴 항목에서는 작동하지 않습니다(열 이름 가져오기가 동일하게 작동하지 않음).짐,
좋은 작업.나는 추가해야했다
dt << Run Formulas;
Eval(Parse(theExpr)) 뒤와 delete 수식 문 앞, 훌륭하게 작성된 스크립트의 두 위치에 있습니다.
Re: 스크립트는 스크립팅 편집기에서 작동하지만 메뉴 항목에서는 작동하지 않습니다(열 이름 가져오기가 동일하게 작동하지 않음).내 가정은 변수(:)의 범위를 구체적으로 지정하지 않았기 때문에 두 가지 다른 환경에서 실행하려고 할 때 문제가 발생한다는 것입니다.내가 관찰한 다른 항목은 귀하의 방법이 매우 느린 코드 조각이 될 것이라는 것입니다.이를 감안하여 두 환경 모두에서 작동하고 훨씬 빠르게 실행될 것이라고 생각되는 몇 가지 방법을 사용하여 스크립트를 다시 작성했습니다.아래 스크립트는 JMP와 함께 배포되는 Semiconductor Capability 데이터 테이블에 대해 실행됩니다.그러나 해당 테이블 열기에 대한 참조를 데이터 테이블의 Open 다음에 오는 문과 함께 제거하고
dt = 현재 데이터 테이블();
코드는 데이터에서 작동해야 합니다.
아래 코드에 주석을 달았으니 따라하시면 될 것 같습니다.또한 JMP 설치와 함께 배포되는 스크립팅 가이드를 반드시 읽어 보시기 바랍니다.
도움말==>도서==>스크립팅 가이드
그 미친 콜론이 무엇인지에 대해 모두 알려줄 것입니다.
Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/semiconductor capability.jmp" );
dt << delete columns( {2, 3, 4} );
// Get the numeric column names as strings
colNames = dt << get column names( Numeric, string );
// Create the new calculated columns
// They will be populated later
dt << New Column( "Num Tests Failing", numeric );
dt << New Column( "Failing Tests", character );
// Create a new column for each column in the colNames list
// and populate the colNames name, if it does NOT pass
For( i = 1, i <= N Items( colNames ), i++,
// Create the new colum
dt << New Column( "PassFail " || Char( i ), character );
// Get the Spec Limits for the first column
specLimits = Column( dt, colNames[i] ) << get property( "Spec Limits" );
// If no Spec Limits are found, do not process
If( Is Empty( specLimits ) == 0,
// Get the USL and LSL and if not present set to missing
LSL = Try( specLimits["LSL"], . );
USL = Try( specLimits["USL"], . );
// If the LSL is not missing process
If( Is Missing( LSL ) == 0,
// Find all rows where the colNames column is less than
// the LSL
dt << select where( As Column( dt, colNames[i] ) < LSL );
// If any rows are selected, then process
If( N Rows( dt << get selected rows ) > 0,
// Set the value in the PassFail column to the name of
// the colNames being processed. This will allow for
// the counting and the concatenating for the new
// calculation columns
Column( dt, "PassFail " || Char( i ) )[dt << get selected rows] = colNames[i]
|| "; "
);
);
// See above comments for LSL
If( Is Missing( USL ) == 0,
dt << select where( As Column( dt, colNames[i] ) > USL );
If( N Rows( dt << get selected rows ) > 0,
Column( dt, "PassFail " || Char( i ) )[dt << get selected rows] = colNames[i]
|| "; "
);
);
);
);
// Clean up and selected columns
dt << clear select;
// Create the command string required for the formula for the
// Failing Tests, which is a concatenated string of all of the
// PassFail columns.
theExpr = "dt:Failing Tests << set formula(Concat(:PassFail 1";
For( i = 2, i <= N Items( colNames ), i++,
theExpr = theExpr || ",:PassFail " || Char( i )
);
theExpr = theExpr || "))";
// Execute the command string
Eval( Parse( theExpr ) );
// Delete the formula, which will remove the formula, but not
// the calculated values
dt:Failing Tests << delete formula;
// Create the command string for the Num Tests Failing column
// The count is the sum of the "True" Boolean comparisions.
// That is, if PassFail 1 != "", it will be "True" and therefore
// will have the value of 1. If the cell is blank, it will have a
// value of 0. The sum of all of these comparisons will be equal to
// the number of non passing parameters(tests)
theExpr = "dt:Num Tests Failing << set formula(sum(:PassFail 1 != \!"\!"";
For( i = 2, i <= N Items( colNames ), i++,
theExpr = theExpr || ",:PassFail " || Char( I ) || " != \!"\!""
);
theExpr = theExpr || "));";
Eval( Parse( theExpr ) );
dt:Num Tests Failing << delete formula;
// Delete all of the PassFail columns, just to clean up the data table
dt << delete columns(index(n cols(dt)-N items(colNames)+1,ncols(dt)));