Skip to main content
Answer

Grid data does not re-appear unless I change data and save

  • October 30, 2025
  • 13 replies
  • 127 views

Hello, I am working on a custom screen that has a parent record and child grid records. I am running into an issue where the grid data does not appear unless I change something in the parent record and then hit save, then the grids populate with the appropriate data. The record previously exists in the database, and I’ve confirmed it. Obviously this is not the behavior we’re looking for.

Another issue is, when I attempt to create a new record in the grid, it follows the same issue. I have to change and save the parent record and then create a new child record in the grid, otherwise it’ll throw an exception saying that the key value is null. I have added a PXParent attribute to the proper field and it works properly when the save trick is done. 

I have a hunch there is something going on with the record loading fully. I added an event handler for the row selected event and then checked that the parent record was loaded, I also check the views for the grids via a .select() to see if they were populated and they have records in them. 

Before save

After save

Graph code:

using System;
using System.Collections;
using System.Linq;
using PX.Data;
using PX.Data.BQL.Fluent;
using PX.Objects.CR;
using static PX.Data.BQL.BqlPlaceholder;

namespace MWIBiddingEngineInternal
{
public class MWBidSheetRegistryEntry : PXGraph<MWBidSheetRegistryEntry, MWBidSheet>
{
#region Views
public SelectFrom<MWBidSheet>.View BidBaseRecords;

public SelectFrom<MWBidSheet>
.Where<MWBidSheet.baseID
.IsEqual<MWBidSheet.bidSheetID.FromCurrent>
.And<MWBidSheet.sheetType.IsEqual<MWBidSheetType.vendorType>>>
.View BidSheets = null!;

public SelectFrom<MWBidLine>
.Where<MWBidLine.bidSheetID
.IsEqual<MWBidSheet.bidSheetID.FromCurrent>>
.View BidLines = null!;

public SelectFrom<MWBidSheetVendorList>
.Where<MWBidSheetVendorList.bidSheetID
.IsEqual<MWBidSheet.bidSheetID.FromCurrent>>
.View VendorListRecords = null!;

//TODO: add prospect vendors
#endregion

#region Event Handlers

protected void _(Events.FieldUpdated<MWBidSheet.customerID> e)
{
var row = e.Row;
e.Cache.SetDefaultExt<MWBidSheet.customerLocationID>(row);
}

protected void _ (Events.FieldUpdated<MWBidSheetVendorList.vendorID> e)
{
var row = e.Row;
e.Cache.SetDefaultExt<MWBidSheetVendorList.vendorLocationID>(row);
}

protected void _(Events.FieldUpdated<MWBidLine.vendorID> e)
{
var row = e.Row;
e.Cache.SetDefaultExt<MWBidLine.vendorLocationID>(row);
}

protected void _(Events.RowSelected<MWBidSheet> e)
{
if (e.Row == null) return;
PXTrace.WriteInformation(e.Row.BidSheetID.ToString());
BidLines.View.RequestRefresh();
VendorListRecords.View.RequestRefresh();
}
#endregion

#region Actions
public PXAction<MWBidSheet> StartBidding = null!;
[PXButton(), PXUIField(
DisplayName = "Start Bidding",
MapEnableRights = PXCacheRights.Select,
MapViewRights = PXCacheRights.Select)]
protected virtual IEnumerable startBidding(PXAdapter adapter) => adapter.Get();

public PXAction<MWBidSheet> ReturnToPlanning = null!;
[PXButton(), PXUIField(
DisplayName = "Return to Planning",
MapEnableRights = PXCacheRights.Select,
MapViewRights = PXCacheRights.Select)]
protected virtual IEnumerable returnToPlanning(PXAdapter adapter) => adapter.Get();

public PXAction<MWBidSheet> CloseBidding = null!;
[PXButton(), PXUIField(
DisplayName = "Close Bidding",
MapEnableRights = PXCacheRights.Select,
MapViewRights = PXCacheRights.Select)]
protected virtual IEnumerable closeBidding(PXAdapter adapter) => adapter.Get();

public PXAction<MWBidSheet> AwardBusiness = null!;
[PXButton(), PXUIField(
DisplayName = "Award Business",
MapEnableRights = PXCacheRights.Select,
MapViewRights = PXCacheRights.Select)]
protected virtual IEnumerable awardBusiness(PXAdapter adapter) => adapter.Get();

public PXAction<MWBidSheet> Abandon = null!;
[PXButton(), PXUIField(
DisplayName = "Abandon",
MapEnableRights = PXCacheRights.Select,
MapViewRights = PXCacheRights.Select)]
protected virtual IEnumerable abandon(PXAdapter adapter) => adapter.Get();

//TODO: not implemented yet
public PXAction<MWBidSheet> GenerateProject = null!;
[PXButton(), PXUIField(
DisplayName = "GenerateProject",
MapEnableRights = PXCacheRights.Select,
MapViewRights = PXCacheRights.Select)]
protected virtual IEnumerable generateProject(PXAdapter adapter) => adapter.Get();

public PXAction<MWBidSheet> CreateBidSheets = null!;
[PXButton(), PXUIField(
DisplayName = "Create Bid Sheets",
MapEnableRights = PXCacheRights.Select,
MapViewRights = PXCacheRights.Select)]
protected virtual IEnumerable createBidSheets(PXAdapter adapter)
{
return adapter.Get();
}

#endregion
}
}

