안녕하세요 여러분,
각 목록 상자에는 데이터 테이블의 해당 열 값이 모두 포함되어 있는 대화 상자 창을 만들려고 합니다. 목록에서 하나 이상의 항목을 선택하면 나머지 목록의 항목이 해당 선택에 따라 필터링되기를 원합니다. 아래에 방금 설명한 내용을 구현했지만 여기에 문제가 있습니다. 아래와 같이 정수로 목록 하위 집합 인덱스를 하드 코딩하는 대신 루프에서 대화 상자 창을 채우면 함수는 호출 당시의 i 값으로 호출됩니다. 루프에서 목록 상자가 생성될 때 사용된 값 대신 실행됩니다. 스크립팅 가이드를 읽고 Eval( Eval Expr( Expr())) 및 Eval Substitute( Expr(), Expr()))을 포함한 여러 옵션을 시도했지만 제대로 작동하지 않습니다. 이제 전체 표현식을 루프의 긴 문자열로 작성하고 Eval(Parse())'하는 작업을 수행하고 있지만 이는 어리석은 것 같습니다. 누군가 여기에서 적절한 구문을 사용하여 나를 도와줄 수 있습니까?
감사해요,
요한
Names Default To Here( 1 );
If( !Namespace Exists( "fq" ),
New Namespace(
"fq"
)
);
dt = New Table( "Sample data",
Add Rows( 9 ),
New Column( "id",
Character,
"Nominal",
Set Values( {"a", "a", "a", "b", "b", "b", "c", "c", "c"} )
),
New Column( "value",
Character,
"Nominal",
Set Values( {"A", "B", "C", "D", "E", "F", "G", "H", "I"} )
),
New Column( "val2",
Character,
"Nominal",
Set Values( {"one", "two", "three", "one", "two", "three","one", "two", "three"} )
)
);
filterSelected = Function( {dt, values, index},
/*
Sorts displayed values in all list boxes based on selection
*/
columns = fq:filterColumns;
filters = fq:filters;
selectedColum = Remove From( columns, index )[1];
selctedFilter = Remove From( filters, index )[1];
rows = dt << Get rows where( Contains( values, as Column( dt, selectedColum ) ) );
// If nothing is selcted, all values should be chosen
If(Length(values)==0,
rows = dt << get rows where(!Ismissing(As Column(dt, selectedColum)))
);
// Set list items according to selection
Local( {j = 1},
For( j = 1, j <= N Items( filters ), j++,
filters[j] << Set items( Column( dt, columns[j] )[rows] )
)
);
);
getSelection = Function( {},
Local( {j =1},
For( j=1, j <= N Items(fq:filters), j++,
print(fq:filterColumns[j], fq:filters[j] << get items());
);
);
);
nestedFilters = Function( {filtercolumns},
fq:filtercolumns = filtercolumns;
dialog = New Window( "Fetch rows matching:",
Show Menu( 0 ),
show toolbars( 0 ),
Border Box( Top( 20 ), Bottom( 20 ), Left( 10 ), Right( 10 ),
V List Box(
Align( right ),
filter_boxes = V List Box(),
H List Box(
ok_button = Button Box( "OK" ),
cancel_button = Button Box( "Cancel", dialog << close window )
)
)
),
ok_button << Set function(
getSelection();
dialog << close window;
)
);
fq:filters = {};
fq:all_rows = {};
//for(i=1, i<=N Items(filtercolumns), i++,
filter_boxes << append( Text Box( fq:filtercolumns[1], <<SET font="" style=""></SET>다시 한 번 감사드립니다. 약간 해킹처럼 보이더라도 eval(parse())를 계속 사용할 것 같습니다. 하지만 어쨌든 귀하의 통찰력에 감사드립니다!
i==4 값이 존재하는 경우 expr()에 래핑되지 않은 i가 있어야 합니다.
Parse와 EvalExpr의 절충점:
- 구문 분석은 편집기에서 구문이 강조 표시되지 않은 문자열을 만들지 만 코드를 유지 관리하는 다음 사람은 아마도 이를 이해할 것입니다. 귀하의 예에서 100개의 연결이 있을 수 있다면 루프 내부에 eval-parse를 넣을 수 있습니다.
- evalexpr은 아마도 구문 분석보다 빠르지만 작은 예에서는 실제 차이가 없습니다. 연결을 통해 백만 개의 문자열을 작성하는 경우 이것이 중요할 수 있습니다. Evaexpr에는 다음 관리자에게 자신이 수행 중인 작업을 알려주는 설명이 필요합니다.
더 강력하고 설명하고 유지하기 어려운 표현식을 조작하는 다른 접근 방식이 있습니다. 이 예에서는 둘 중 하나가 합리적이라고 생각합니다. (arg, narg, 헤드, 삽입, 대체, ... 매번 다시 배워야 해요.)
내가 할 수 있는 일은 이것뿐인데, 그냥 그런 것 같아... 어리석은 것 같아요 ...
expression = "";
for( i = 1, i <= N Items( fq:filtercolumns ), i++,
expression = expression ||
"filter_boxes << append( Text Box( fq:filtercolumns[" || char(i) || "], <<SET font="" style=""></SET>시도해 주셔서 감사합니다! 불행하게도 과거에 직면했던 것과 같은 문제가 발생합니다. 목록에서 항목을 선택할 때 i(예: 4)인 경우 현재 값으로 filterSelected 함수가 호출되어 아래 첨자 범위 오류가 발생합니다.

이 시도
for( i = 1, i <= N Items( filtercolumns ), i++,
eval(
evalexpr(
filter_boxes << append( Text Box( fq:filtercolumns[Expr( i )], <<SET font="" style=""></SET>나는 "1" 케이스를 사용했고, 1을 expr(i)로 변경하고, 그것을 eval/evalexpr 내부, i 루프 내부에 넣었습니다.
편집 : 그리고 멋지게 제시된 질문입니다!