如何避免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 }
代码说明
ValidateDuplicatePeriod方法:这是核心的重复检查逻辑,会查询当前文档下是否存在相同Period的记录。更新操作时会排除原来的行,避免修改其他字段时误判为重复。RowInserting和RowUpdating事件:调用验证方法,在插入或更新行时立即检查重复,界面操作时会即时显示错误提示,导入场景下会终止重复记录的导入并返回错误信息。- 错误抛出:使用
PXSetPropertyException抛出错误,确保Acumatica的界面和导入场景都能正确处理这个错误,阻止重复记录被保存。
这样一来,无论是用户在界面手动添加/修改行,还是通过导入场景批量处理数据,都会严格遵循禁止重复的规则啦。
内容的提问来源于stack exchange,提问作者BhavyaSri
相关产品推荐
相关产品推荐

