1

Dynamische Auswahlfelder in Skripten nutzen

Ich habe in einer Projektdatenbank eine zweite Tabelle mit Aufgaben, die einem Projekt zugewiesen sind. Ein Projekt kann also mehrere Aufgaben haben, was ich leicht mit einer verknüpften Tabelle realisieren konnte. Derzeit ist es aber recht umständlich die Aufgaben abzuhaken, weil die Tabellenansicht der Verknpüfung offenbar keine Checkbox für Ja/Nein-Felder kennt. Ich muss also die Aufgabe per Klick im Popup öffnen und dort ankreuzen. Bei vielen Aufgaben recht zeitaufwendig.

Nun dachte ich mir, dass ich mir mit Ninox 3.3.0 ein dynamisches Mehrfachauswahlfeld aus der Aufgaben-Datenbank bestücken kann. Die Darstellung klappt ziemlich easy, so wie im Blog beschrieben. Nun möchte ich auf das Ankreuzen reagieren und entsprechend die Datensätz der Aufgaben auf erledegt/unerledigt setzen. Doch wie greife ich auf die dynamischen Inhalte einer Mehrfachauswahl zu? text(Feld), string(Feld) oder number(Feld) liefern immer sehr seltsame Zahlen und chosen(Feld) funktioniert hier gar nicht.

Im Prinzip würde ich in dem Skript jetzt jeden einzelnen Datensatz durchgehen und prüfen, ob die zugehörige Checkbox gesetzt wurde. Doch wie erfahre ich etwa den Status von Checkbox 1 oder Checkbox 7 des dynamischen Felds?

Cooler wäre es ja, wenn man die Checkbox direkt mit einem Ja/Nein-Feld verknpüfen könnte. Das geht aber nicht, oder?

32 Antworten

