You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Acumatica中如何实现子记录字段跨标签页强制必填?

问题描述

通过SOOrder界面的“Prepare Invoice”功能创建SOInvoice时,系统会自动插入一条空的子记录(MyChild)。要求用户手动录入数据后,该子记录的MyField字段必须设为必填项。目前遇到两个问题:

  • 基于RowPersisting<MyChild>的代码仅在子记录标签页激活时生效,切换到其他标签页就无法触发校验。
  • 基于RowPersisting<ARInvoice>的代码无法阻止保存操作,也无法正确显示错误提示。

目标:无论当前激活哪个标签页,MyField字段及对应子记录标签页都要显示必填标记,且保存时强制校验。


现有代码1(仅子标签页激活时生效)

public void _(Events.RowPersisting<MyChild> e)
{
    MyChild element = e.Row as MyChild;
    if (element != null && element.MyField == null)
    {
        e.Cache.RaiseExceptionHandling<MyChild.myField>(
            e.Row, 
            null, 
            new PXSetPropertyException(
                Messages.MyFieldIsEmpty, 
                typeof(MyChild.myField).Name
            )
        );
        e.Cancel = true;                
    }
}

现有代码2(无法阻止保存/显示错误)

public SelectFrom<MyChild>.Where<MyChild.myField.IsNotNull.And<MyChild.refNbr.Contains<ARInvoice.refNbr.FromCurrent>>>.View MyChilds;

public void _(Events.RowPersisting<ARInvoice> e)
{
    var hasChildren = MyChilds.Select().Count > 0;
    if (!hasChildren)
    {
        e.Cache.RaiseExceptionHandling<MyChild.myField>(
            e.Row,
            null,
            new PXSetPropertyException(
                Messages.MyFieldIsEmpty,
                typeof(MyChild.myField).Name
            )
        );
        e.Cancel = true;
        throw new PXException(Messages.MyFieldIsEmpty);
    }
}

解决方案

要实现全局校验(无论哪个标签页激活),并让标签页显示必填标记,需从字段属性配置和主记录校验逻辑两方面入手:

1. 给MyField字段添加必填属性(显示必填标记)

直接在MyChild DAC的MyField字段上标记属性,让界面自动显示必填星号,同时子标签页会出现必填提示标记:

[PXDBString(50, IsUnicode = true)]
[PXUIField(DisplayName = "My Field", Required = true)] // 界面显示必填星号
[PXNotNull] // 可选:数据库层面强制非空,根据业务需求决定
public virtual string MyField { get; set; }
public abstract class myField : BqlString.Field<myField> { }

2. 在ARInvoice的RowPersisting事件中实现全局校验

修改原有代码逻辑,直接遍历当前发票关联的所有MyChild记录,检查字段值并正确触发错误提示:

public void _(Events.RowPersisting<ARInvoice> e)
{
    ARInvoice invoice = e.Row as ARInvoice;
    if (invoice == null) return;

    // 获取当前发票关联的所有MyChild子记录
    var childRecords = PXSelect<MyChild, Where<MyChild.refNbr, Equal<Current<ARInvoice.refNbr>>>>.Select(Base);
    
    foreach (MyChild child in childRecords)
    {
        if (string.IsNullOrEmpty(child.MyField))
        {
            // 针对子记录字段触发错误,同时让子标签页显示错误标记
            PXCache<MyChild> childCache = Base.Caches[typeof(MyChild)];
            childCache.RaiseExceptionHandling<MyChild.myField>(
                child, 
                child.MyField, 
                new PXSetPropertyException(Messages.MyFieldIsEmpty, PXErrorLevel.Error)
            );
            
            e.Cancel = true;
            // 无需额外抛出PXException,RaiseExceptionHandling已阻止保存并显示提示
        }
    }
}

3. 保留MyChild的RowPersisting事件(增强即时校验)

保留原有子记录的校验逻辑,让用户在子标签页编辑时能即时得到反馈,与全局校验形成互补:

public void _(Events.RowPersisting<MyChild> e)
{
    MyChild element = e.Row as MyChild;
    if (element != null && string.IsNullOrEmpty(element.MyField))
    {
        e.Cache.RaiseExceptionHandling<MyChild.myField>(
            e.Row, 
            element.MyField, 
            new PXSetPropertyException(Messages.MyFieldIsEmpty, PXErrorLevel.Error)
        );
        e.Cancel = true;                
    }
}

关键说明

  • [PXUIField(Required = true)]能让界面直观显示必填星号,明确用户操作要求。
  • 在主记录(ARInvoice)的RowPersisting事件中校验子记录,确保无论当前在哪个标签页,保存时都会触发校验。
  • 使用PXCache<RaiseExceptionHandling>时传入子记录缓存对象,可让子标签页自动显示错误标记。

内容的提问来源于stack exchange,提问作者Martin Weber

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 03:26:13