0

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

null
    • Ninox-Professional
    • planoxpro
    • vor 3 Monaten
    • Gemeldet - anzeigen

    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.

    • UweG
    • vor 3 Monaten
    • Gemeldet - anzeigen

    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)
    end

    Funktionsaufruf im Script:
    let vResponse := fxTest(formatJSON((select Table).Name))

    • Ninox-Professional
    • planoxpro
    • vor 3 Monaten
    • Gemeldet - anzeigen

    Uwes Version ist natürlich noch eleganter. 

    • Lamping & Reisig Gmbh & Co.KG
    • LuRLorenz
    • vor 3 Monaten
    • Gemeldet - anzeigen

    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)
    
    • Ninox-Professional
    • planoxpro
    • vor 3 Monaten
    • Gemeldet - anzeigen

    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.
     

    • Lamping & Reisig Gmbh & Co.KG
    • LuRLorenz
    • vor 3 Monaten
    • Gemeldet - anzeigen

    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