스크립트여러분, 안녕하세요,
수식이나 스크립트에서 새 열을 만들고 싶은 데이터베이스가 있습니다.
다음은 데이터베이스의 개요입니다.

- 열 T는 수행할 작업을 나타냅니다.
- 열 X_3은 기능을 나타냅니다.
- op 열은 객체를 나타냅니다.
목표는 동일한 "obj"에 대해 결점의 합계가 라인마다 다를 때 "ko"와 "op"에 해당하는 숫자를 추가하는 "assessment" 열을 만드는 것입니다(여기서는 AT와 동일한 값). ).
마지막으로 작업 수 "3061"에 대해 대차대조표 열을 작성해야 합니다.
이것은 데이터베이스의 개요입니다. obj 열은 "A"이지만 데이터베이스에서 이 열은 값을 변경합니다.
귀하의 답변에 감사드립니다!
자동화 및 스크립팅Re: 스크립트행 6 작업 180이 마지막 열에 추가되지 않는 이유는 무엇입니까? 0은 1과 다릅니다.
(단지 한 단어보다 더 유익한 게시물 제목을 사용해야 합니다)
Re: 스크립트합계가 6행에 대해 0과 같기 때문입니다. 오히려 결점의 합이 0과 다를 때 "balance" 열에 "op"의 값을 알려준다.
Re: 스크립트그렇다면 두 행 간에 값이 다른지 확인할 필요가 있습니까? 아니면 :op이 0이 아닌 행에만 관심이 있습니까?
Re: 스크립트:sum default의 값이 0이 아닌 행에만 관심을 가질 수 있다고 생각합니다. 기본 합계 값이 0이면 대차대조표 열에서 아무것도 얻지 못하기 때문입니다.
Re: 스크립트당신의 답변에 감사드립니다 !
두 가지 방법을 비교해보면 제 경우에는 두 번째 방법이 더 나은 것 같습니다.
나는 그것을 내 데이터베이스에 적용했고 열은 두 데이터베이스에서 동일한 형식을 가지며 다음 유형의 오류가 발생합니다.