ASPX:

<%@ Page Language="C#" MasterPageFile="~/MasterPages/FormTab.master" AutoEventWireup="true" ValidateRequest="false" CodeFile="MW301000.aspx.cs" Inherits="Page_MW301000" Title="Untitled Page" %>
<%@ MasterType VirtualPath="~/MasterPages/FormTab.master" %>

<asp:Content ID="cont1" ContentPlaceHolderID="phDS" Runat="Server">
<px:PXDataSource ID="ds" runat="server" Visible="True" Width="100%"
TypeName="MWIBiddingEngineInternal.MWBidSheetRegistryEntry"
PrimaryView="BidBaseRecords"
>
<CallbackCommands>

</CallbackCommands>
</px:PXDataSource>
</asp:Content>
<asp:Content ID="cont2" ContentPlaceHolderID="phF" Runat="Server">
<px:PXFormView Caption="Bid Sheet Summary" FilesIndicator="True" NoteIndicator="True" ID="form" runat="server" DataSourceID="ds" DataMember="BidBaseRecords" Width="100%" Height="" AllowAutoHide="false">
<Template>
<px:PXLayoutRule runat="server" ID="CstPXLayoutRule1" StartColumn="True" ></px:PXLayoutRule>
<px:PXNumberEdit runat="server" ID="CstPXNumberEdit13" DataField="BidSheetID" />
<px:PXNumberEdit runat="server" ID="CstPXNumberEdit3" DataField="BaseID" ></px:PXNumberEdit>
<px:PXDropDown runat="server" ID="CstPXDropDown9" DataField="Status" ></px:PXDropDown>
<px:PXLayoutRule runat="server" ID="CstPXLayoutRule2" StartColumn="True" ></px:PXLayoutRule>
<px:PXSegmentMask CommitChanges="True" runat="server" ID="CstPXSegmentMask4" DataField="CustomerID" ></px:PXSegmentMask>
<px:PXSegmentMask CommitChanges="True" runat="server" ID="CstPXSegmentMask5" DataField="CustomerLocationID" ></px:PXSegmentMask>
<px:PXDateTimeEdit runat="server" ID="CstPXDateTimeEdit7" DataField="EndDate" ></px:PXDateTimeEdit>
<px:PXDateTimeEdit runat="server" ID="CstPXDateTimeEdit8" DataField="StartDate" ></px:PXDateTimeEdit></Template>
</px:PXFormView>
</asp:Content>
<asp:Content ID="cont3" ContentPlaceHolderID="phG" Runat="Server">
<px:PXTab ID="tab" runat="server" Width="100%" Height="150px" DataSourceID="ds" AllowAutoHide="false">
<Items>
<px:PXTabItem Text="Template Bid Lines">
<Template>
<px:PXGrid Height="100%" SkinID="DetailsInTab" Width="100%" DataSourceID="ds" SyncPosition="True" runat="server" ID="CstPXGrid10">
<Levels>
<px:PXGridLevel DataMember="BidLines" >
<Columns>
<px:PXGridColumn DataField="BidSheetID" Width="70" />
<px:PXGridColumn DataField="VendorID" Width="140" ></px:PXGridColumn>
<px:PXGridColumn DataField="VendorLocationID" Width="70" ></px:PXGridColumn>
<px:PXGridColumn DataField="Service" Width="220" ></px:PXGridColumn>
<px:PXGridColumn DataField="Equipment" Width="220" ></px:PXGridColumn>
<px:PXGridColumn DataField="HaulFee" Width="100" ></px:PXGridColumn>
<px:PXGridColumn DataField="DisposalFee" Width="100" ></px:PXGridColumn>
<px:PXGridColumn DataField="MiscFee" Width="100" ></px:PXGridColumn>
<px:PXGridColumn DataField="MiscNotes" Width="280" ></px:PXGridColumn></Columns></px:PXGridLevel></Levels>
<AutoSize Enabled="True" /></px:PXGrid></Template>
</px:PXTabItem>
<px:PXTabItem Text="Vendor Bid Sheets">
<Template>
<px:PXGrid SyncPosition="True" DataSourceID="ds" Width="100%" Height="100%" runat="server" ID="CstPXGrid11" SkinID="DetailsInTab">
<Levels>
<px:PXGridLevel DataMember="BidSheets" >
<Columns>
<px:PXGridColumn DataField="BaseID" Width="70" ></px:PXGridColumn>
<px:PXGridColumn DataField="BidSheetID" Width="70" />
<px:PXGridColumn DataField="VendorID" Width="140" ></px:PXGridColumn>
<px:PXGridColumn DataField="VendorLocationID" Width="70" ></px:PXGridColumn></Columns></px:PXGridLevel></Levels>
<AutoSize Enabled="True" /></px:PXGrid></Template>
</px:PXTabItem>
<px:PXTabItem Text="Candidate Vendors" >
<Template>
<px:PXGrid DataSourceID="ds" SyncPosition="True" runat="server" ID="CstPXGrid12" SkinID="DetailsInTab" Height="100%" Width="100%">
<Levels>
<px:PXGridLevel DataMember="VendorListRecords" >
<Columns>
<px:PXGridColumn DataField="BidSheetID" Width="70" />
<px:PXGridColumn DataField="VendorID" Width="140" ></px:PXGridColumn>
<px:PXGridColumn DataField="VendorLocationID" Width="70" ></px:PXGridColumn></Columns></px:PXGridLevel></Levels>
<AutoSize Enabled="True" ></AutoSize></px:PXGrid></Template></px:PXTabItem></Items>
<AutoSize Container="Window" Enabled="True" MinHeight="150" ></AutoSize>
</px:PXTab>
</asp:Content>


