Filtrer une table de données avec une application de filtrage personnaliséeBonjour à tous,
Je suis en train de créer une application/un tableau de bord avec un ensemble de rapports à l'intérieur. À la fin, j'aimerais donner aux utilisateurs la possibilité de faire une « requête » sur la table de données principale et de la sauvegarder s'ils en ont besoin plus tard.
Actuellement, j'ai un bouton qui ouvre une autre fenêtre et invite l'utilisateur à sélectionner des colonnes de filtrage (à partir d'une liste présélectionnée).
Une fois qu'ils les ont sélectionnés, ils appuient sur un autre bouton qui devrait alors créer une liste déroulante pour chacune des colonnes de filtrage avec toutes les valeurs distinctes disponibles. Je pense qu'à partir de là, l'utilisateur sélectionnerait les valeurs pour lesquelles il souhaite que le filtrage s'effectue dans chaque liste déroulante, puis appuierait sur un dernier bouton pour enregistrer ces valeurs, puis une clause filter/where serait créée qui sous-ensembleerait la table de données principale et l'enregistrerait pour lui dans un emplacement connu.
Je crois que j'en suis à mi-chemin. J'arrive à faire fonctionner la première fenêtre et la sélection de la colonne de filtre. Ensuite, je peux afficher les valeurs dans les zones de liste, mais je ne parviens pas à créer le bon bouton pour enregistrer ces valeurs sélectionnées. De plus, je crois que je rencontre le problème de ne pas savoir combien de colonnes de filtre les utilisateurs vont créer, je dois donc avoir une expression pour définir un nombre inconnu de colonnes. J'ai vu quelques exemples avec des instructions Eval(Parse(Eval Into mais je ne l'ai pas encore compris.
Toute aide sera appréciée. Il existe peut-être une manière beaucoup plus simple de procéder.
Voici une partie du code que j'ai jusqu'à présent
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>Automatisation et scripts</LINGO-LABEL><LINGO-LABEL>Exploration et visualisation des données</LINGO-LABEL><LINGO-LABEL>Fenêtres</LINGO-LABEL></LINGO-LABS>Ré: Filtrer une table de données avec une application de filtrage personnaliséeAvez-vous envisagé de créer un filtre de données basé sur les colonnes sélectionnées par l'utilisateur ?
Ré: Filtrer une table de données avec une application de filtrage personnaliséeOui, mais moins il y a d'encombrement, mieux c'est, car peu d'utilisateurs sont nouveaux sur JMP et je veux leur permettre de visualiser le plus facilement possible et d'obtenir leurs données filtrées en appuyant sur un bouton.
Le faire avec le filtre local pourrait également fonctionner
Ré: Filtrer une table de données avec une application de filtrage personnaliséeJe créerais un filtre de données (que vous pouvez nettoyer si nécessaire), mais voici une option d'utilisation des zones de liste
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);
)
);
)
)
);
Ré: Filtrer une table de données avec une application de filtrage personnaliséeMerci, cela fonctionne comme je le souhaitais.
Cependant, l'étape suivante me semble un peu dans l'impasse.
Pour créer le filtre de données, je pensais placer directement le tableau associé avec les sélections de l'utilisateur, mais cela ne fonctionne pas.
Ensuite, j'ai pensé à décomposer cela dans le filtre de données et à utiliser Expr et d'autres commandes de chaîne pour le construire pour ressembler exactement à si j'avais utilisé le triangle rouge après avoir créé un filtre de données interactif, mais je pense que je me trompe quelque part sur la syntaxe.
Voici mon code de votre exemple 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 ))));
Cependant, existe-t-il un moyen plus direct et intuitif de procéder ?
Ré: Filtrer une table de données avec une application de filtrage personnaliséeSi vous avez déjà les sélections dans un tableau associatif, avez-vous encore besoin du filtre de données ? Ma suggestion précédente d'utiliser le filtre de données était d'éviter la création de zones de liste « supplémentaires » pour sélectionner les valeurs des lignes.
Ré: Filtrer une table de données avec une application de filtrage personnaliséeUne fois que j'ai les sélections (à la fois les noms et les valeurs des colonnes), je voulais sous-ensemble les données et extraire uniquement ce qui est filtré par les sélections de l'utilisateur. Pour cela, j'aurais besoin d'un filtre de données, n'est-ce pas ?
Ré: Filtrer une table de données avec une application de filtrage personnaliséeSelon ce que vous entendez par « extraire », vous pouvez utiliser << Obtenir les lignes où + Sous-ensemble ou << Sélectionner où + Sous-ensemble ou << Sélectionner où + Masquer et exclure
Ré: Filtrer une table de données avec une application de filtrage personnaliséeOui, exactement, je voulais utiliser certaines de ces méthodes, mais je ne savais pas comment procéder lorsque je ne savais pas quelle colonne et quelles valeurs l'utilisateur avait sélectionnées. Les sélections sont désormais dans un tableau associatif, mais leur traduction dans une clause Where était la difficulté pour moi. C'est pourquoi j'ai essayé de construire la clause Where avec le morceau de code précédent que j'ai montré, mais je n'y suis pas parvenu. Il existe peut-être un moyen plus simple de travailler avec le tableau associatif pour construire la clause where
Ré: Filtrer une table de données avec une application de filtrage personnaliséeL'utilisation directe d'un filtre de données serait l'option la plus simple, mais nous l'avons déjà exclue. Les sélections de l'utilisateur doivent-elles être combinées par ET ou par OU ?
Ré: Filtrer une table de données avec une application de filtrage personnaliséeVoici quelques options
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);