Filtern einer Datentabelle mit einer benutzerdefinierten FilteranwendungHallo zusammen,
Ich erstelle eine Anwendung/ein Dashboard mit einer Reihe von Berichten darin. Am Ende möchte ich den Benutzern die Möglichkeit geben, eine „Abfrage“ der Hauptdatentabelle durchzuführen und diese zu speichern, falls sie sie später benötigen.
Derzeit habe ich eine Schaltfläche, die ein weiteres Fenster öffnet und den Benutzer auffordert, Filterspalten (aus einer vorab ausgewählten Liste) auszuwählen.
Sobald sie diese ausgewählt haben, drücken sie eine weitere Schaltfläche, die dann ein Listenfeld für jede der Filterspalten mit allen verfügbaren unterschiedlichen Werten erstellen sollte. Meiner Ansicht nach wählt der Benutzer von hier aus in jedem Listenfeld die Werte aus, für die die Filterung erfolgen soll, und drückt dann eine letzte Schaltfläche, um diese Werte zu speichern. Anschließend wird eine Filter-/Where-Klausel erstellt, die die Hauptdatentabelle unterteilt und für sie an einem bekannten Ort speichert.
Ich glaube, ich bin auf halbem Weg. Ich bekomme das erste Fenster und die Filterspaltenauswahl zum Laufen. Dann kann ich die Werte in Listenfeldern anzeigen, aber ich kann nicht die richtige Schaltfläche erstellen, um diese ausgewählten Werte zu speichern. Außerdem glaube ich, dass ich auf das Problem stoße, nicht zu wissen, wie viele Filterspalten die Benutzer erstellen werden, deshalb muss ich einen Ausdruck haben, um eine unbekannte Anzahl von Spalten zu definieren. Ich habe einige Beispiele mit Eval(Parse(Eval Into-Anweisungen gesehen, aber habe es noch nicht verstanden.
Für jede Hilfe bin ich dankbar. Vielleicht gibt es einen viel einfacheren Weg, das zu tun.
Hier ist ein Teil des Codes, den ich bisher habe
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>Automatisierung und Skripting</LINGO-LABEL><LINGO-LABEL>Datenexploration und -visualisierung</LINGO-LABEL><LINGO-LABEL>Windows</LINGO-LABEL></LINGO-LABS>Betreff: Filtern einer Datentabelle mit einer benutzerdefinierten FilteranwendungHaben Sie darüber nachgedacht, einen Datenfilter basierend auf den vom Benutzer ausgewählten Spalten zu erstellen?
Betreff: Filtern einer Datentabelle mit einer benutzerdefinierten FilteranwendungJa, aber je weniger Unordnung, desto besser, da nicht viele Benutzer neu bei JMP sind und ich ihnen die Visualisierung so einfach wie möglich machen möchte und sie ihre gefilterten Daten mit einem Knopfdruck abrufen können.
Es könnte auch mit dem lokalen Filter funktionieren
Betreff: Filtern einer Datentabelle mit einer benutzerdefinierten FilteranwendungIch würde einen Datenfilter erstellen (den Sie bei Bedarf bereinigen können), aber hier ist eine Möglichkeit, Listenfelder zu verwenden
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);
)
);
)
)
);
Betreff: Filtern einer Datentabelle mit einer benutzerdefinierten FilteranwendungDanke, das funktioniert wie beabsichtigt.
Beim nächsten Schritt stecke ich jedoch in einer Sackgasse.
Um den Datenfilter zu erstellen, habe ich darüber nachgedacht, das zugehörige Array direkt mit den Benutzerauswahlen zu platzieren, aber das funktioniert nicht.
Dann habe ich darüber nachgedacht, das in den Datenfilter aufzuteilen und Expr und andere Zeichenfolgenbefehle zu verwenden, um es so aufzubauen, dass es genauso aussieht, als hätte ich das rote Dreieck verwendet, nachdem ich einen interaktiven Datenfilter erstellt habe. Aber ich glaube, ich mache irgendwo einen Syntaxfehler.
Dies ist mein Code aus Ihrem BigClass-Beispiel
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 ))));
Gibt es jedoch eine direktere und intuitivere Möglichkeit, dies zu tun?
Betreff: Filtern einer Datentabelle mit einer benutzerdefinierten FilteranwendungWenn Sie die Auswahl bereits im assoziativen Array haben, benötigen Sie den Datenfilter dann noch? Mein früherer Vorschlag zur Verwendung des Datenfilters bestand darin, die Erstellung der „zusätzlichen“ Listenfelder zur Auswahl von Zeilenwerten zu vermeiden.
Betreff: Filtern einer Datentabelle mit einer benutzerdefinierten FilteranwendungSobald ich die Auswahl (sowohl die Spaltennamen als auch die Werte) habe, möchte ich die Daten unterteilen und nur das extrahieren, was durch die Benutzerauswahl gefiltert wird. Dafür bräuchte ich einen Datenfilter, oder?
Betreff: Filtern einer Datentabelle mit einer benutzerdefinierten FilteranwendungJe nachdem, was Sie mit „extrahieren“ meinen, können Sie << Zeilen abrufen, wobei + Teilmenge oder << Auswählen, wobei + Teilmenge oder << Auswählen, wobei + Ausblenden und Ausschließen verwenden.
Betreff: Filtern einer Datentabelle mit einer benutzerdefinierten FilteranwendungJa, genau, ich wollte einige dieser Methoden verwenden, war mir aber nicht sicher, wie ich das machen sollte, wenn ich nicht weiß, welche Spalte und Werte der Benutzer ausgewählt hat. Die Auswahlen befinden sich jetzt in einem assoziativen Array, aber sie in eine Where-Klausel zu übersetzen, war für mich die Schwierigkeit. Deshalb habe ich versucht, die Where-Klausel mit dem zuvor gezeigten Codeblock zu konstruieren, aber ich habe es nicht hinbekommen. Vielleicht gibt es einen einfacheren Weg, mit dem assoziativen Array zu arbeiten, um die Where-Klausel zu konstruieren
Betreff: Filtern einer Datentabelle mit einer benutzerdefinierten FilteranwendungDie direkte Verwendung eines Datenfilters wäre die einfachste Möglichkeit, aber das haben wir bereits ausgeschlossen. Sollen die Benutzerauswahlen per UND oder per ODER kombiniert werden?
Betreff: Filtern einer Datentabelle mit einer benutzerdefinierten FilteranwendungHier sind einige Optionen
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);