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

Acumatica维护页保存时自动添加空白行报错问题排查

Acumatica维护页面保存时自动添加空白行并报错的排查方案

我有一个极简的Acumatica维护页面,未配置任何事件,页面代码如下:

public PXCancel<RCDistributorSalesStat> Cancel;
public PXSave<RCDistributorSalesStat> Save;

public SelectFrom<RCDistributorSalesStat>.View Records;

每次保存第一条输入的记录时,系统会自动添加一条空白行,并抛出必填字段缺失的错误。之前排查过类似问题是多主键导致,但我仅设置了一个主键:

#region DistributorSalesStatID
[PXDBIdentity(IsKey = true)]
public virtual int? DistributorSalesStatID { get; set; }
public abstract class distributorSalesStatID : PX.Data.BQL.BqlInt.Field<distributorSalesStatID> { }
#endregion

#region InventoryID
[StockItem(Visibility = PXUIVisibility.SelectorVisible, DescriptionField = typeof(InventoryItem.inventoryCD), Enabled = true)]
[PXRestrictor(typeof(Where<InventoryItem.baseUnit.IsEqual<BQLConstants.Straw>>), null)]
[PXForeignReference(typeof(Field<inventoryID>.IsRelatedTo<InventoryItem.inventoryID>))]
public virtual int? InventoryID { get; set; }
public abstract class inventoryID : PX.Data.BQL.BqlInt.Field<inventoryID> { }
#endregion

#region StatisticDate
[PXDBDate()]
[PXUIField(DisplayName = "Statistic Date")]
public virtual DateTime? StatisticDate { get; set; }
public abstract class statisticDate : PX.Data.BQL.BqlDateTime.Field<statisticDate> { }
#endregion

#region CustomerID
[CustomerActive(
    //typeof(Search<BAccountR.bAccountID, Where<True, Equal<True>>>),
    Visibility = PXUIVisibility.SelectorVisible,
    DescriptionField = typeof(Customer.acctName),
    Filterable = true) ]
//[CustomerOrOrganizationInNoUpdateDocRestrictor]
[PXForeignReference(typeof(Field<RCDistributorSalesStat.customerID>.IsRelatedTo<PXAccess.BAccount.bAccountID>))]
public virtual int? CustomerID { get; set; }
public abstract class customerID : PX.Data.BQL.BqlInt.Field<customerID> { }
#endregion

#region CustomerLocationID
[LocationActive(typeof(Where<Location.bAccountID, Equal<Current<customerID>>,
        And<MatchWithBranch<Location.cBranchID>>>),
    DescriptionField = typeof(Location.descr),
    Visibility = PXUIVisibility.SelectorVisible)]
[PXDefault(typeof(Coalesce<Search2<BAccountR.defLocationID,
        InnerJoin<CRLocation, On<CRLocation.bAccountID, Equal<BAccountR.bAccountID>, And<CRLocation.locationID, Equal<BAccountR.defLocationID>>>>,
        Where<BAccountR.bAccountID, Equal<Current<customerID>>,
            And<CRLocation.isActive, Equal<True>,
                And<MatchWithBranch<CRLocation.cBranchID>>>>>,
    Search<CRLocation.locationID,
        Where<CRLocation.bAccountID, Equal<Current<customerID>>,
            And<CRLocation.isActive, Equal<True>, And<MatchWithBranch<CRLocation.cBranchID>>>>>>>>))]
[PXForeignReference(
    typeof(CompositeKey<
        Field<customerID>.IsRelatedTo<Location.bAccountID>,
        Field<customerLocationID>.IsRelatedTo<Location.locationID>
    >))]
public virtual int? CustomerLocationID { get; set; }
public abstract class customerLocationID : PX.Data.BQL.BqlInt.Field<customerLocationID> { }
#endregion

#region SalesAmount
[PXDBDecimal()]
[PXUIField(DisplayName = "Sales Amount")]
public virtual Decimal? SalesAmount { get; set; }
public abstract class salesAmount : PX.Data.BQL.BqlDecimal.Field<salesAmount> { }
#endregion

#region SalesUnits
[PXDBInt()]
[PXUIField(DisplayName = "Sales Units")]
public virtual int? SalesUnits { get; set; }
public abstract class salesUnits : PX.Data.BQL.BqlInt.Field<salesUnits> { }
#endregion

#region QuantityOnHand
[PXDBInt()]
[PXUIField(DisplayName = "Quantity On Hand")]
public virtual int? QuantityOnHand { get; set; }
public abstract class quantityOnHand : PX.Data.BQL.BqlInt.Field<quantityOnHand> { }
#endregion

以下是具体排查方向:

  • 检查字段的必填约束:确认数据库表中是否有字段被设置为NOT NULL,但DAC中未添加[PXDefault]或AllowNull = false的显式配置。比如InventoryID、StatisticDate这类核心字段,数据库层面的必填会导致系统尝试插入空白记录时触发验证错误。
  • 排查PXDefault的自动触发逻辑:CustomerLocationID的默认值使用了复杂的联合查询,当选择客户后,该默认值逻辑可能意外在缓存中创建了新的空白记录。可以临时注释掉CustomerLocationID的PXDefault属性,测试保存是否正常。
  • 调整视图的缓存配置:尝试将页面中的视图从新BQL语法改为旧语法:public PXSelect<RCDistributorSalesStat> Records;,部分版本中,新BQL的SelectFrom视图在缓存处理上可能存在差异,导致自动创建空白行。
  • 验证数据库表结构:直接查看数据库中RCDistributorSalesStat表的主键设置,确保只有DistributorSalesStatID是主键,没有隐性的联合主键约束,避免DAC配置与数据库实际结构不一致。
  • 简化场景测试:创建一个仅包含主键和单个必填字段的极简DAC及对应页面,测试保存行为是否正常。如果正常,再逐步添加其他字段,定位到引发问题的具体字段配置。
  • 检查版本兼容性:部分旧版Acumatica在使用PXDBIdentity作为主键搭配复杂默认值时,存在自动创建空白记录的已知bug,确认当前使用的版本是否有对应的补丁可用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 12:10:57