PXFormula 屬性
一般說明
Acumatica 中的公式是 DAC 欄位,它是根據其他物件欄位的值計算的。
為了計算公式,Aсumatiсa 框架提供了一組各種操作和函式(例如算術,邏輯和比較運算以及字串處理函式;請參閱內建公式列表 )。除了欄位值之外,公式還可以使用 Acumatica 核心和應用程式解決方案提供的各種常量。此外,公式不僅可以從當前記錄中獲得計算值,還可以從其他來源獲得計算值(請參閱公式上下文及其修飾符 )。
公式的美妙之處在於它們會在適當的時間自動重新計算價值:
- 欄位預設(插入新行;公式欄位的
FieldDefaulting
事件處理程式) - 關於依賴欄位的更新(每個依賴欄位的
FieldUpdated
事件處理程式) - 關於資料庫選擇(僅適用於未繫結欄位;
RowSelecting
事件處理程式) - 在需要時保持資料庫持久化(開發人員應明確指定它;
RowPersisted
事件處理程式)
在依賴欄位的更新上重新計算公式欄位值會引發公式欄位的 FieldUpdated
事件。這允許你建立一系列相關公式(請參閱公式中的直接和中介迴圈引用)。
應用程式開發人員可以編寫自己的應用程式端公式
使用方式
公式可以用於三種主要模式:
- 只需計算值並將其分配給公式欄位(請參閱基本用法 )
- 從公式欄位的現有值計算聚合值並將其分配給父物件中的指定欄位(請參閱聚合用法 )
- 混合模式:計算公式值,將其分配給公式欄位,計算聚合值,並將其分配給父物件中的欄位(請參閱組合使用 )
還有另一種輔助模式,未繫結的公式,與混合模式非常相似,但公式的計算值未分配給公式欄位。立即計算聚合值並將其分配給父物件的欄位。有關詳細資訊,請參閱未繫結公式的用法。
PXFormulaAttribute
屬性和建構函式引數
公式功能由 PXFormulaAttribute
實現。PXFormulaAttribute 的建構函式具有以下簽名:
public PXFormulaAttribute(Type formulaType)
{
// ...
}
單個引數 formulaType
是一種公式表示式,用於計算來自同一資料記錄的其他欄位的欄位值。此引數必須滿足以下條件之一:
- 必須實現 IBqlField 介面
- 必須是 BQL 常量
- 必須實現 IBqlCreator 介面(參見內建常用公式列表 )
public PXFormulaAttribute(Type formulaType, Type aggregateType)
{
// ...
}
第一個引數 formulaType
與第一個建構函式中的相同。第二個引數 aggregateType
是一種聚合公式,用於計運算元資料記錄欄位中的父資料記錄欄位。可以使用聚合函式,例如 SumCalc,CountCalc,MinCalc 和 MaxCalc。應用開發人員可以建立自己的聚合公式。
聚合公式型別必須是泛型型別,並且必須實現 IBqlAggregateCalculator
介面。聚合公式型別的第一個通用引數必須實現 IBqlField
介面,並且必須具有父物件的欄位型別。
public virtual bool Persistent { get; set; }
PXFormulaAttribute.Persistent
屬性指示在將更改儲存到資料庫後屬性是否重新計算公式。如果在 RowPersisting
事件中更新了公式所依賴的欄位,則可能需要重新計算。預設情況下,該屬性等於 false
。
用法
在大多數情況下,公式用於直接計算來自同一資料記錄的其他欄位的公式欄位的值。
最簡單的公式用法示例:
[PXDBDate]
[PXFormula(typeof(FADetails.receiptDate))]
[PXDefault]
[PXUIField(DisplayName = Messages.PlacedInServiceDate)]
public virtual DateTime? DepreciateFromDate { get; set; }
在此示例中,ReceiptDate 欄位的值在插入新記錄和 ReceiptDate 欄位更新時分配給 DepreciateFromDate 欄位。
一個稍微複雜的例子:
[PXCurrency(typeof(APPayment.curyInfoID), typeof(APPayment.unappliedBal))]
[PXUIField(DisplayName = "Unapplied Balance", Visibility = PXUIVisibility.Visible, Enabled = false)]
[PXFormula(typeof(Sub<APPayment.curyDocBal, APPayment.curyApplAmt>))]
public virtual Decimal? CuryUnappliedBal { get; set; }
這裡,文件的未應用餘額計算為文件餘額與應用金額之間的差額。
具有預設值的多項選擇示例:
[PXUIField(DisplayName = "Class Icon", IsReadOnly = true)]
[PXImage]
[PXFormula(typeof(Switch<
Case<Where<EPActivity.classID, Equal<CRActivityClass.task>>, EPActivity.classIcon.task,
Case<Where<EPActivity.classID, Equal<CRActivityClass.events>>, EPActivity.classIcon.events,
Case<Where<EPActivity.classID, Equal<CRActivityClass.email>,
And<EPActivity.isIncome, NotEqual<True>>>, EPActivity.classIcon.email,
Case<Where<EPActivity.classID, Equal<CRActivityClass.email>,
And<EPActivity.isIncome, Equal<True>>>, EPActivity.classIcon.emailResponse,
Case<Where<EPActivity.classID, Equal<CRActivityClass.history>>, EPActivity.classIcon.history>>>>>,
Selector<Current2<EPActivity.type>, EPActivityType.imageUrl>>))]
public virtual string ClassIcon { get; set; }
領域順序
DAC 中的欄位順序對於校正公式計算很重要。必須在公式欄位之前的 DAC 中定義包括其他公式的所有源欄位(從中計算公式)。否則,可能會錯誤地計算欄位,或者可能導致執行時錯誤。
公式語境及其修飾語
預設情況下,公式計算的上下文受包含公式宣告的類的當前物件(記錄)限制。它也允許使用常量(Constant<>
類的後代)。
僅使用其物件欄位的公式:
public partial class Contract : IBqlTable, IAttributeSupport
{
//...
[PXDecimal(4)]
[PXDefault(TypeCode.Decimal, "0.0", PersistingCheck = PXPersistingCheck.Nothing)]
[PXFormula(typeof(Add<Contract.pendingRecurring, Add<Contract.pendingRenewal, Contract.pendingSetup>>))]
[PXUIField(DisplayName = "Total Pending", Enabled=false)]
public virtual decimal? TotalPending { get; set; }
//...
}
但是,可以從其他來源獲取公式計算的輸入值:
- BLC 中任何快取的當前記錄(如果已分配)。
PXSelectorAttribute
指定的外國記錄。- 由
PXParentAttribute
指定的父記錄。
該公式支援以下上下文修飾符。
Current<TRecord.field>
和 Current2<TRecord.field>
從儲存在 TRecord 快取的 Current
屬性中的記錄中獲取欄位值。
如果快取的 Current
屬性或欄位本身包含 null:
- 當前<>強制欄位預設並返回預設欄位值。
- Current2 <>返回 null。
例:
[PXFormula(typeof(Switch<
Case<Where<
ARAdjust.adjgDocType, Equal<Current<ARPayment.docType>>,
And<ARAdjust.adjgRefNbr, Equal<Current<ARPayment.refNbr>>>>,
ARAdjust.classIcon.outgoing>,
ARAdjust.classIcon.incoming>))]
protected virtual void ARAdjust_ClassIcon_CacheAttached(PXCache sender)
Parent<TParent.field>
從駐留在當前 DAC 上的 PXParentAttribute 定義的父資料記錄中獲取欄位值。
public class INTran : IBqlTable
{
[PXParent(typeof(Select<
INRegister,
Where<
INRegister.docType, Equal<Current<INTran.docType>>,
And<INRegister.refNbr,Equal<Current<INTran.refNbr>>>>>))]
public virtual String RefNbr { ... }
[PXFormula(typeof(Parent<INRegister.origModule>))]
public virtual String OrigModule { ... }
}
IsTableEmpty<TRecord>
如果對應於指定 DAC 的 DB 表不包含記錄,則返回 true
,否則返回 false
。
public class APRegister : IBqlTable
{
[PXFormula(typeof(Switch<
Case<Where<
IsTableEmpty<APSetupApproval>, Equal<True>>,
True,
Case<Where<
APRegister.requestApproval, Equal<True>>,
False>>,
True>))]
public virtual bool? DontApprove { get; set; }
}
Selector<KeyField, ForeignOperand>
獲取在當前 DAC 的外來鍵欄位(KeyField)上定義的 PXSelectorAttribute
獲取選擇器當前引用的外部資料記錄
計算並返回 ForeignOperand 定義的資料記錄上的表示式
public class APVendorPrice : IBqlTable
{
// Note: inventory attribute is an
// aggregate containing a PXSelectorAttribute
// inside, which is also valid for Selector<>.
// -
[Inventory(DisplayName = "Inventory ID")]
public virtual int? InventoryID
[PXFormula(typeof(Selector<
APVendorPrice.inventoryID,
InventoryItem.purchaseUnit>))]
public virtual string UOM { get; set; }
}
在未繫結欄位上使用公式
如果公式欄位是標記有 PXFieldAttribute
後代之一的未繫結欄位(例如 PXIntAttribute
或 PXStringAttribute
),則在 RowSelecting
事件期間另外觸發其計算。
內建常用公式列表
TBD
公式中的直接和中介迴圈引用
TBD
條件公式中的控制流程
TBD
在一個場上使用多個公式
TBD