MWBidSheet DAC
 

using MWIBiddingEngineInternal.Helpers;
using PX.Data;
using PX.Objects.AP;
using PX.Objects.AR;
using PX.Objects.CR;
using PX.Objects.CS;
using System;

namespace MWIBiddingEngineInternal
{
[Serializable]
[PXCacheName("MWBidSheet")]
[PXPrimaryGraph(typeof(MWBidSheetRegistryEntry))]
public class MWBidSheet : PXBqlTable, IBqlTable
{
//TODO add description and or CD
#region BidSheetID
[PXDBIdentity(IsKey = true)]
[PXUIField(DisplayName = "Bid Sheet ID", Enabled = false)]
public virtual int? BidSheetID { get; set; }
public abstract class bidSheetID : PX.Data.BQL.BqlInt.Field<bidSheetID> { }
#endregion

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

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

#region Status
[PXDBString(2, IsUnicode = true, IsFixed = false)]
[PXUIField(DisplayName = "Status", Enabled = false)]
[PXDefault(BidSheetConstants.Planning)]
[PXStringList(
new string[]
{
BidSheetConstants.Planning,
BidSheetConstants.Open,
BidSheetConstants.PendingAward,
BidSheetConstants.BusinessAwarded,
BidSheetConstants.Cancelled,
BidSheetConstants.Completed
}, new string[]
{
Messages.Planning,
Messages.Open,
Messages.PendingAward,
Messages.BusinessAwarded,
Messages.Cancelled,
Messages.Completed
})]
public virtual string Status { get; set; }
public abstract class status : PX.Data.BQL.BqlString.Field<status> { }
#endregion

#region BaseID
[PXDBInt()]
[PXUIField(DisplayName = "BaseID", Enabled = false)]
public virtual int? BaseID { get; set; }
public abstract class baseID : PX.Data.BQL.BqlInt.Field<baseID> { }
#endregion

#region VendorID
[VendorActive(DisplayName = "Vendor", DescriptionField = typeof(BAccount.acctName))]
public virtual int? VendorID { get; set; }
public abstract class vendorID : PX.Data.BQL.BqlInt.Field<vendorID> { }
#endregion

#region VendorLocationID
[LocationActive(typeof(Where<Location.bAccountID, Equal<Current<vendorID>>>), DisplayName = "Vendor Location", DescriptionField = typeof(Location.descr))]
[PXDefault(typeof(Search<Vendor.defLocationID, Where<Vendor.bAccountID, Equal<Current<vendorID>>>>), PersistingCheck = PXPersistingCheck.Nothing)]
public virtual int? VendorLocationID { get; set; }
public abstract class vendorLocationID : PX.Data.BQL.BqlInt.Field<vendorLocationID> { }
#endregion

#region CustomerID
[CustomerActive(DescriptionField = typeof(Customer.acctName))]
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>>>), DisplayName = "Customer Location", DescriptionField = typeof(Location.descr))]
[PXDefault(typeof(Search<Customer.defLocationID, Where<Customer.bAccountID, Equal<Current<customerID>>>>), PersistingCheck = PXPersistingCheck.Nothing)]
public virtual int? CustomerLocationID { get; set; }
public abstract class customerLocationID : PX.Data.BQL.BqlInt.Field<customerLocationID> { }
#endregion

#region LineCntr
[PXDBInt]
[PXDefault(0)]
public virtual int? LineCntr { get; set; }
public abstract class lineCntr : PX.Data.BQL.BqlInt.Field<lineCntr> { }
#endregion

