こんにちは、みんな、
データ テーブル内の対応する列のすべての値を含む複数のリスト ボックスを含むダイアログ ウィンドウを作成しようとしています。 リストのいずれかで1つ以上のアイテムを選択すると、残りのリストのアイテムがその選択に従ってフィルタリングされます。 以下で説明したことを実装しましたが、ここに問題があります。以下のようにリストサブセットインデックスを整数でハードコーディングする代わりに、ループでダイアログウィンドウにデータを入力すると、関数は 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 のトレードオフ:
- parse は、エディターで構文が強調表示されていない文字列を作成しますが、コードを維持する次の人はおそらくそれを理解するでしょう。 あなたの例では、何百もの連結がある可能性がある場合、ループ内に eval-parse を配置する可能性があります。
- evalexpr はおそらく parse よりも高速ですが、小さな例では実際の違いはありません。 連結によって 100 万文字の文字列を構築していた場合、これは重要なことかもしれません。 Evalexpr には、次のメンテナに何をしているのかを伝えるコメントが必要です。
より強力で、説明や維持が難しい式を操作する方法は他にもあります。この例では、これらのいずれかが妥当だと思います。 (arg、narg、head、insertinto、substituteinto、... 毎回これらを再学習する必要があります。)
私にできることはこれだけですが、それはただのようです... ばかげていると思います...
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>これを試してくれてありがとう! 残念ながら、過去に直面したのと同じ問題が発生します。リストで選択を行うと、filterSelected 関数が現在の値 if i (つまり 4) で呼び出され、Subscript Range エラーが発生します。

これを試して
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 ループ内に配置しました。
編集:そしてうまく提示された質問!