0

Automatisch Untertabelle erzeugen mit Verknüpfungen

Hallo,

habe eine Tabelle mit Haushaltstiteln.

Jetzt möchte ich für jedes Kalenderjahr die entsprechenden Haushaltsansätze (Beträge) in eine weitere Tabelle eintragen. Hier für möchte ich in die Tabele HH-Jahre nur das Jahr einträgen und es soll automatisch eine Untertabelle erzeugt werden, die die HAushaltstitel aus der Tabelle Haushaltstitel enthält und pro Hauhshaltstitel noch ein Feld Betrag.

Wie lässt sich die Untertabelle erzeugen?

Grüße

Maurice

2019-02-18_01-06-36

17 Antworten

null
    • Frank_Schafer
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo Maurice,

    eine Untertabelle kannst du nicht automatisch erzeugen - sehr wohl aber Einträge in eine vorhandene (Unter-)Tabelle. Also solltest du eine Tabelle anlegen, die eine Verknüpfung mit der Jahrestabelle enthält und alle Jahre in einer Tabelle abhandelt. Diese kannst du dann etwa wie folgt aus dem Trigger "Bei neuem Datensatz folgendes Skript ausführen" der Jahr-Tabelle oder dem Trigger "Nach Änderung folgendes Skript ausführen" des Feldes 'HH-Jahr' der Jahr-Tabelle füllen (ich hoffe, ich habe deine Datenbank-Struktur halbwegs verstanden):

    let myHHJahr := this;
    for myAnsatz in (select 'Haushaltstitel') do
      let newUntertabelleneintrag := (create Untertabelle);
      newUntertabelleneintrag.'HH-Jahr' := myHHJahr;
      newUntertabelleneintrag.Kapitel := myAnsatz.Kapitel;
      newUntertabelleneintrag.Titelgruppe := myAnsatz.Titelgruppe;
      newUntertabelleneintrag.Titel := myAnsatz.Titel;
      newUntertabelleneintrag.'HH-Ansatz' := myAnsatz.'HH-Ansatz';
      //... hier eventuell noch weitere Felder übernehmen oder diese Zeile löschen
    end;

    VG Frank

    • Maurice
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo Frank,

    danke für die schnelle Rückmeldung. Ich habe verstanden: nur eine Untertabelle mit allen Jahresansätzen. Mit

    let myHHJahr := this;
    for myAnsatz in select Haushaltstitel do
    let newUntertabelleneintrag := (create 'HH-Ansätze');
    newUntertabelleneintrag.('HH-Jahr' := myHHJahr);
    newUntertabelleneintrag.(Haushaltstitel := myAnsatz.Titel)
    end

    werden die Titel (das ist ein Zahlenfeld in der Tabelle "Haushaltstitel") leider nicht eingetragen. In der Untertabelle "HH-Ansätze" (die hieß bei meinem ersten Posting HH-Ansätze 2019) stehen jetzt zwar (ich sage jetzt mal) 20 neue Einträge mit der neuen Jahreszahl, aber bei den Einträgen ist das Feld "Haushaltstitel" ist jeweils leer.

    Sonst sieht das schon sehr gut aus.

    Grüße

    Maurice

    • Maurice
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo,

    so geht es:

    let myHHJahr := this;
    for myAnsatz in select Haushaltstitel do
    let Nummer := number(myAnsatz.Nr);
    let newUntertabelleneintrag := (create 'HH-Ansätze');
    newUntertabelleneintrag.('HH-Jahr' := myHHJahr);
    newUntertabelleneintrag.(Haushaltstitel := Nummer)
    end

    Grüße

    Maurice

    • Maurice
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo,

    gibt es auch eine Möglichkeit, statt für jeden Haushaltstitel eine neuen Datensatz anzulegen, für jeden Haushatlstitel ein neues Feld in einer Tabelle (in der gleichen Tabelle wie das Datum) generieren zu lassen. So dass dann Datum und alle HAushaltstitel einen Datensatz bilden und ich keine Untertabelle benötige?

    PS: Es geht jetzt nicht um die jährlichen Haushaltsansätze, sondern eine Abfrage, wie viel Geld in den einzelnen Positionen noch vorhanden ist.

    Grüße

    Maurice

    • Frank_Schafer
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo Maurice,

    Du kannst leider derzeit keine Änderungen an der Datenbankstruktur per Skript durchführen - lediglich Datenänderungen...

    VG Frank

    • Maurice
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Danke, Frank. Dann weiß ich, was zu tun ist.

    Grüße Maurice

    • Maurice
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo, hänge doch an einer Stelle:

    Nachdem ich die Ansätze für die Haushaltstitel für verschiedene Haushaltsjahre über die Tabelle HH-Jahre mit Untertabelle HH-Ansätze umgesetzt habe, will ich in einer weiteren Tabelle die Haushaltsreste berechnen. Hierzu die gleiche Konstruktion: Tabelle HH-Stand Datum (hier wird das Datum eingetragen) und eine Untertabelle HH-Stände. In letztere sollen automatisch beim Anlegen eines neuen Datums in HH-Stand Datum für jeden Haushaltstitel der dazugehörige Titel, das Haushaltsjahr und der HH-Ansatz (aus der Tabelle HH-Ansätze) eingetragen werden. Die entsprechenden Verknüpfungen zu den Tabellen sind angelegt. 

    Im Feld "Bei neuem Datensatz folgendes Skript ausführen" habe ich eingetragen:

    let myYear := year(Datum);
    let myDatum := this;
    for myStand in select Haushaltstitel do
    let Nummer := number(myStand.Nr);
    let newUntertabelleneintrag := (create 'HH-Stände');
    newUntertabelleneintrag.('HH-Stand Datum' := myDatum);
    newUntertabelleneintrag.(Haushaltstitel := Nummer);
    select 'HH-Ansätze' where 'HH-Jahr' = myYear;
    newUntertabelleneintrag.('HH-Ansätze' := 'HH-Ansätze'.'HH-Ansatz')
    end

    Die HH-Ansätze des entsprechenden HH-Jahres werden nicht eingetragen. Weiß jemand Rat?

    Grüße

    Maurice

    2019-02-19_22-49-48

    • Frank_Schafer
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo Maurice,

    dein 2. select

    select 'HH-Ansätze' where 'HH-Jahr' = myYear;

    macht nichts ausser sich selbst auszuführen. Du müsstest das Ergebnis einer Konstanten (let myKonst := select 'HH-Ansätze' where 'HH-Jahr' = myYear;) oder Variablen (var myVar := select 'HH-Ansätze' where 'HH-Jahr' = myYear;) zuweisen oder es in einer Schleife (for myVar in select 'HH-Ansätze' where 'HH-Jahr' = myYear do) verarbeiten.

    Bei der Zuweisung zu einer Konstanten oder Variablen solltest du aber auch bedenken, dass das select grundsätzlich mehrere Datensätze zurückgeben kann. Du kannst mit first() oder last() den ersten bzw. letzten Datensatz der Ergebnismenge auswählen und so sicherstellen, dass du nur einen Datensatz verarbeitest.

    VG Frank

    • Maurice
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo Frank,

    ich muss ja das select in die for myStand Schleife packen, damit ich den korrekten Datensatz aus Haushaltstitel habe. Das sieht bei mir jetzt so aus:

    let myYear := year(Datum);
    let myDatum := this;
    for myStand in select Haushaltstitel do
    let Nummer := number(myStand.Nr);
    let myKapitel := myStand.Kapitel;
    let myTitel := myStand.Titel;
    let myAnsatz := (select 'HH-Ansätze')['HH-Jahr' = myYear and 'HH-Titel'.Kapitel = myKapitel and 'HH-Titel'.Titel = myTitel].'HH-Ansatz';
    let newUntertabelleneintrag := (create 'HH-Stände');
    newUntertabelleneintrag.('HH-Stand Datum' := myDatum);
    newUntertabelleneintrag.(Haushaltstitel := Nummer);
    newUntertabelleneintrag.('HH-Ansätze' := myAnsatz)
    end

    Mit den Bedingungen bei select sollte ein eindeutiger Datensatz zurückgegeben werden, da die Haushaltstitel über Titel und Kapitel eindeutig definiert sind. Bekomme aber die Meldung, dass der Ausdruck meherere Ergebnisse liefert. Dann das Ganze in eine first-Klammer, um nur einen DAtensatz zu erhalten - erfolglos.

    Um die Funktionsweise zu testen, habe ich auch vereinfacht versucht:

    let myAnsatz := first((select 'HH-Ansätze')['HH-Jahr' = myYear]).'HH-Ansatz';

    dann auch statt eckiger Klammer mit where gearbeitet, siehe Therad hier:

    https://ninoxdb.de/en/forum/technische-hilfe-5ab8fe445fe2b42b7dd39ee8/select-syntax-5bebee43cffb9b0d63355f03

    Es erfolgt einfach kein Eintrag in das Feld 'HH-Ansätze'.

    Grüße

    Maurice

    • Frank_Schafer
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo Maurice,

    jetzt sieht das für mich erst mal nicht schlecht aus ... aber ohne genauere Kenntnisse über die Datenbankstruktur kann ich deinen Fehler nicht einordnen...

    Du könntest mal mit einem alert(myAnsatz) nach der Zuweisung prüfen, ob da überhaupt etwas gefunden wird.

    VG Frank

    btw: Du kannst natürlich über eine entsprechende Abfrage sicher stellen, dass das Ergebnis eindeutig ist und nur einen Datensatz liefert - das kann Ninox aber bei der Syntax-Prüfung nicht feststellen und meckert daher ... dann tut aber ein first() auch nicht weh.

    • Maurice
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo Frank,

    jeeeetzt geht es. Mehrere Denkfehler hatte ich. Der Hinweis auf die alert-Funktion zur Analyse war super. Danke. Der Code lautet nun:

    let myDatum := this;
    let myYear := year(Datum);
    for myStand in select Haushaltstitel do
    let Nummer := number(myStand.Nr);
    let myKapitel := myStand.Kapitel;
    let myTitel := myStand.Titel;
    let myAnsatz := number(first((select 'HH-Ansätze')['HH-Jahr'.Haushaltsjahr = myYear and 'HH-Titel'.Kapitel = myKapitel and 'HH-Titel'.Titel = myTitel].Nr));
    let newUntertabelleneintrag := (create 'HH-Stände');
    newUntertabelleneintrag.('HH-Stand Datum' := myDatum);
    newUntertabelleneintrag.(Haushaltstitel := Nummer);
    newUntertabelleneintrag.('HH-Ansätze' := myAnsatz)
    end;

    Datumssperre := true

    Auffällig war, dass ein alert(myYear) und ein alert(myAnsatz) jeweils ein leeres Feld brachten. Außerdem musste ich bei select 'HH-Ansätze' statt 'HH-Jahr' korrekterweise 'HH-Jahr'.Haushaltsjahre nehmen, da es sich um ein verknüpftes feld handelt.

    ZU den zwei leeren Alerts

    1) Ich hatte die Befehlsstruktur ja beim Anlegen eines neuen Datensatzes in der Tabelle eingegeben, wenn zu einem bestimmten Datum der Mittelabfluss erhoben werden soll. Wenn der Datensatz angelegt wird, ist aber noch gar keine Datumseingabe erfolgt. Deshalb ist year(Datum) beim Anlegen ins Leere gelaufen. Ich habe also die ganze Befehlsstruktur beim Feld Datum untergebracht bei "Nach Änderung folgendes Skript ausführen". Gegen Änderungen habe ich eine manuelle Absicherung eingebaut: ein Ja/Nein Feld als Schieberegler (Datumssperre). Das Feld Datum kann nur geändert werden, wenn dieses Feld entsperrt wird. Durch Datumssperre := true wird automatisch nach Eingabe eines neuen Datums die Sperre gesetzt. Das Datumsfeld kann nur geändert werden, wenn ich hier manuell entriegele.

    2) Irgendwo hatte ich gelesen, dass bei dem Befehl create die Datensatz-ID bzw. Nr übergeben werden muss. Hier: https://ninoxdb.de/de/forum/technische-hilfe-5ab8fe445fe2b42b7dd39ee8/duplizieren-von-datensatzen-mit-untertabelle-5ab8fe445fe2b42b7dd39ef4 steht dann auch, dass diese erst mit der Number-Funktion in eine Zahl gewandelt werden muss. Deshalb bei myAnsatz das Konstrukt mit number(). Ohne das first() klappt es nicht.

    Vielen Dank Frank. Ohne dich hätte ich es nicht geschafft.

    Grüße

    Maurice

    • Maurice
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Es muss natürlich alert(text(myYear)) heißen, was auch ein leere Ausgabe brachte. myYear war nicht belegt.

    Maurice

    • Frank_Schafer
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Prima - gerne bei der nächsten Frage wieder :)

    • Maurice
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo,

    noch eine Merkwürdigkeit bzw. Frage.

    In der Tabellenansicht (oder Karten etc.) steht jetzt der HH-Ansatz schön drinnen, aber im Eingabeformular steht nur (unbekannt) - siehe Bild. Wie kommt das denn? Da hätte ich auch gerne den Wert stehen.

    Grüße

    Maurice

    2019-02-21_06-07-42

    • Frank_Schafer
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo Maurice,

    zumindest ist ein Datensatz verknüpft - sonst sähe das Feld anders aus. Vielleicht weiß Ninox aber nicht, was angezeigt werden soll. Du kannst im Feld "Anzeigen als" des Verknüpfungsfeldes einstellen, was hier von dem verknüpften Datensatz angezeigt werden soll - z. B. den Betrag. Prüfe doch mal, was dort drin steht bzw. stell mal ein, was du dort sehen möchtest.

    VG Frank

    • Maurice
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo Frank,

    oh, klar. Habe da jetzt was eingetragen. Geht. Wird allerdings linksbündig agezeigt, obwohl es ein verknüpftes Zahlenfeld ist.

    Grüße

    Maurice

    • Frank_Schafer
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo Maurice,

    den Betrag kannst du ja noch über ein Funktionsfeld als "richtige Zahl" anzeigen. Wenn die Zuordnung auch ausschließlich über das Script bei der Zuweisung des Datums passiert und nicht bearbeitet werden muss könntest Du die Zuweisung hier dann auch ausblenden.

    VG Frank

Content aside

  • vor 5 JahrenZuletzt aktiv
  • 17Antworten
  • 5612Ansichten