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:
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:
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:
if Parent then
let parentMembers := Parent.Members;
Members[contains(parentMembers, this)]
else
Members
endEffective 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
Memberseiner Untergruppe enthält jetzt Personen, die nicht Mitglied der Gruppe sind: Alles, was die Mitglieder anzeigt oder verwendet (Ansichten, Schaltflächen, globale Funktionen), mussEffective memberslesen. - Ein Zyklus kann auch über zwei Felder laufen:
Members, dasParent.'Effective members'läse, bildete die SchleifeMembers→Effective members→Members. Wie Ninox diesen Fall behandelt, haben wir nicht geprüft: Vermeiden Sie ihn auf dieselbe Weise.