null
    • Tekl
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Ich habe entdeckt, dass es neben dem dokumentierten chosen(Feld) noch ein undokumentierts chosen(Feld, Index) gibt. Genau das würde mir helfen, wenn es nicht stets "False" ausspucken würde.

    • Tekl
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Jetzt konnte ich mir doch helfen.

    Bei chosen() ist die Datensatznummer als Index entscheidend und nicht die (gedachte) fortlaufende Nummerierung der sichtbaren Auswahlfelder.

    Mein Skript sieht also vereinfacht wie folgt aus:

    for r in select Aufgaben do
      if chosen('Mehrfachauswahl', number(r)) then
        r.(Status := true)
      else
       r.(Status := false)
      end
    end

    • Tekl
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Soweit so gut. Jetzt fehlt noch der Rückweg. Wenn ich in der Aufgaben-Datenbank einen Datensatz abhake, soll natürlich auch die Checkbox in der Mehrfachauswahl erscheinen. Wie ich eine einzelne Checkbox setze ohen andere zu beeinflussen, habe ich bislang nicht rausgefunden.

    • Tekl
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Ich habe heute wohl einen Lauf und konnte mir wieder selbst helfen. ;-)

    Der Wert für Mehrfachauswahlfelder besteht aus eine umgedrehten Hexadezimalzahl, die ich mir jetzt mit folgender Formel aus den Datensätzen baue (innerhalb der Projekt-Tabelle). Ändere ich den Status eine Aufgabe, weist ein Skript diese errechnete Hex-Zahl dem Auswahlfeld zu.

    let num := 0;
    for i in select Aufgaben where Status = 3 do
       num := num + pow(2, number(i) - 1)
    end;
    let AUS := ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];
    var DEZ := num;
    var BCD := "";
    var POS := 0;
    var WER := 1;
    while DEZ > 0 or WER > 0 do
      WER := floor(DEZ / 16);
      POS := DEZ - WER * 16;
      BCD := item(AUS, POS) + BCD;
      DEZ := WER
    end
    ;
    "" + for i in range(length(BCD) - 1, -1) do
      substr(BCD, i, 1)
    end

    - Das Skript addiert für alle angehakten Aufgaben den Wert des 2^Datensatz-Index zu einer Endsumme "num"

    - Diese zu einer Hexadezimalzahl gewandelt (Funktion im Forum gefunden)

    - Abschließend wird die Zahl umgedreht.

    • Leonid_Semik
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Tekl, einfach genial. Wie bist du überhaupt auf hexadezimale zuweizung gekommen?

    • Leonid_Semik
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Ok, ich sehe es.

    raw(dmulti)

    • Tekl
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Bei mir liefert auch text() und string() den Hexcode. raw() kannte ich noch nicht, dabei ist es sogar dokumentiert. ;-)

    Wofür steht dmulti? Das ist nämlich nicht dokumentiert (oder wird von der Suche ignoriert)

    • Tekl
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Die Umwandlung zur Hex-Zahl funktioniert leider nicht mit einer großen Anzahl von Datensätzen. Offenbar dürfen Zahlen nicht endlos groß werden. Ich musste deshalb eine neue Formel schreiben, die alles über Strings realisert. 

     

    let me := this;
    let len := number(last((select Aufgaben).Nr));
    len := len + (len - floor(len / 4) * 4);
    let bin_result := rpad("", len, "0");
    for i in Aufgaben[Status = 3] do
      bin_result := substr(bin_result, 0, len - number(i) - 1) + "1" + substr(bin_result, len - number(i))
    end;
    "" + for i from 0 to len - 4 step 4 do
      let str := lpad(substr(bin_result, length(bin_result) - 5, 4), 4, "0");
      bin_result := substr(bin_result, 0, length(bin_result) - 4);
      switch str do
      case "0000":
        "0"
      case "0001":
        "1"
      case "0010":
        "2"
      case "0011":
        "3"
      case "0100":
        "4"
      case "0101":
        "5"
      case "0110":
        "6"
      case "0111":
        "7"
      case "1000":
        "8"
      case "1001":
        "9"
      case "1010":
        "a"
      case "1011":
        "b"
      case "1100":
        "c"
      case "1101":
        "d"
      case "1110":
        "e"
      case "1111":
        "f"
      end
    end

     

    Auch hier fehlen noch ausgiebige Tests.

    • Tekl
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Nach etwas Feintuning bin ich bei folgendem Code gelandet (bearbeitbare Foren-Beträge wären super):

     

    let me := this;
    let len := number(last((select Aufgaben).Nr));
    len := len + (len - floor(len / 4) * 4) + 4;
    let bin_result := rpad("", len, "0");
    for i in select Aufgaben where Status = 3 and 'Zugewiesener Artikel' = me do
    bin_result := substr(bin_result, 0, len - number(i) - 1) + "1" + substr(bin_result, len - number(i))
    end;
    "" + for i from 0 to len - 3 step 4 do
    let str := lpad(substr(bin_result, length(bin_result) - 5, 4), 4, "0");
    bin_result := substr(bin_result, 0, length(bin_result) - 4);
    switch str do
    case "0000":
    "0"
    case "0001":
    "1"
    case "0010":
    "2"
    case "0011":
    "3"
    case "0100":
    "4"
    case "0101":
    "5"
    case "0110":
    "6"
    case "0111":
    "7"
    case "1000":
    "8"
    case "1001":
    "9"
    case "1010":
    "a"
    case "1011":
    "b"
    case "1100":
    "c"
    case "1101":
    "d"
    case "1110":
    "e"
    case "1111":
    "f"
    end
    end

    • Leonid_Semik
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Das übersteigt meine Verständnisgrenzen total. Habe jetzt an ein paar Stellen getestet - funktioniert ohne Probleme. 
    Habe mir jetzt erlaubt daraus eine Funktion zu schreiben. Die Idee ist es, dass man wie bei normalen MFAF immer ein Array benutzt um das Feld zu ändern. Die Funktion wird global gespeichert:

    ---

    function getDmulti(arr : text) do
    let myTarr := split(arr, ",");
    let myDarr := for i in myTarr do
    number(i)
    end;
    let myOBJ := {
    '1000': "8",
    '1001': "9",
    '1010': "a",
    '1011': "b",
    '1100': "c",
    '1101': "d",
    '1110': "e",
    '1111': "f",
    '0000': "0",
    '0001': "1",
    '0010': "2",
    '0011': "3",
    '0100': "4",
    '0101': "5",
    '0110': "6",
    '0111': "7"
    };
    let len := max(myDarr);
    len := len + (len - floor(len / 4) * 4) + 4;
    let bin_result := rpad("", len, "0");
    for i in myDarr do
    bin_result := substr(bin_result, 0, len - number(i) - 1) + "1" + substr(bin_result, len - number(i))
    end;
    "" + for i from 0 to len - 3 step 4 do
    let str := lpad(substr(bin_result, length(bin_result) - 5, 4), 4, "0");
    bin_result := substr(bin_result, 0, length(bin_result) - 4);
    item(myOBJ, str)
    end
    end

    ---

    Wenn man jetzt ein Array aus IDs hat (über select where oä) kann man man das feld so ändern:

    FELDNAME:=getMulti(concat('DEIN ARRAY') 

    Ich danke dir herzlich, damit werden die dynamischen MFAF endlich nutzbar. Ich lasse die Funktion auch in Referenz DB reinschreiben.

    Leo

      • Maurice
      • vor 1 Jahr
      • Gemeldet - anzeigen

      Leonid Semik Tekl 

      Ich habe Leos Funktion verwendet, erhalte aber Fehler (siehe Screenshot). Ich habe Leos Code zur Deklaration der Funktion 1:1 übernommen. Darunter dieser Code.

      let Fach1 := 'Fach 1'.Nr;
      let Fach2 := 'Fach 2'.Nr;
      let Fach3 := 'Fach 3'.Nr;
      let myArray := getDmulti(concat(Fach1, Fach2,Fach3 ));
      'Fächer' := myArray
      

      Wie im Screenshot ersichtlich, erhalte ich statt nur der zwei Fächer, drei Fächer im DMAF markiert. Das bekomme ich sogar, wenn ich nur mit  getDmulti(concat(Fach1, Fach2 )) arbeite, hat also nix mit dem leeren Fach 3 zu tun. Bei machen 2-Fach Kombinationen stimmt es , bei manchen nicht. Ein Hinweis könnte sein: das falsche Fach, das ausgewählt wird (hier Latein), ist immer das Fach, das in der Ursprungstabelle, also jene, auf die das DMAF per select zugreift, nach dem Fach kommt, was die höchste ID.Nr der beiden Fächer in der Tabelle hat. In diesem Fall hat Französisch die Nr 15 und Spanisch die 16. Latein hat die 17. Bei anderen Kombinationen ist die Nr des falschen Faches immer Max(Fach 1,Fach 2)+1.

      Wo kann der Fehler liegen?

      Grüße Maurice

      • Maurice
      • vor 1 Jahr
      • Gemeldet - anzeigen

      Durch einen Parallelbeitrag habe ich gefunden, dass man gar nicht mehr über die Hex-Zahlen gehen muss. Ein

      let Fach1 := 'Fach 1'.Nr;
      let Fach2 := 'Fach 2'.Nr;
      let Fach3 := 'Fach 3'.Nr;
      let myArray := (select 'Fächer')[Nr = Fach1 or Nr = Fach2 or Nr = Fach3].number(Nr);
      'Fächer' := myArray
      

      reicht und funktioniert. Bestens. Maurice

    • Morris_Hanson
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Wäre es möglich eine Beispiel Datenbank zu bekommen. Für mich ist das noch nicht nachvollziehbar. ich würde es aber gerne reverse zerpflücken.. 

    danke

    • Tekl
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Danke Leonid für die Verbesserung. Wusste nicht, dass es assoziative Arrays in Ninox gibt. Schade, dass die Doku so veraltet ist.

     

    @swinxx: Ich habe mal eine Beispieldatenbank erstellt: https://www.dropbox.com/s/d1250a46vp1px7v/Projekte%20mit%20Aufgaben.ninox?dl=0

    • UweG
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Super Sache @Tekl, Wow.
    Eine kleine Anmerkung zur Aktualisierung des Formulares wenn eine neue Aufgabe ergänzt wurde. Leider funktioniert openRecord() nicht im Trigger. Nur bei aktiven Klick wird die Funktion ausgeführt. Man kommt wohl zur Zeit nicht daran vorbei einen Button zu bauen um das Formular zu aktualisieren und die neu erstellte Aufgabe angezeigt zu bekommen. Hier reicht dann let me:= this; openRecord(me)

    • UweG
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Ergänzung: Nicht ganz korrekte Aussage. Dies betrifft nur die Cloudanwendung, in der App funktioniert openRecord() auch mit Trigger.

    • Morris_Hanson
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Danke für die Datenbank! Es schein, als würden sich hier sehr tolle Möglichkeiten ergeben :) Ist es auch möglich Punkte so anzulegen, dass Sie dann für jedes "Projekt" gleich bleiben und immer als dynamische Liste sichtbar und anwählbar sind?

    • Tekl
    • vor 3 Jahren
    • Gemeldet - anzeigen

    @Uwe. Ich nutze Ninox generell nur in der App. Und da gibt es oben links auch einen Reload-Button. Falles es ihn auch in der Cloud gibt, muss man keinen eigenen Button basteln. ;-)

     

    @swinxx ich verstehe nicht ganz, was du meinst. Wenn jedes Projekt dieselbe Todo-Listen haben sollen, kannst du entweder die Aufgabentabelle beim Anlegen eines Projekts mit den gewünschten Todos befüllen oder du generierst die Checkliste via "select Aufgaben" aus allen Aufgaben-Datensätzen und verzichtest auf die Verknüpfung von Projekttabelle und Aufgabentabelle. Letztere ist aber nur sinnvoll, wenn du für Aufgaben eh nur einen Text und eine Checkbox brauchst.

    • Morris_Hanson
    • vor 3 Jahren
    • Gemeldet - anzeigen

    hatte nur vergessen die Beziehung zu den dynamischen Werten für die Namen einzufügen. jetzt klappt das wunderbar. danke

    • UweG
    • vor 3 Jahren
    • Gemeldet - anzeigen

    @Tekl. Da hast du natürlich Recht, wenn man in der Tabellenansicht ist. In der Formularanzeige gibt es den Reload-Knopf leider nicht. Aber ein Super-Projekt. Darf ich es in der 0001_Ninox-Reference als Beispiel aufnehmen mit Urheberrecht auf Dich?

    • Tekl
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Mach damit, was du willst. ;-) Wo finde ich die "0001_Ninox-Reference"? 

    • UweG
    • vor 3 Jahren
    • Gemeldet - anzeigen

    hallo @Tekl. Die Datenbank findest du im Team' Webinar DE 2021'. Dazu benötigst du jedoch einen Ninox-Cloud Abo. Wenn du nur die App nutzt, kann ich die die Datenbank auch per Mail senden. Schick mir dann einfach deine Mailadresse an test.ninox@gmx.de.

    • Kim_Tischler
    • vor 3 Jahren
    • Gemeldet - anzeigen

    @UweG wie kann man dem Webinar beitreten?

    • Tacho
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Hallo Kim,

    einfach eine E-Mail an    support@ninox.com    schicken, mit der Bitte um Einladung in das Team "Webinar DE 2021".

    Gruß
    Tacho

    • Leonid_Semik
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Hallo Tekl,
    Ich habe noch das Problem, dass die Formel nur funktioniert wenn es mindestens 2 Einträge im Array sind. Dei einem Eintrag ist es reine Glücksache. Wenn ich 11 eingebe, bekomme ich 1 angeklickt, bei 4 werden 4 und 5 angeklick. Ich habe versucht es selbst hinzubekommen, blicke aber in dem Ganzen Hexasalat nicht durch. Das ganze mit dem einen Eintrag ist daraus entstanden, dass dmulti in radio modus sich nicht automatisch aktualisiert wenn die Formel bei value eine Bedingung enthällt. So war die Idee zumindest die erste ID mitzuliefern. dann aktualisieren sich dmulti automatisch.

    Wäre schön, wenn du die Zeit hättest sich die Formel nochmals anzuschauen.

    Grüße
    Leo

Content aside

  • 1 „Gefällt mir“ Klicks
  • vor 1 JahrZuletzt aktiv
  • 32Antworten
  • 4111Ansichten
  • 6 Folge bereits