Re: 스크립트오류 메시지가 프랑스어로 되어 있어서 이해할 수 없습니다. 오류가 결국 bilan3 열이 없다는 것을 알려주는 것일 수 있습니다. (잘못된 첨자가 있다는 말인데 bilan3 컬럼이 없어서 생긴 현상입니다. 이는 열이 없는 경우 dt[input_loc, "bilan3"]이 [](1, 0)을 반환하고 일부 값을 열에 설정하려고 시도하기 때문입니다.
Re: 스크립트"input_loc" 변수가 비어 있기 때문입니다. 따라서 "대차대조표3" 열에 새 셀을 할당하는 것은 불가능합니다.
Re: 스크립트열 "T"에서 값 "3061"(숫자가 아닌 문자)을 찾을 수 없습니다. 또한 빈 input_loc을 처리하기 위해 구현한 검사가 올바르지 않습니다. < 0 대신 < 1로 수정해야 합니다.
Re: 스크립트이 스크립트는 두 가지를 모두 수행하며 제공된 예제와 함께 작동합니다. 나는 당신이 그것이 무엇을 하는지 이해하려고 노력하고 당신이 하지 않는 부분이 있는지 물어볼 것을 강력히 제안합니다.
Names Default To Here(1);
dt = Open("$DOWNLOADS/AAA.jmp");
dt << New Column("bilan2", Character, Nominal);
dt << New Column("bilan3", Character, Nominal);
Summarize(dt, unique_objects = by(:obj));
m_obs = dt[0, "obj"];
/* comparing rows */
For Each({unique_object}, unique_objects,
object_rows = Loc(m_obs, unique_object);
values = dt[object_rows, "SOMME DEFAUT"];
values1 = Remove(values, 1);
values2 = Remove(values, N Items(values));
differences = [0] |/ values1 - values2;
ops = dt[object_rows[Loc(differences != 0)], "op"];
result_str = "ko - " || Concat Items(ops, " / ko - ");
input_loc = Loc(dt[object_rows, "T"], "3061");
If(N Items(input_loc) < 0,
continue();
,
dt[input_loc, "bilan2"] = Repeat({result_str}, N Items(input_loc));
);
);
/* zeros */
For Each({unique_object}, unique_objects,
object_rows = Loc(m_obs, unique_object);
values = dt[object_rows, "SOMME DEFAUT"];
ops = dt[object_rows[Loc(values)], "op"];
result_str = "ko - " || Concat Items(ops, " / ko - ");
input_loc = Loc(dt[object_rows, "T"], "3061");
If(N Items(input_loc) < 1,
continue();
,
dt[input_loc, "bilan3"] = Repeat({result_str}, N Items(input_loc));
);
);

편집: 수정된 if 문 If(N 항목(input_loc) ... < 0에서 < 1까지
Re: 스크립트데이터베이스에서 :T 열의 값은 동일한 유형의 개체에 대해 반드시 오름차순으로 정렬되지는 않습니다. 이것은 요소가 오름차순으로 정렬된 또 다른 :OPE 열입니다. :T 및 :OPE 열은 밀접하게 관련되어 있으며 각 개체 유형에 대해 고유합니다.
값 3061에 해당하는 :OPE 값보다 낮은 :OPE는 대차대조표 열에 아무것도 입력하지 않아야 합니다.
:OPE 값이 값 3061에 해당하는 값:OPE보다 크면 첫 번째 메시지에서 이미 설명한 작업이 수행됩니다.
예를 들어 아래 만화를 참조하십시오.

답변 감사합니다!!
Re: 스크립트:OPE 값에 대한 추가 검사를 추가합니다. 행의 :OPE 값이 "3061"의 :OPE 값보다 낮으면 무시하십시오. 다른 인덱스와 행으로 추적하기가 약간 어려울 수 있지만 디버그 인쇄를 추가하면 도움이 됩니다. 또한 하나의 개체에 "3061"이 두 개 이상 있을 수 있는 경우 계산이 더 복잡해집니다.
Re: 스크립트네 무슨 말씀인지 알겠습니다!
나는 다음과 같은 것을 상상합니다.
If( col = Loc(dt[Row(), :OPE] < Loc(dt[Row(), :T=="3061")),
continue();
,
script...
);
반면에 같은 객체가 3061이라는 숫자를 두 번 갖는 것은 불가능합니다.
Re: 스크립트작동하지 않습니다. 어떻게 그런 스크립트를 만들 수 있는지 아십니까? @jthi (마지막으로 확인해야 할 사항)?
당신의 도움에 다시 한 번 감사드립니다!
Re: 스크립트unique_object에 대한 모든 :OPE 값을 가져온 다음 3061 행에 대한 :OPE 값을 가져옵니다. 그런 다음 모든 :OPE 값 목록에서 3061에 대한 :OPE 값보다 높은 인덱스를 확인합니다(Loc()가 이 작업을 수행할 수 있음).
Re: 스크립트네, 그렇게 생각했습니다. 그런 생각을 했지만 변수 a와 b를 정의하는 데 어려움이 남아 있습니다.
dt = current data table();
b = // all values :OPE for unique_object
a = // values :OPE for 3061
test = Loc(dt[Row(), b]) > Loc(dt[Row(),a]);
If( test=0 ,
continue();
,
script...;
);
Re: 스크립트특정 고유 개체에 대한 :SOMME DEFAUT 값을 저장하는 값 변수에 사용되는 것과 유사한 방법
values = dt[object_rows, "SOMME DEFAUT"];
디버그 인쇄를 추가하고 한 개체만 사용하여 한 번에 한 줄씩 스크립트를 실행해 보십시오.
Re: 스크립트네 감사합니다. 필요한 정보를 얻을 수 있도록 다음과 같은 코드를 작성했습니다.
dt = current data table();
For Each({unique_objects}, unique_objects,
object_rows = Loc(m_obs, unique_objects);
b = dt[object_rows, "OPE"];
show(b);
a = dt << Get Rows Where( :T == "3061");
valeurs_OPE = :OPE[a];
show(valeurs_OPE);
valeurs_OPE_3061_obj = dt[unique_objects, "valeurs_OPE"];
show(valeurs_OPE_3061_obj);
);그러나 obj(변수 "valeurs_OPE_3061_obj")로는 작업 3061에 해당하는 OPE 값을 가져올 수 없습니다.
"valeurs_OPE" 변수만 작업 3061에 해당하는 모든 OPE 데이터를 수집합니다.
Re: 스크립트For Each(현재로서는)를 무시하면 테스트하기가 더 쉽습니다. 다음과 같이 시작하십시오.
Names Default To Here(1);
// dt = Open("$DOWNLOADS/AAA.jmp");
// dt = Current Data Table();
dt = New Table("AAA(1)",
Add Rows(12),
Compress File When Saved(1),
New Column("obj", Character(16), "Nominal", Set Values({"A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "C", "C"})),
New Column("T", Character(4), "Ordinal", Set Values({"3052", "3061", "3082", "3940", "4012", "5010", "2890", "4060", "3061", "3081", "5010", "3061"})),
New Column("OPE", Numeric, "Continuous", Format("Best", 12), Set Values([12, 20, 32, 44, 56, 125, 210, 54, 60, 80, 45, 50])),
New Column("X__3", Character(4), "Nominal", Set Values({"rien", "rien", "incl", "ret", "ret", "rien", "incl", "incl", "ret", "incl", "ret", "rien"})),
New Column("SOMME DEFAUT", Numeric, "Continuous", Format("Best", 12), Set Values([0, 0, 1, 2, 1, 0, 2, 1, 2, 1, 1, 0])),
New Column("op", Character(12), "Nominal", Set Values({"40", "32", "55", "212", "510", "180", "2100", "2240", "2100", "500", "", ""})),
New Column("correct", Character, "Nominal", Set Values({"", "ko - 55 / ko - 212 / ko - 510 / ko - 2100", "", "", "", "", "", "", "ko - 500", "", "", "."}))
);
dt << New Column("bilan", Character, Nominal);
Summarize(dt, unique_objects = by(:obj));
m_obs = dt[0, "obj"];
unique_object = unique_objects[2];
object_rows = Loc(m_obs, unique_object);
input_loc = Loc(dt[object_rows, "T"], "3061"); // location of 3061 for unique_object
show(input_loc); // index within object_rows
show(object_rows[input_loc]); // real row number
opes = dt[object_rows, "OPE"]; // all OPE values for unique_object
valid_ope_idx = Loc(...//Re: 스크립트
다음 스크립트를 계속 사용했습니다.
Names Default To Here(1);
dt = current data table();
dt << New Column("BILAN", Character, Nominal);
Summarize(dt, unique_objects = by(:obj));
m_obs = dt[0, "obj"];
dt = current data table();
For Each({unique_objects}, unique_objects,
object_rows = Loc(m_obs, unique_objects); // lignes pour chaque obj
b = dt[object_rows, "OPE"]; // les différentes opé pour chaque obj
show(b);
input_loc = Loc(dt[object_rows, "T"], "3061"); // localiser 3061 pour chaque objet
z = object_rows[input_loc]; // localiser les lignes OPE 3061 pour chaque obj
value_OPE_3061 = :OPE[z]; // valeur de l'ope 3061 pour chaque obj
show(value_OPE_3061);
//valid_ope_idx = Loc(b > value_OPE_3061);<BR /> //show(valid_ope_idx);
For( i = 1, i <= N Items(b), i++,
If(N Items(input_loc) < 1 & b[i] <= value_OPE_3061,
continue();
,
values = dt[object_rows, "SOMME DEFAUT"];
ops = dt[object_rows[Loc(values)], "op"];
result_str = "ko - " || Concat Items(ops, " / ko - ");
dt[object_rows[input_loc], "BILAN"] = Repeat({result_str}, N Items(input_loc));
);
);
);먼저 Loc() 함수를 사용하여 행 인덱스를 결정했지만 스크립트를 계속하는 방법을 모르겠습니다. 그래서 "For" 루프로 시도했지만 결과는 여전히 올바르지 않습니다. 앞으로 나아갈 수 있도록 도와주실 수 있나요?
모든 답변에 미리 감사드립니다!
Re: 스크립트스크립트의 다른 부분이 작동할 때까지는 For Each Row를 다시 추가할 필요가 없습니다. 올바른 값이 행 9로 설정될 때까지 내가 제공한 예제를 계속할 수 있습니다(B인 unique_objects[2]로 작업하기 때문). "3061" 행 OPE보다 높은 OPE 인덱스를 얻으려면 다음과 같이 Loc을 사용할 수 있습니다.
valid_ope_idx = Loc(opes > opes[input_loc]);
이들은 데이터 테이블의 행이 아닌 연산 행렬 내의 인덱스라는 점에 유의하십시오. 다시 행으로 변환하려면 object_rows가 특정 고유 개체에 대한 행이 있는 행렬이므로 object_rows와 함께 해당 인덱스를 사용할 수 있습니다.
Re: 스크립트그래 나도 너와 같은 생각이야 !
내 공식으로 찾은 값은 정확하고 당신과 같은 것을 찾습니다.
하지만 더 어려운 부분은 대본의 연속 구성에 있습니다!
값을 돌려줘야 하기 때문에 "코-..... /코-...» :OPE가 :T = 3061에 해당하는 :OPE보다 크고 :DEFAULT SUM이 0이 아닌 경우(예에서와 같이).
Re: 스크립트그들 당신은 비슷한 생각을 계속
- valid_ope_idx에 0개 이상의 항목이 있는지 확인 추가
- valid_ope_idx의 모든 값 가져오기
- 그런 다음 이것으로부터 0보다 큰 값의 인덱스를 얻습니다.
- 그런 다음 이 특정 인덱스에 대해 :op에서 값을 얻을 수 있습니다(먼저 행으로 변환해야 함을 기억하십시오).
- Concat Items()를 사용하여 이러한 값을 함께 연결합니다.
- 올바른 행에 값 추가
Re: 스크립트내 테스트 데이터베이스에서는 다음 코드와 함께 잘 작동합니다.
Names Default To Here(1);
dt = current data table();
dt << New Column("BILAN", Character, Nominal);
Summarize(dt, unique_objects = by(:obj));
m_obs = dt[0, "obj"];
somme_col = Filter Each( {col_name}, dt << Get Column Names( "String", Continuous ),
Starts With( col_name, "SOMME" )
);
dt = current data table();
For Each({unique_objects}, unique_objects,
object_rows = Loc(m_obs, unique_objects); // lignes pour chaque obj
b = dt[object_rows, "OPE"]; // les différentes opé pour chaque obj
show(b);
input_loc = Loc(dt[object_rows, "T"], "3061"); // localiser 3061 pour chaque objet
z = object_rows[input_loc]; // localiser les lignes OPE 3061 pour chaque obj
value_OPE_3061 = :OPE[z]; // valeur de l'ope 3061 pour chaque obj
show(value_OPE_3061);
valid_ope_idx = Loc(b > value_OPE_3061 & dt[object_rows,somme_col] > 0) ;
show(valid_ope_idx);
if( N items(valid_ope_idx) < 1,
continue();
,
ops = dt[object_rows[valid_ope_idx], "op"];
result_str = "ko - " || Concat Items(ops, " / ko - ");
dt[object_rows[input_loc], "BILAN"] = Repeat({result_str}, N Items(input_loc));
);
);그러나 내 최종 데이터베이스에서 동일한 obj에 대해 값 :T = 3061이 여러 번 표시될 수 있습니다(반면에 OPE의 값은 동일합니다!).
다른 것을 변경해야 한다고 생각합니다. value_OPE_3061의 값은 고유해야 합니다(예를 들어 value_OPE_3061 = [ 50 , 50 , 50 ]이 아니라 value_OPE_3061 = [ 50 ]).
배열/목록에서 중복 항목을 제거하는 기능이 JMP에 있습니까?
귀하의 답변에 감사드립니다!
Re: 스크립트이전에 "3061" 값이 여러 개 있을 수 없다고 말씀하셨습니까?
중복을 제거하는 한 가지 옵션은 << get 키와 함께 Associative Array()를 사용하는 것입니다(플로트가 있는 경우 작동하지 않음). 이 경우 다른 좋은 방법은 Design(<
Re: 스크립트이 부분을 추가했는데 더 잘 작동합니다.
Names Default To Here(1);
dt = current data table();
dt << New Column("BILAN", Character, Nominal);
Summarize(dt, unique_objects = by(:obj));
m_obs = dt[0, "obj"];
somme_col = Filter Each( {col_name}, dt << Get Column Names( "String", Continuous ),
Starts With( col_name, "SOMME" )
);
dt = current data table();
For Each({unique_objects}, unique_objects,
object_rows = Loc(m_obs, unique_objects); // lignes pour chaque obj
b = dt[object_rows, "OPE"]; // les différentes opé pour chaque obj
show(b);
input_loc = Loc(dt[object_rows, "T"], "3061"); // localiser 3061 pour chaque objet
if( N items(input_loc) < 1,
continue();
,
z = object_rows[input_loc]; // localiser les lignes OPE 3061 pour chaque obj
value_OPE_3061 = :OPE[z]; // valeur de l'ope 3061 pour chaque obj
liste={}; // transformer en liste pour supprimer les doublons
for (i = 1, i <= NRows(value_OPE_3061), i++,
for (j = 1, j <= NCols(value_OPE_3061), j++,
InsertInto(liste, value_OPE_3061[i, j]);
);
);
// supprimer les doublons
if( N items(liste) <= 1,
a = liste;
,
a = Left(liste,1);
);
// repasser en matrice pour faire les comparaisons
Mat_3061 = Matrix(a);
show(Mat_3061);
valid_ope_idx = Loc(b > Mat_3061 & dt[object_rows,somme_col] > 0) ;
show(valid_ope_idx);
if( N items(valid_ope_idx) < 1,
continue();
,
ops = dt[object_rows[valid_ope_idx], "op"];
result_str = "ko - " || Concat Items(ops, " / ko - ");
dt[object_rows[input_loc], "BILAN"] = Repeat({result_str}, N Items(input_loc));
);
);
);사실 당신 말이 맞아요 @jthi , 그러나 나는 :obj의 값 3061에 대해 변수 :OPE의 다른 값이 있을 수 없다고 말했습니다(나중에 obj에서 값이 2번 있을 수 있습니다. 예를 들어 값 :T는 3061과 같지만 값 :OPE는 동일합니다).
결국 출력에서 같은 :obj에 대해 3061과 같은 값 :T가 여러 번 있을 때 표시가 반복되지 않았으면 합니다.
예 :

다음과 같은 스크립트를 사용합니다.
input_loc = Loc(dt[object_rows, "T"], "3061");// localiser 3061 pour chaque objet
liste2={}; // transformer en liste pour supprimer les doublons
for (i = 1, i <= NRows(input_loc), i++,
for (j = 1, j <= NCols(input_loc), j++,
InsertInto(liste2, input_loc[i, j]);
);
);
// supprimer les doublons
if( N items(liste2) <= 1,
c = liste2;
,
c = Left(liste2,1);
);
// repasser en matrice pour faire les comparaisons
loc_3061 = Matrix(c);
올바르게 작동합니다. :T에 해당하는 첫 번째 인덱스는 3061입니다.
그러나 위의 캡처에서와 같이 동일한 줄에서 중복 요소를 제거할 수 있기를 원합니다.
kb - 2203 / kb - 2203 --> kb - 2203
Re: 스크립트개체에 대한 값이 3061인 첫 번째 인덱스를 선택할 수 있습니다.
Re: 스크립트이런 식으로 해결했을 것입니다. 예제 데이터로 작업해야 함
Names Default To Here(1);
// dt = Open("$DOWNLOADS/AAA.jmp");
// dt = Current Data Table();
dt = New Table("AAA(1)",
Add Rows(12),
Compress File When Saved(1),
New Column("obj", Character(16), "Nominal", Set Values({"A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "C", "C"})),
New Column("T", Character(4), "Ordinal", Set Values({"3052", "3061", "3082", "3940", "4012", "5010", "2890", "4060", "3061", "3061", "3081", "5010", "3061"})),
New Column("OPE", Numeric, "Continuous", Format("Best", 12), Set Values([12, 20, 32, 44, 56, 125, 210, 54, 60, 60, 80, 45, 50])),
New Column("X__3", Character(4), "Nominal", Set Values({"rien", "rien", "incl", "ret", "ret", "rien", "incl", "incl", "ret", "ret", "incl", "ret", "rien"})),
New Column("SOMME DEFAUT", Numeric, "Continuous", Format("Best", 12), Set Values([0, 0, 1, 2, 1, 0, 2, 1, 2, 2, 1, 1, 0])),
New Column("op", Character(12), "Nominal", Set Values({"40", "32", "55", "212", "510", "180", "2100", "2240", "2100", "2100", "500", "", ""}))
);
dt << New Column("bilan", Character, Nominal);
Summarize(dt, unique_objects = by(:obj));
m_obs = dt[0, "obj"];
For Each({unique_object}, unique_objects,
object_rows = Loc(m_obs, unique_object);
input_loc = Loc(dt[object_rows, "T"], "3061");
If(N Items(input_loc) == 0,
continue();
//Throw("3061 not found");
, N Items(input_loc) > 0,
input_loc = input_loc[1];
);
opes = dt[object_rows, "OPE"];
valid_ope_idx = Loc(opes > opes[input_loc]);
If(N Items(valid_ope_idx) < 1,
result_str = ".";
,
values = dt[object_rows[valid_ope_idx], "SOMME DEFAUT"];
ops = dt[object_rows[valid_ope_idx[Loc(values)]], "op"];
result_str = "ko - " || Concat Items(ops, " / ko - ");
);
dt[object_rows[input_loc], "bilan"] = result_str;
);