カスタム フィルタリング アプリケーションを使用してデータテーブルをフィルタリングするみなさんこんにちは
多数のレポートを内蔵したアプリケーション/ダッシュボードを構築しています。最後に、メイン データ テーブルの「クエリ」を作成し、後で使用する場合に備えて保存するオプションをユーザーに提供したいと考えています。
現在、別のウィンドウを開いて、ユーザーにフィルタリング列を(事前に選択されたリストから)選択するように求めるボタンがあります。
それらを選択すると、別のボタンが押され、各フィルタリング列に使用可能なすべての個別値を含むリスト ボックスが作成されます。私の考えでは、ここからユーザーは各リスト ボックスでフィルタリングを実行する値を選択し、最後のボタンを押してそれらの値を保存し、その後、メイン データ テーブルをサブセット化するフィルター/WHERE 句が構築され、既知の場所に保存されます。
半分くらいはできたと思います。最初のウィンドウとフィルター列の選択が機能するようになりました。その後、リスト ボックスに値を表示できますが、選択した値を保存するための適切なボタンを作成できません。また、ユーザーが作成するフィルター列の数がわからないという問題が発生していると思います。そのため、不明な数の列を定義する式が必要です。Eval(Parse(Eval Into ステートメントの例をいくつか見ましたが、まだ理解できていません。
どのような助けでもありがたいです。おそらく、もっと合理的な方法があるでしょう。
ここに私がこれまでに書いたコードの一部を示します
filter_col_append_expr = Expr(
lub1 << Append(List Box(column(dt1,Char(col_filter[count_i])) <<GETASMATRIX></GETASMATRIX>
//The button which will run the whole thing is here. Some code is ommited
Panel Box("Database Query", Button Box("Query",query_expr;query_window << Append(bb3 = Button Box("Select Filter Values",query_values = lub1<<GET selected=""></GET><BR /><LINGO-LABS id="lingo-labs-828278" slang="en-US" mode="CREATE"><LINGO-LABEL>自動化とスクリプト</LINGO-LABEL><LINGO-LABEL>データの探索と視覚化</LINGO-LABEL><LINGO-LABEL>ウィンドウズ</LINGO-LABEL></LINGO-LABS>Re: カスタム フィルタリング アプリケーションを使用してデータテーブルをフィルタリングするユーザーが選択した列に基づいてデータ フィルターを構築することを検討しましたか?
Re: カスタム フィルタリング アプリケーションを使用してデータテーブルをフィルタリングするはい、しかし、JMP を初めて使用するユーザーはあまりいないので、混乱が少ないほど良いです。ユーザーが視覚化をできるだけ簡単にし、ボタンを押すだけでフィルタリングされたデータを取得できるようにしたいと考えています。
ローカルフィルターで実行することもできます
Re: カスタム フィルタリング アプリケーションを使用してデータテーブルをフィルタリングする私はデータフィルターを構築します(必要に応じてクリーンアップできます)が、リストボックスを使用するオプションが1つあります。
Names Default To Here(1);
dt = open("$SAMPLE_DATA/Big Class.jmp");
options = dt << Get Column Names("String");
filter_col_append_expr = Expr(
Summarize(dt, colvals = By(Eval(selection))); // Note that Summarize this will change numeric values to strings
lub1 << Append(List Box(colvals));
);
query_expr = Expr(
query_window = New Window("Database Query",
Spacer Box(size(1, 5)),
vlb3 = V List Box(
Text Box("Select All Filter Columns"),
H List Box(
Spacer Box(size(1, 5)),
lb3 = List Box(
options,
max selected(8)
)
),
Spacer Box(size(1, 10)),
Button Box("Select Filter Columns",
cols = lb3 << get selected;
Try(lub1 << Delete Box());
lub_collector << Append(lub1 = Lineup Box(N Col(4)));
For Each({selection}, cols,
filter_col_append_expr
);
),
lub_collector = V List Box();
)
)
);
//The button which will run the whole thing is here. Some code is ommited
nw = New Window("",
Panel Box("Database Query",
Button Box("Query",
query_expr;
query_window << Append(
bb3 = Button Box("Select Filter Values",
vals = (lub1 << XPath("//ListBoxBox")) << get selected;
user_selections = Associative Array(cols, vals);
show(user_selections);
)
);
)
)
);
Re: カスタム フィルタリング アプリケーションを使用してデータテーブルをフィルタリングするありがとうございます。意図したとおりに動作しました。
しかし、次のステップについては少し行き詰まっています。
データ フィルターを構築するために、ユーザーの選択内容と関連配列を直接配置することを考えていましたが、うまくいきませんでした。
次に、データ フィルターに入る部分を分割し、Expr やその他の文字列コマンドを使用して、インタラクティブ データ フィルターを作成した後に赤い三角形を使用した場合とまったく同じように構築することを考えましたが、構文のどこかが間違っていると思います。
これはBigClassの例からの私のコードです
where_clause_list = {};
where_clause = "";
keys = user_selections << getkeys;
values = user_selections << getvalues;
For ( i=1, i<=NItems(keys), i++,
// Inner loop iterating over items for each category
For Each( {value}, values[i],
// Action for each category-item pair
(where_clause = where_clause || ":"||keys[i] || " ==" || " " || Char(value) || " &"|| " ");
InsertInto(where_clause_list, where_clause);
where_clause = "";));
where_clause="";
For Each({where},where_clause_list,where_clause=where_clause||where);
where_clause = Left(where_clause,Length(where_clause) -3);
Show(where_clause_list);
Show(where_clause);
where_expr = Expr(where_clause);
key_clause="";
For Each({key},keys,key_clause=key_clause||"Ascolumn("||key||")"||" ,");
key_clause = Left(key_clause,Length(key_clause) -2);
keys_expr=Expr(key_clause);
Show(key_clause);
dt << Data Filter(Add Filter(columns(key_expr),Where(where_expr),
Mode( Select( 0 ), Show( 1 ), Include( 1 ))));
しかし、これをより直接的かつ直感的に行う方法はあるのでしょうか?
Re: カスタム フィルタリング アプリケーションを使用してデータテーブルをフィルタリングする連想配列に既に選択内容がある場合、データ フィルターはもう必要でしょうか? 以前、データ フィルターの使用を提案したのは、行の値を選択するための「余分な」リスト ボックスの作成を避けるためでした。
Re: カスタム フィルタリング アプリケーションを使用してデータテーブルをフィルタリングする選択内容 (列名と値の両方) を取得したら、データをサブセット化し、ユーザーの選択内容によってフィルターされたものだけを抽出したいと考えました。そのためには、何らかのデータ フィルターが必要でしょうか?
Re: カスタム フィルタリング アプリケーションを使用してデータテーブルをフィルタリングする「抽出」の意味に応じて、<< Get Rows Where + Subset または << Select Where + Subset または << Select Where + Hide and Exclude を使用できます。
Re: カスタム フィルタリング アプリケーションを使用してデータテーブルをフィルタリングするはい、まさにその通りです。私はそれらのメソッドのいくつかを使いたかったのですが、ユーザーがどの列と値を選択したかがわからないときにどうすればよいかわかりませんでした。選択は現在連想配列にありますが、それを Where 句に変換するのが難しかったのです。そのため、以前示したコードで Where 句を作成しようとしましたが、うまくいきませんでした。連想配列を使用して Where 句を作成するより簡単な方法があるかもしれません。
Re: カスタム フィルタリング アプリケーションを使用してデータテーブルをフィルタリングするデータ フィルターを直接使用するのが、最も簡単なオプションですが、すでに除外されています。ユーザー選択は AND で結合する必要がありますか、それとも OR で結合する必要がありますか?
Re: カスタム フィルタリング アプリケーションを使用してデータテーブルをフィルタリングするいくつかのオプションがあります
Names Default To Here(1);
dt = open("$SAMPLE_DATA/Big Class.jmp");
// Build using Select Where (simplest)
// Note that we convert to Char due to using Summary and because we can have numeric values
// This could (and should) be handled earlier in some other method
user_selections = ["age" => {"13", "14"}, "sex" => {"F"}];
For Each({{col, values}, idx}, user_selections,
If(idx == 1,
dt << Select Where(Contains(values, Char(Column(dt, col)[])));
);
dt << Select Where(Contains(values, Char(Column(dt, col)[])), Current Selection("restrict")); // AND
// dt << Select Where(Contains(values, Char(Column(dt, col)[])), Current Selection("extend")); // OR
);
show(dt << get selected rows);
wait(1); // demo purposes
dt << Clear Select;
// A bit more complicated is to build expression and use that
user_selections = ["age" => {13, 14}, "sex" => {"F"}]; // simplified to use numeric value for numeric column
filter_expr = Expr(And()); // optionally use Or()
For Each({{col, values}, idx}, user_selections,
cur_expr = Substitute(
Expr(Contains(_list_, _column_)),
Expr(_list_), values,
Expr(_column_), Name Expr(AsColumn(dt, col))
);
Insert Into(filter_expr, Name Expr(cur_expr));
);
// Show(Name Expr(filter_expr));
my_rows = dt << Get Rows Where(filter_expr);
show(my_rows);