Eigener Funktion als Parameter ein Array übergeben
Hallo,
ich bin aktuell dabei in meinen Ansichten erweiterte Suchparameter ("+" : und, "/": oder, "-": nicht) einzubauen. Mein nächster Schritt wäre jetzt Klammerung noch hinzuzufügen. Dabei wollte ich dies zunächst Rekursiv lösen bis mir aufgefallen ist, dass Ninox keine rekursiven Funktionen unterstützt.
Daher jetzt die Frage, gibt es einen Weg wie ich einer function ein Array übergeben kann?
Vielen Dank schon mal
6 Antworten
-
Hallo, man könnte die Array-Items bspw. per concat() als String an die Funktion übergeben und dort mit split() wieder in ein Array umwandeln.
Beispiel:
function processArray(arrayText : text,itemNo : number) do let myItems := split(arrayText, ","); let myItem := item(myItems, itemNo); alert(myItem) end; let myArray := ["A", "B", "C", "D"]; let myAText := concat(myArray); let myNumber := 2; processArray(myAText, myNumber)
Ergebnis wäre ein alert()-Fenster, das den Wert "C" zurückgibt.
-
Man kann es mit formatJSON(Array) übergeben und in der Funktion mit parseJSON(TextArray) wieder zurück spielen.
Bsp:
function fxTest(xArr : text) do
let vArr := parseJSON(xArr);
first(xArr)
endFunktionsaufruf im Script:
let vResponse := fxTest(formatJSON((select Table).Name)) -
Uwes Version ist natürlich noch eleganter.
-
Vielen Dank schon mal für die Antworten.
Mein Anwendungsfall ist dass ich eine Ansicht über Material habe und über ein Suchfeld dieses Material filtern möchte.
Und die Eingabe "(Apple / Samsung) + Handy" halt alle Datensätze welche in Oberbegriff oder Hersteller "Samsung" oder "Apple" stehen hat und in Oberbegriff oder Hersteller "Handy".
Dabei wäre jetzt meine Idee dass ich den Teilstring "(Apple / Samsung)" zuerst auswerte und alle Records der Tabelle Material zwischen speichere. Danach dann die Ergebnisse für "Handy" und dann diese beiden je nach Operator per Und/Oder zusammenfüge.
Bei der JSON Lösung von Uwe habe ich das Problem, dass dies als "Any" von Ninox erkannt wird und ich dies nicht in einer Ansicht darstellen kann. Gibt es einen Weg, dass ich das dann als "Material" casten kann?
Bei der concat Lösung von planox, dachte ich, dass ich mir einfach immer die Nr der records speichere und am Ende dann mein Material filtere.
let concatMaterialNr := concat(Material.Nr); let arrNr := split(concatMaterialNr, ", "); count(Material[contains(arrNr, number(this.Nr))])
Aber mit dem Code erhalte ich immer 0 Datensätze.
Ich habe es für eine Klammerung schon programmiert, aber würde eigentlich gern unbegrenzt viele Klammern einbauen.
let suche := Suche; function getProjektMaterial(projekt : 'Filterung Ansicht',suchText : text) do let material := projekt.Material; if contains(suchText, " + ") then let splitSuche := split(suchText, " + "); for x in splitSuche do material := material[Hersteller like x or Oberbegriff like x] end else if contains(suchText, " / ") then let splitSuche := split(suchText, " / "); let item1 := item(splitSuche, 0); let material2 := material[Hersteller like item1 or Oberbegriff like item1]; for x in splitSuche[this != item1] do let material3 := array(material2, material[Hersteller like x or Oberbegriff like x]); material2 := material[contains(material3.Nr, this.Nr)] end; material := material2 else if contains(suchText, " - ") then let splitSuche := split(suchText, " - "); let item1 := item(splitSuche, 0); material := material[Hersteller like item1 or Oberbegriff like item1]; for x in splitSuche[this != item1] do material := material[not Hersteller like x and not Oberbegriff like x] end else material := material[Hersteller like suchText or Oberbegriff like suchText] end end end; material end; function fusionMaterial(project : 'Filterung Ansicht',filter1 : text,filter2 : text,operator : text) do let material1 := getProjektMaterial(project, filter1); let material2 := getProjektMaterial(project, filter2); switch operator do case "and": (material1 := material1[contains(material2.Nr, this.Nr)]) case "or": (material1 := project.Material[contains(material1.Nr, this.Nr) or contains(material2, this.Nr)]) case "except": (material1 := project.Material[contains(material1.Nr, this.Nr) and contains(material2.Nr, this.Nr)]) end; material1 end; function klammerAufteilung(project : 'Filterung Ansicht',suche : text) do if contains(suche, "(") and contains(suche, ")") then let splitSuche := split(suche, ""); if item(splitSuche, 0) = "(" or item(splitSuche, 1) = "(" then let klammerSuche := split(suche, ")"); let innerKlammerInhalt := ""; let ohneKlammerInhalt := ""; innerKlammerInhalt := replace(item(klammerSuche, 0), "(", ""); ohneKlammerInhalt := item(klammerSuche, 1); if contains(ohneKlammerInhalt, " + ") then fusionMaterial(this, innerKlammerInhalt, replace(ohneKlammerInhalt, " + ", ""), "and") else if contains(ohneKlammerInhalt, " / ") then fusionMaterial(this, innerKlammerInhalt, replace(ohneKlammerInhalt, " / ", ""), "or") else if contains(ohneKlammerInhalt, " - ") then fusionMaterial(this, innerKlammerInhalt, ohneKlammerInhalt, "except") end end end else let klammerSuche := split(suche, "("); let innerKlammerInhalt := ""; let ohneKlammerInhalt := ""; innerKlammerInhalt := replace(item(klammerSuche, 1), ")", ""); ohneKlammerInhalt := item(klammerSuche, 0); if contains(ohneKlammerInhalt, " + ") then fusionMaterial(this, innerKlammerInhalt, replace(ohneKlammerInhalt, " + ", ""), "and") else if contains(ohneKlammerInhalt, " / ") then fusionMaterial(this, innerKlammerInhalt, replace(ohneKlammerInhalt, " / ", ""), "or") else if contains(ohneKlammerInhalt, " - ") then fusionMaterial(this, innerKlammerInhalt, ohneKlammerInhalt, "except") end end end end else getProjektMaterial(this, suche) end end; klammerAufteilung(this, suche)
-
Das gesamte Vorhaben durchschaue ich jetzt nicht, aber auf die Schnelle zu dem Dreizeiler ...
said:
Aber mit dem Code erhalte ich immer 0 Datensätze.concat() gibt immer einen String zurück. Beispiel:
let myNumbers := [3, 12, 14, 19]; let myDigits := concat(myNumbers);
myDigits wäre dann ein String: "3,12,14,19". Zerlege ich diesen String wieder mit
let myArray := split(myDigits, ",");
bekomme ich ein aus einzelnen Strings bestehendes Array: ["3", "12", "14", "19"].
Um die Items daraus wieder als numerische Werte zu verarbeiten, müssen sie zuvor mit number() wieder in Zahlen umgewandelt werden:
number(item(myArray, 2)) * 10
Ergebnis wäre 140.
-
Ah verdammt stimmt.
function filterMaterial(projekt : 'Filterung Ansicht',filterNr : text) do let textNrs := split(filterNr, ", "); let numbersNrs := [0]; for x in textNrs do numbersNrs := array(numbersNrs, [number(x)]) end; select Material where contains(numbersNrs, number(this.Nr)) end; let myFilterMaterial := Material.Nr; filterMaterial(this, concat(myFilterMaterial))
wenn ich es jetzt in die produktiv Datenbank übernehme werde ich halt sehen, ob es auch noch schnell genug ist beim Laden der Datensätze.
Also meine Idee ist dass ich in dem Array die ID der Materialrecords behalte und dann die einzelnen Arrays zusammenführe und dann am Ende nur die Materialien anzeige, welche die ID haben welche in dem zusammengeführten Array sind.
Content aside
- vor 3 MonatenZuletzt aktiv
- 6Antworten
- 68Ansichten
-
3
Folge bereits