Ansicht mit mehreren dynamischen Mehrfachauswahlen filtern
Einige hier hatten schon danach gefragt, wie man ein Ansichtstabelle mit Mehrfachauswahl filtern kann. Ich habe hier ein bisschen recherchiert und Eure Beiträge in den folgenden Code eingebaut.
Das Problem: Eine Ansichtstabelle soll gefiltert werden und zwar nach mehreren ODER Kriterien. Die "ODER" Kriterien stehen in einer/mehreren dynamischen Mehrfachauswahl(en).
Beispiel:
Die Tabelle "Kostenelemente" enthält die Felder "zu Gesellschaft", "Genauigkeit" und "Wiederholung". (Sie beschreiben die Genauigkeit einer Kostenschätzung (gering, mittel, hoch), die Häufigkeit der Wiederholung (monatlich, jährlich etc) und die Gesellschaft, die die Kosten tragen muss).
Diese Felder werden aus Lookup-Tabellen gefüllt und es kann pro Kostenelement immer nur eine Gesellschaft, Genauigkeit und Wiederholung ausgewählt werden. Ich beziehe mich dabei immer nur auf die Satzummer der LookupTabelle, nicht den Text, damit eine einfache Änderung am text nicht den ganzen Code kaputt macht und das Ergebnis eindeutig ist.
In der Ansicht möchte ich nun die Kostenelemente gefiltert anzeigen. Dafür kommen drei dynamische Mehrfachauswahlen ins Spiel, die die selben LookUp Tabellen verwenden. Die Kriterien sollen sein: 0..n Gesellschaften (ODER!), UND 0..n Wiederholungen (ODER) UND 0..n Genauigkeiten (ODER).
Die DMAF verwenden dazu natürlich die selben LookUp Tabellen, die auch im Kostenelement verwendet werden, damit es einen Match auf Basis der Datensatznummer geben kann.
Der Code dazu:
"Dieser Code steht im Element 'Ansicht'";
"Die dynanimische Mehrfachauswahl 'Filter Gesellschaften' auslesen und als Array mm zwischenspeichern";
let mm := numbers('Filter Gesellschaften');
"Die Funktion liest nun alle Kostenelemente (x..) und vergleicht in jedem einzelnen, ob ein Wert aus dem Array mm enthalten ist";
let myView := for x in select Kostenelemente do
for y in mm do
if x.'zu Gesellschaft' = y then
x
end
end
end;
"Das Ergbebnis wird ein weiteres mal gefiltert, mit dem gleichen Prozess wie oben";
let ww := numbers('Filter Wiederholung');
let myView := for x in myView do
for y in ww do
if x.Wiederholung = y then x end
end
end;
let zz := numbers('Filter Genauigkeit');
let myView := for x in myView do
for y in zz do
if x.Genauigkeit = y then x end
end
end;
"Und zum Schluss ausgeben.."
myView
Im obersten Block werden die Datensätze aus "Kostentabelle" herausgefiltert, die eine der ausgewählten Gesellschaften enthalten. Das Ergebnis steht dann im Array "MyView".
Im zweiten Block wird das Array "MyView" ein weiteres Mal gefiltert, diesmal auf das zweite Kriterium, hier können auch wieder mehrere ausgewählt werden.
Im Dritten Block wird das Array ein weiteres Mal gefiltert.... dann ausgegeben.
Wegen der insgesamt 3x2 geschachtelten Schleifen ist das für Ninox Verhältnisse "relativ" langsam. Mit 10 Gesellschaften, 2000 Kostenelementen, 12 Wiederholungen und 8 Genauigkeiten komme ich auf eine Antwortzeit von gefühlt einer 1/10 Sekunde ;-)
Vielleicht kann ja mal jemand den Code auf Geschwindigkeit optimieren?
Hoffe es hilft... wollte mal ein paar Learnings aus dem Forum zurückgeben
Gruss ZitronenKiller
2 Antworten
-
Zur Geschwindigkeitsoptimierung:
Probiere mal die Abfrage am Server durchzuführen und nicht am Endgerät:
do as server
...
Code
...
end
Wenn Du Glück hast, erhöht das die Geschwindigkeit dramatisch.
-
Eigentlich würde ich den Artikel gerne wieder löschen...
Mein Code Beispiel oben funktioniert nur eingeschränkt: wenn man versucht, in der View den Datensatz zu öffnen, kommt immer ein leerer Datensatz.
Aber dafür habe ich von einem peer ein drastische Code Verbesserung bekommen, die nun auch superschnell ist.:
Also, Ansicht filtern mit mehreren dynamischen Mehrfachauswahlen- In einer Zeile ;-) (Danke an Thomas)
let me := this; let gesell := concat(numbers('Filter Gesellschaften')); let wdh := concat(numbers('Filter Wiederholung')); let genau := concat(numbers('Filter Genauigkeit')); select Kostenelemente where contains(gesell, text(number('zu Gesellschaft'))) and contains(wdh, text(number(Wiederholung))) and contains(genau, text(number(Genauigkeit)));
Bei dieser Variante müssen in den DMFAWs auch "alle" angewählt sein, damit die Ansicht Daten enthält.
Wir arbeiten gerade an der umgekehrten Variante, die vielleicht etwas intuitiver ist, dabei ist die Ansicht zunächst vollständig gefüllt und wird dann auf Basis der Auswahlen soweit gefiltert, bis sie nur noch das enthält, was wirklich gebraucht wird. Fortsetzung folgt.
Content aside
- vor 2 JahrenZuletzt aktiv
- 2Antworten
- 189Ansichten
-
2
Folge bereits