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

如何避免Acumatica自定义网格及导入场景中的重复条目

解决Acumatica网格禁止重复记录(含导入场景)的方案

我来帮你搞定这个需求——不管是用户在界面操作还是通过导入场景,都要禁止网格里插入重复的记录。咱们主要通过在网格行的验证事件中添加重复检查逻辑,确保两种场景都能生效。

从你的代码来看,网格里的Period字段是区分重复的关键(你用它来设置排序号),所以咱们就以检查同一文档下是否存在重复的Period为例来实现。

步骤1:添加重复验证的事件处理程序

你需要在KWStoreTrafficEntityDetails的RowInserting和RowUpdating事件中加入重复检查逻辑。这样不管是插入新行还是修改现有行,都会触发验证,及时阻止重复记录。

步骤2:确保导入场景也遵循规则

Acumatica的导入场景在处理数据时会触发常规的行级事件,所以只要咱们的验证逻辑写在RowInserting/RowUpdating里,导入时自然会生效,不需要额外的特殊处理。

修改后的完整代码

public class KWStoreTrafficEntityMaint : PXGraph<KWStoreTrafficEntityMaint, KWStoreTrafficEntity> {
    public PXSelect<KWStoreTrafficEntity> Document;
    [PXImport(typeof(KWStoreTrafficEntity))]
    public PXSelect<KWStoreTrafficEntityDetails, Where<KWStoreTrafficEntityDetails.entityNbr, Equal<Current<KWStoreTrafficEntity.entityNbr>>>, OrderBy<Asc<KWStoreTrafficEntityDetails.sortOrder>>> Transactions;

    #region Event Handlers
    protected virtual void KWStoreTrafficEntityDetails_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e) {
        KWStoreTrafficEntityDetails items = e.Row as KWStoreTrafficEntityDetails;
        if (items == null) return;
        
        // 简化原有的Period对应SortOrder逻辑
        items.SortOrder = items.Period switch {
            "9 AM" => 1,
            "10 AM" => 2,
            "11 AM" => 3,
            "12 PM" => 4,
            "1 PM" => 5,
            "2 PM" => 6,
            "3 PM" => 7,
            "4 PM" => 8,
            "5 PM" => 9,
            "6 PM" => 10,
            "7 PM" => 11,
            _ => items.SortOrder
        };
    }

    // 新增:检查插入行的重复情况
    protected virtual void KWStoreTrafficEntityDetails_RowInserting(PXCache sender, PXRowInsertingEventArgs e) {
        ValidateDuplicatePeriod(sender, e.Row as KWStoreTrafficEntityDetails);
    }

    // 新增:检查更新行的重复情况
    protected virtual void KWStoreTrafficEntityDetails_RowUpdating(PXCache sender, PXRowUpdatingEventArgs e) {
        ValidateDuplicatePeriod(sender, e.Row as KWStoreTrafficEntityDetails, e.OldRow as KWStoreTrafficEntityDetails);
    }

    // 核心验证方法:检查同一文档下是否存在重复Period
    private void ValidateDuplicatePeriod(PXCache cache, KWStoreTrafficEntityDetails currentRow, KWStoreTrafficEntityDetails oldRow = null) {
        if (currentRow == null || string.IsNullOrEmpty(currentRow.Period)) return;

        // 确定要排除的行号:更新时排除原行,插入时排除当前行(避免自判重复)
        decimal? excludeLineNbr = oldRow?.LineNbr ?? currentRow.LineNbr;

        // 查询当前文档下,Period与当前行相同且不是排除行的记录
        var duplicate = Transactions.SelectSingle(
            new PXDataFieldRestrict<KWStoreTrafficEntityDetails.entityNbr, Equal<Current<KWStoreTrafficEntity.entityNbr>>>,
            new PXDataFieldRestrict<KWStoreTrafficEntityDetails.period, Equal<Required<KWStoreTrafficEntityDetails.period>>>,
            new PXDataFieldRestrict<KWStoreTrafficEntityDetails.lineNbr, NotEqual<Required<KWStoreTrafficEntityDetails.lineNbr>>>()
        );

        if (duplicate != null) {
            // 抛出错误,阻止保存/导入
            cache.RaiseExceptionHandling<KWStoreTrafficEntityDetails.period>(
                currentRow,
                currentRow.Period,
                new PXSetPropertyException("该时间段已存在,无法添加重复记录。", PXErrorLevel.Error)
            );
        }
    }

    protected virtual void KWStoreTrafficEntity_RowPersisting(PXCache sender, PXRowPersistingEventArgs e) {
        KWStoreTrafficEntity row = e.Row as KWStoreTrafficEntity;
        if (row == null) return;

        if(this.IsImport) {
            if (row.EntityDate == null) return;
            foreach(KWStoreTrafficEntityDetails items in this.Transactions.Cache.Cached) {
                PXTrace.WriteInformation(items.Period);
            }
        }

        if ((this.Document.Cache.GetStatus(this.Document.Current) == PXEntryStatus.Inserted || this.Document.Cache.GetStatus(this.Document.Current) == PXEntryStatus.Updated)) {
            decimal? total = default(decimal);
            foreach (KWStoreTrafficEntityDetails items in this.Transactions.Select()) {
                total = total + items.TotalVisitors;
            }
            row.TotalVisitors = total;
        }
    }
    #endregion
}

代码说明

  1. ValidateDuplicatePeriod方法:这是核心的重复检查逻辑,会查询当前文档下是否存在相同Period的记录。更新操作时会排除原来的行,避免修改其他字段时误判为重复。
  2. RowInserting和RowUpdating事件:调用验证方法,在插入或更新行时立即检查重复,界面操作时会即时显示错误提示,导入场景下会终止重复记录的导入并返回错误信息。
  3. 错误抛出:使用PXSetPropertyException抛出错误,确保Acumatica的界面和导入场景都能正确处理这个错误,阻止重复记录被保存。

这样一来,无论是用户在界面手动添加/修改行,还是通过导入场景批量处理数据,都会严格遵循禁止重复的规则啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 12:42:48