Formelfelder: der Zirkelbezug

Eine Feldformel kann die Felder eines verknüpften Datensatzes lesen, auch wenn dieser Datensatz zur selben Tabelle gehört. Ihr eigenes Feld auf diesem Datensatz kann sie dagegen nicht lesen: Der Formel-Editor lehnt sie mit der Meldung „Circular reference“ ab.

Der Fall

Eine Tabelle Groups hat eine Verknüpfung auf sich selbst, Parent: So verweist eine Untergruppe auf ihre Gruppe. Das Formelfeld Members wählt die Personen eines Landes aus (Country filter), und eine Untergruppe soll ihre Personen unter den Mitgliedern ihrer Gruppe auswählen:

Ninox
let country := 'Country filter';
let candidates := if Parent then Parent.Members else select People end;
candidates[Country = country]

Der Formel-Editor lehnt diesen Code ab: „Circular reference: Members“.

Warum

Ninox denkt in Feldern, nicht in Datensätzen. Um die Formel von Members zu kompilieren, muss es den Typ von Parent.Members kennen und dafür die Formel von Members kompilieren … genau die Formel, die es gerade kompiliert. Dass der übergeordnete Datensatz nie der Datensatz selbst ist, spielt keine Rolle: Die Abhängigkeit wird schon beim Kompilieren abgelehnt.

Achtung

Derselbe Ausdruck erzeugt keinen Fehler, wenn er über die Programmierschnittstelle (/query) ausgewertet wird oder in der Formel eines anderen Feldes steht. Nur der Formel-Editor des Feldes, das er liest, lehnt ihn ab: Ein gelungener Test an anderer Stelle garantiert also nicht, dass er angenommen wird.

Die Lösung: ein zweites Feld

Lassen Sie Members seine Liste berechnen, ohne die übergeordnete Gruppe zu lesen:

Ninox
let country := 'Country filter';
select People where Country = country

Übertragen Sie die Einschränkung dann einem zweiten Formelfeld, Effective members, das Members auf dem Datensatz und auf seinem übergeordneten Datensatz liest:

Ninox
if Parent then
    let parentMembers := Parent.Members;
    Members[contains(parentMembers, this)]
else
    Members
end

Effective members liest Members, aber Members liest nicht Effective members: Es gibt keinen Zyklus mehr. In den eckigen Klammern bezeichnet this die geprüfte Person; deshalb werden die Mitglieder des übergeordneten Datensatzes vorher in eine Variable gelesen.

Gut zu wissen

  • Das Feld Members einer Untergruppe enthält jetzt Personen, die nicht Mitglied der Gruppe sind: Alles, was die Mitglieder anzeigt oder verwendet (Ansichten, Schaltflächen, globale Funktionen), muss Effective members lesen.
  • Ein Zyklus kann auch über zwei Felder laufen: Members, das Parent.'Effective members' läse, bildete die Schleife Members → Effective members → Members. Wie Ninox diesen Fall behandelt, haben wir nicht geprüft: Vermeiden Sie ihn auf dieselbe Weise.