#region SheetType
[PXDBString(2, IsUnicode = true, IsFixed = false)]
[PXUIField(DisplayName = "Sheet Type")]
[MWBidSheetType.List] // Dropdown from constants
[PXDefault(MWBidSheetType.Base)] // Optional, remove if not needed
public virtual string SheetType { get; set; }
public abstract class sheetType : PX.Data.BQL.BqlString.Field<sheetType> { }
#endregion

#region Metadata
#region Noteid
[PXNote()]
public virtual Guid? Noteid { get; set; }
public abstract class noteid : PX.Data.BQL.BqlGuid.Field<noteid> { }
#endregion



#region CreatedByID
[PXDBCreatedByID()]
public virtual Guid? CreatedByID { get; set; }
public abstract class createdByID : PX.Data.BQL.BqlGuid.Field<createdByID> { }
#endregion

#region CreatedByScreenID
[PXDBCreatedByScreenID()]
public virtual string CreatedByScreenID { get; set; }
public abstract class createdByScreenID : PX.Data.BQL.BqlString.Field<createdByScreenID> { }
#endregion

#region CreatedDateTime
[PXDBCreatedDateTime()]
public virtual DateTime? CreatedDateTime { get; set; }
public abstract class createdDateTime : PX.Data.BQL.BqlDateTime.Field<createdDateTime> { }
#endregion

#region LastModifiedByID
[PXDBLastModifiedByID()]
public virtual Guid? LastModifiedByID { get; set; }
public abstract class lastModifiedByID : PX.Data.BQL.BqlGuid.Field<lastModifiedByID> { }
#endregion

#region LastModifiedByScreenID
[PXDBLastModifiedByScreenID()]
public virtual string LastModifiedByScreenID { get; set; }
public abstract class lastModifiedByScreenID : PX.Data.BQL.BqlString.Field<lastModifiedByScreenID> { }
#endregion

#region LastModifiedDateTime
[PXDBLastModifiedDateTime()]
public virtual DateTime? LastModifiedDateTime { get; set; }
public abstract class lastModifiedDateTime : PX.Data.BQL.BqlDateTime.Field<lastModifiedDateTime> { }
#endregion

#region Tstamp
[PXDBTimestamp()]
[PXUIField(DisplayName = "Tstamp")]
public virtual byte[] Tstamp { get; set; }
public abstract class tstamp : PX.Data.BQL.BqlByteArray.Field<tstamp> { }
#endregion
#endregion
}
}

MWBidLine DAC
 

using PX.Data;
using PX.Objects.AP;
using PX.Objects.CS;
using System;
using PX.Objects.AR;
using PX.Objects.CR;
using MWIBiddingEngineInternal.Helpers;

