公式欄位:循環參照
欄位公式可以讀取關聯記錄的欄位,即使該記錄屬於同一張表。但它不能讀取該記錄上的自身欄位:公式編輯器會拒絕它,並顯示訊息「Circular reference」。
範例
表 Groups 有一個指向自身的參照 Parent:子群組透過它指向所屬的群組。公式欄位 Members 選出某個國家的人員(Country filter),而子群組必須從其所屬群組的成員中選取自己的成員:
Ninox
let country := 'Country filter';
let candidates := if Parent then Parent.Members else select People end;
candidates[Country = country]公式編輯器拒絕這段程式碼:「Circular reference: Members」。
原因
Ninox 以欄位而非記錄來推理。要編譯 Members 的公式,它必須知道 Parent.Members 的型別,因此要編譯 Members 的公式……而這正是它此刻在編譯的公式。父記錄永遠不會是記錄本身,這一點無關緊要:這種依賴在編譯時就被拒絕了。
注意
同一個運算式透過程式介面(/query)求值時,或者放在另一個欄位的公式中時,都不會報錯。只有它所讀取的那個欄位的公式編輯器會拒絕它:因此,在別處測試成功並不能保證它會被接受。
解決方法:第二個欄位
讓 Members 在不讀取父群組的情況下計算其清單:
Ninox
let country := 'Country filter';
select People where Country = country然後把限制交給第二個公式欄位 Effective members,它讀取記錄本身及其父記錄上的 Members:
Ninox
if Parent then
let parentMembers := Parent.Members;
Members[contains(parentMembers, this)]
else
Members
endEffective members 讀取 Members,但 Members 不讀取 Effective members:不再有循環。在方括號內,this 指正在檢查的人員;因此父記錄的成員要事先讀入一個變數。
須知
- 子群組的
Members欄位現在包含不屬於該群組的人員:所有顯示或使用成員的地方(檢視、按鈕、全域函式)都必須讀取Effective members。 - 循環也可能經過兩個欄位:讀取
Parent.'Effective members'的Members會形成Members→Effective members→Members的循環。我們沒有驗證 Ninox 如何處理這種情況:請用同樣的方法避免它。