namespace MWIBiddingEngineInternal
{
[Serializable]
[PXCacheName("MWBidLine")]
public class MWBidLine : PXBqlTable, IBqlTable
{
#region BidLineID
[PXDBIdentity()]
public virtual int? BidLineID { get; set; }
public abstract class bidLineID : PX.Data.BQL.BqlInt.Field<bidLineID> { }
#endregion

#region BidSheetID
[PXDBInt()]
[PXUIField(DisplayName = "Bid Sheet ID", Enabled = false)]
[PXDBDefault(typeof(MWBidSheet.bidSheetID))]
[PXParent(typeof(Select<MWBidSheet,
Where<MWBidSheet.bidSheetID, Equal<Current<MWBidLine.bidSheetID>>>>))]
public virtual int? BidSheetID { get; set; }
public abstract class bidSheetID : PX.Data.BQL.BqlInt.Field<bidSheetID> { }
#endregion

#region VendorID
[VendorActive(DisplayName = "Vendor", DescriptionField = typeof(BAccount.acctName))]
public virtual int? VendorID { get; set; }
public abstract class vendorID : PX.Data.BQL.BqlInt.Field<vendorID> { }
#endregion

#region VendorLocationID
[LocationActive(typeof(Where<Location.bAccountID, Equal<Current<vendorID>>>), DisplayName = "Vendor Location", DescriptionField = typeof(Location.descr))]
[PXDefault(typeof(Search<Vendor.defLocationID, Where<Vendor.bAccountID, Equal<Current<vendorID>>>>), PersistingCheck = PXPersistingCheck.Nothing)]
public virtual int? VendorLocationID { get; set; }
public abstract class vendorLocationID : PX.Data.BQL.BqlInt.Field<vendorLocationID> { }
#endregion

#region LineNbr
/// <inheritdoc cref="LineNbr"/>
public abstract class lineNbr : PX.Data.BQL.BqlInt.Field<lineNbr> { }
protected Int32? _LineNbr;

/// <summary>
/// The line number of the bidsheet.
/// </summary>
[PXDBInt(IsKey = true)]
[PXLineNbr(typeof(MWBidSheet.lineCntr))]
[PXUIField(DisplayName = "Line Nbr.", Visible = false)]
public virtual Int32? LineNbr
{
get
{
return this._LineNbr;
}
set
{
this._LineNbr = value;
}
}
#endregion

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

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

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

#region MiscNotes
[PXDBString(255, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Misc Notes")]
public virtual string MiscNotes { get; set; }
public abstract class miscNotes : PX.Data.BQL.BqlString.Field<miscNotes> { }
#endregion

#region Equipment
[PXDBString(60, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Equipment")]
public virtual string Equipment { get; set; }
public abstract class equipment : PX.Data.BQL.BqlString.Field<equipment> { }
#endregion

#region Service
[PXDBString(60, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Service")]
public virtual string Service { get; set; }
public abstract class service : PX.Data.BQL.BqlString.Field<service> { }
#endregion

#region ServiceScheduleType
[PXDBString(15, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Service Schedule Type")]
public virtual string ServiceScheduleType { get; set; }
public abstract class serviceScheduleType : PX.Data.BQL.BqlString.Field<serviceScheduleType> { }
#endregion

#region ServiceDaysMask
[PXDBInt()]
[PXUIField(DisplayName = "Service Days Mask")]
public virtual int? ServiceDaysMask { get; set; }
public abstract class serviceDaysMask : PX.Data.BQL.BqlInt.Field<serviceDaysMask> { }
#endregion

#region RecurrenceIntervalWeek
[PXDBInt()]
[PXUIField(DisplayName = "Recurrence Interval Week")]
public virtual int? RecurrenceIntervalWeek { get; set; }
public abstract class recurrenceIntervalWeek : PX.Data.BQL.BqlInt.Field<recurrenceIntervalWeek> { }
#endregion

#region Noteid
[PXNote()]
public virtual Guid? Noteid { get; set; }
public abstract class noteid : PX.Data.BQL.BqlGuid.Field<noteid> { }
#endregion

#region CreatedByID
[PXDBCreatedByID()]
public virtual Guid? CreatedByID { get; set; }
public abstract class createdByID : PX.Data.BQL.BqlGuid.Field<createdByID> { }
#endregion

#region CreatedByScreenID
[PXDBCreatedByScreenID()]
public virtual string CreatedByScreenID { get; set; }
public abstract class createdByScreenID : PX.Data.BQL.BqlString.Field<createdByScreenID> { }
#endregion

#region CreatedDateTime
[PXDBCreatedDateTime()]
public virtual DateTime? CreatedDateTime { get; set; }
public abstract class createdDateTime : PX.Data.BQL.BqlDateTime.Field<createdDateTime> { }
#endregion

#region LastModifiedByID
[PXDBLastModifiedByID()]
public virtual Guid? LastModifiedByID { get; set; }
public abstract class lastModifiedByID : PX.Data.BQL.BqlGuid.Field<lastModifiedByID> { }
#endregion

#region LastModifiedByScreenID
[PXDBLastModifiedByScreenID()]
public virtual string LastModifiedByScreenID { get; set; }
public abstract class lastModifiedByScreenID : PX.Data.BQL.BqlString.Field<lastModifiedByScreenID> { }
#endregion

#region LastModifiedDateTime
[PXDBLastModifiedDateTime()]
public virtual DateTime? LastModifiedDateTime { get; set; }
public abstract class lastModifiedDateTime : PX.Data.BQL.BqlDateTime.Field<lastModifiedDateTime> { }
#endregion

#region Tstamp
[PXDBTimestamp()]
[PXUIField(DisplayName = "Tstamp")]
public virtual byte[] Tstamp { get; set; }
public abstract class tstamp : PX.Data.BQL.BqlByteArray.Field<tstamp> { }
#endregion
}
}

 

Best answer by aleksejslusar19

Hi ​@tyrussonneborn 

I think I've figured out what your problem is.

Look, the primary keys for master-detail tables in the database need to be defined in a specific way (pay attention to the keys definition).

  1. For [MWBidSheet], a single primary key is defined in the DB, and it's configured correctly in the DAC. That part is right.
     

    CREATE TABLE [dbo].[MWBidSheet](
    [CompanyID] [int] NOT NULL,
    [BidSheetID] [int] IDENTITY(1,1) NOT NULL,
    [StartDate] [datetime] NULL,
    [EndDate] [datetime] NULL,
    [Status] [nvarchar](2) NULL,
    [BaseID] [int] NULL,
    [VendorID] [int] NULL,
    [VendorLocationID] [int] NULL,
    [CustomerID] [int] NULL,
    [CustomerLocationID] [int] NULL,
    [LineCntr] [int] NOT NULL,
    [SheetType] [nvarchar](2) NULL,
    [Noteid] [uniqueidentifier] NULL,
    [CreatedByID] [uniqueidentifier] NULL,
    [CreatedByScreenID] [nvarchar](8) NULL,
    [CreatedDateTime] [datetime] NULL,
    [LastModifiedByID] [uniqueidentifier] NULL,
    [LastModifiedByScreenID] [nvarchar](8) NULL,
    [LastModifiedDateTime] [datetime] NULL,
    [Tstamp] [timestamp] NOT NULL,
    CONSTRAINT [MWBidSheet_PK] PRIMARY KEY CLUSTERED
    (
    [CompanyID] ASC,
    [BidSheetID] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
    ) ON [PRIMARY]
    GO

    ALTER TABLE [dbo].[MWBidSheet] ADD DEFAULT ((0)) FOR [LineCntr]
    GO
    [Serializable]
    [PXCacheName("MWBidSheet")]
    [PXPrimaryGraph(typeof(MWBidSheetRegistryEntry))]
    public class MWBidSheet : PXBqlTable, IBqlTable
    {
    // TODO add description and or CD

    #region BidSheetID

    [PXDBIdentity(IsKey = true)]
    [PXUIField(DisplayName = "Bid Sheet ID", Enabled = false)]
    public virtual int? BidSheetID { get; set; }
    public abstract class bidSheetID : PX.Data.BQL.BqlInt.Field<bidSheetID> { }

    #endregion
    }

     

  2. For MWBidLine, the primary key is composite, made up of BidLineID, BidSheetID, and LineNbr. Therefore, in the DAC, these fields must all be marked as key fields.
     

    CREATE TABLE [dbo].[MWBidLine](
    [CompanyID] [int] NOT NULL,
    [BidLineID] [int] IDENTITY(1,1) NOT NULL,
    [BidSheetID] [int] NOT NULL,
    [LineNbr] [int] NOT NULL,
    [VendorID] [int] NULL,
    [VendorLocationID] [int] NULL,
    [HaulFee] [decimal](18, 2) NULL,
    [DisposalFee] [decimal](18, 2) NULL,
    [MiscFee] [decimal](18, 2) NULL,
    [MiscNotes] [nvarchar](255) NULL,
    [Equipment] [nvarchar](60) NULL,
    [Service] [nvarchar](60) NULL,
    [ServiceScheduleType] [nvarchar](15) NULL,
    [ServiceDaysMask] [int] NULL,
    [RecurrenceIntervalWeek] [int] NULL,
    [Noteid] [uniqueidentifier] NULL,
    [CreatedByID] [uniqueidentifier] NULL,
    [CreatedByScreenID] [nvarchar](8) NULL,
    [CreatedDateTime] [datetime] NULL,
    [LastModifiedByID] [uniqueidentifier] NULL,
    [LastModifiedByScreenID] [nvarchar](8) NULL,
    [LastModifiedDateTime] [datetime] NULL,
    [Tstamp] [timestamp] NOT NULL,
    CONSTRAINT [MWBidLine_PK] PRIMARY KEY CLUSTERED
    (
    [CompanyID] ASC,
    [BidLineID] ASC,
    [BidSheetID] ASC,
    [LineNbr] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
    ) ON [PRIMARY]
    GO
    [Serializable]
    [PXCacheName("MWBidLine")]
    public class MWBidLine : PXBqlTable, IBqlTable

    {
    #region BidLineID
    [PXDBIdentity(IsKey = true)]
    [PXUIField(DisplayName = "Bid Line ID", Visible = false)]
    public virtual int? BidLineID { get; set; }
    public abstract class bidLineID : PX.Data.BQL.BqlInt.Field<bidLineID> { }
    #endregion

    #region BidSheetID
    [PXDBInt(IsKey = true)]
    [PXUIField(DisplayName = "Bid Sheet ID", Enabled = false)]
    [PXDBDefault(typeof(MWBidSheet.bidSheetID))]
    [PXParent(typeof(Select<MWBidSheet,
    Where<MWBidSheet.bidSheetID, Equal<Current<bidSheetID>>>>))]
    public virtual int? BidSheetID { get; set; }
    public abstract class bidSheetID : PX.Data.BQL.BqlInt.Field<bidSheetID> { }
    #endregion

    #region LineNbr
    public abstract class lineNbr : PX.Data.BQL.BqlInt.Field<lineNbr> { }
    protected int? _LineNbr;
    /// <summary>
    /// The line number of the bidsheet.
    /// </summary>
    [PXDBInt(IsKey = true)]
    [PXLineNbr(typeof(MWBidSheet.lineCntr))]
    [PXUIField(DisplayName = "Line Nbr.", Visible = false)]
    public virtual int? LineNbr
    {
    get
    {
    return _LineNbr;
    }
    set
    {
    _LineNbr = value;
    }
    }

    #endregion
    }

    That's basically it. After these changes, the records save and display correctly on the screen.
     

    Everything is fine in the database too.
     

     

I've attached an archive with my test project. The src and cst folders contain the source code for the customization and the extension libraries. The pkg folder contains the customization package.

Let me know if you have any questions.

13 replies

darylbowman
Captain II
Forum|alt.badge.img+15

Is this by any chance AI-generated code? You’re using = null! all over the place. This is not an Acumatica framework practice.


Forum|alt.badge.img+3

It would be useful to look at the MWBidSheet and MWBidLine DACs code as well.


  • Author
  • Freshman I
  • October 30, 2025

@darylbowman I was following along the examples in the training series. For example views and actions in the RSSVWorkOrderEntry:
 

 

 


  • Author
  • Freshman I
  • October 30, 2025

@aleksandrsechin added details to main post


darylbowman
Captain II
Forum|alt.badge.img+15

Is this by any chance AI-generated code? You’re using = null! all over the place. This is not an Acumatica framework practice.

@darylbowman I was following along the examples in the training series. For example views and actions in the RSSVWorkOrderEntry:

 

@Dmitrii Naumov - Is this something new? I see it several places in source in 25 R1/2, but I’ve not seen it before.


darylbowman
Captain II
Forum|alt.badge.img+15

I’m confused on the MWBidLine. You have an auto-generated key (BidLineID) but you have IsKey set on the LineNbr field. Why is that?


  • Author
  • Freshman I
  • October 30, 2025

I’m confused on the MWBidLine. You have an auto-generated key (BidLineID) but you have IsKey set on the LineNbr field. Why is that?

@darylbowman likely an artifact of me learning how line numbering works. I originally was going to leave the lines with an ID, but discovered the line number pattern and just haven’t cleaned it up yet. Would this cause the grids to not load? Another thing I’m noticing is the caption above the action bar is “Bid Sheet Registry” before I save, and then the ID after I save, it seems that the record is in a strange partially loaded limbo state. 


Forum|alt.badge.img+3

I can see that the master-detail relationships are defined incorrectly. Try the following steps:
1. Add the IsKey=true property to the MWBidLine.BidSheetID field.
2. Remove MWBidLine.BidLineID (if possible). I don’t think it’s necessary.
 

 


darylbowman
Captain II
Forum|alt.badge.img+15

Would this cause the grids to not load?

Unfortunately, there are many things in the Acumatica framework that are extremely sensitive to following patterns exactly as they are expected. I can’t say it would or it wouldn’t. I’ve seen stranger things arise from less. Essentially, I would assume the framework is trying to use a different key than the database.

I would remove the auto-generated key and use the BidSheetID and LineNbr as the keys. Make sure the DAC reflects the database.


  • Author
  • Freshman I
  • October 30, 2025

I can see that the master-detail relationships are defined incorrectly. Try the following steps:
1. Add the IsKey=true property to the MWBidLine.BidSheetID field.
2. Remove MWBidLine.BidLineID (if possible). I don’t think it’s necessary.

@aleksandrsechin makes sense! Your suggested changes didn’t break anything at least lol! Still running into the same issue


Forum|alt.badge.img+3

I’m not sure if RequestRefresh is needed in the RowSelected event handler. Try commenting it out, and if the issue is not resolved, we can dig deeper.


Forum|alt.badge.img+1
  • Jr Varsity III
  • Answer
  • October 31, 2025

Hi ​@tyrussonneborn 

I think I've figured out what your problem is.

Look, the primary keys for master-detail tables in the database need to be defined in a specific way (pay attention to the keys definition).

  1. For [MWBidSheet], a single primary key is defined in the DB, and it's configured correctly in the DAC. That part is right.
     

    CREATE TABLE [dbo].[MWBidSheet](
    [CompanyID] [int] NOT NULL,
    [BidSheetID] [int] IDENTITY(1,1) NOT NULL,
    [StartDate] [datetime] NULL,
    [EndDate] [datetime] NULL,
    [Status] [nvarchar](2) NULL,
    [BaseID] [int] NULL,
    [VendorID] [int] NULL,
    [VendorLocationID] [int] NULL,
    [CustomerID] [int] NULL,
    [CustomerLocationID] [int] NULL,
    [LineCntr] [int] NOT NULL,
    [SheetType] [nvarchar](2) NULL,
    [Noteid] [uniqueidentifier] NULL,
    [CreatedByID] [uniqueidentifier] NULL,
    [CreatedByScreenID] [nvarchar](8) NULL,
    [CreatedDateTime] [datetime] NULL,
    [LastModifiedByID] [uniqueidentifier] NULL,
    [LastModifiedByScreenID] [nvarchar](8) NULL,
    [LastModifiedDateTime] [datetime] NULL,
    [Tstamp] [timestamp] NOT NULL,
    CONSTRAINT [MWBidSheet_PK] PRIMARY KEY CLUSTERED
    (
    [CompanyID] ASC,
    [BidSheetID] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
    ) ON [PRIMARY]
    GO

    ALTER TABLE [dbo].[MWBidSheet] ADD DEFAULT ((0)) FOR [LineCntr]
    GO
    [Serializable]
    [PXCacheName("MWBidSheet")]
    [PXPrimaryGraph(typeof(MWBidSheetRegistryEntry))]
    public class MWBidSheet : PXBqlTable, IBqlTable
    {
    // TODO add description and or CD

    #region BidSheetID

    [PXDBIdentity(IsKey = true)]
    [PXUIField(DisplayName = "Bid Sheet ID", Enabled = false)]
    public virtual int? BidSheetID { get; set; }
    public abstract class bidSheetID : PX.Data.BQL.BqlInt.Field<bidSheetID> { }

    #endregion
    }

     

  2. For MWBidLine, the primary key is composite, made up of BidLineID, BidSheetID, and LineNbr. Therefore, in the DAC, these fields must all be marked as key fields.
     

    CREATE TABLE [dbo].[MWBidLine](
    [CompanyID] [int] NOT NULL,
    [BidLineID] [int] IDENTITY(1,1) NOT NULL,
    [BidSheetID] [int] NOT NULL,
    [LineNbr] [int] NOT NULL,
    [VendorID] [int] NULL,
    [VendorLocationID] [int] NULL,
    [HaulFee] [decimal](18, 2) NULL,
    [DisposalFee] [decimal](18, 2) NULL,
    [MiscFee] [decimal](18, 2) NULL,
    [MiscNotes] [nvarchar](255) NULL,
    [Equipment] [nvarchar](60) NULL,
    [Service] [nvarchar](60) NULL,
    [ServiceScheduleType] [nvarchar](15) NULL,
    [ServiceDaysMask] [int] NULL,
    [RecurrenceIntervalWeek] [int] NULL,
    [Noteid] [uniqueidentifier] NULL,
    [CreatedByID] [uniqueidentifier] NULL,
    [CreatedByScreenID] [nvarchar](8) NULL,
    [CreatedDateTime] [datetime] NULL,
    [LastModifiedByID] [uniqueidentifier] NULL,
    [LastModifiedByScreenID] [nvarchar](8) NULL,
    [LastModifiedDateTime] [datetime] NULL,
    [Tstamp] [timestamp] NOT NULL,
    CONSTRAINT [MWBidLine_PK] PRIMARY KEY CLUSTERED
    (
    [CompanyID] ASC,
    [BidLineID] ASC,
    [BidSheetID] ASC,
    [LineNbr] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
    ) ON [PRIMARY]
    GO
    [Serializable]
    [PXCacheName("MWBidLine")]
    public class MWBidLine : PXBqlTable, IBqlTable

    {
    #region BidLineID
    [PXDBIdentity(IsKey = true)]
    [PXUIField(DisplayName = "Bid Line ID", Visible = false)]
    public virtual int? BidLineID { get; set; }
    public abstract class bidLineID : PX.Data.BQL.BqlInt.Field<bidLineID> { }
    #endregion

    #region BidSheetID
    [PXDBInt(IsKey = true)]
    [PXUIField(DisplayName = "Bid Sheet ID", Enabled = false)]
    [PXDBDefault(typeof(MWBidSheet.bidSheetID))]
    [PXParent(typeof(Select<MWBidSheet,
    Where<MWBidSheet.bidSheetID, Equal<Current<bidSheetID>>>>))]
    public virtual int? BidSheetID { get; set; }
    public abstract class bidSheetID : PX.Data.BQL.BqlInt.Field<bidSheetID> { }
    #endregion

    #region LineNbr
    public abstract class lineNbr : PX.Data.BQL.BqlInt.Field<lineNbr> { }
    protected int? _LineNbr;
    /// <summary>
    /// The line number of the bidsheet.
    /// </summary>
    [PXDBInt(IsKey = true)]
    [PXLineNbr(typeof(MWBidSheet.lineCntr))]
    [PXUIField(DisplayName = "Line Nbr.", Visible = false)]
    public virtual int? LineNbr
    {
    get
    {
    return _LineNbr;
    }
    set
    {
    _LineNbr = value;
    }
    }

    #endregion
    }

    That's basically it. After these changes, the records save and display correctly on the screen.
     

    Everything is fine in the database too.
     

     

I've attached an archive with my test project. The src and cst folders contain the source code for the customization and the extension libraries. The pkg folder contains the customization package.

Let me know if you have any questions.


  • Author
  • Freshman I
  • November 4, 2025

Hi ​@tyrussonneborn 

I think I've figured out what your problem is.

Look, the primary keys for master-detail tables in the database need to be defined in a specific way (pay attention to the keys definition).

 

@aleksejslusar19 that did the trick! Thank you loads!