Skip to main content

How To Run an Event Handler Once per Screen Load

  • April 11, 2025
  • 1 reply
  • 171 views

Forum|alt.badge.img+8

Hello everyone,

 

I am sure we all have events we would want to run once per screen load, unfortunately, we do not have a ScreenLoaded event or anything of that sort.

 

To overcome this you can create a non-persisted bool.

#region TrueFalse
public abstract class trueFalse : BqlBool.Field<trueFalse> { }
[PXBool]
[PXUIField(Display Name ="True/False", Enabled = false, Visible = false)]
public virtual bool? TrueFalse { get; set; }
#endregion

Then you can control the value of this with a RowSelected event handler

protected virtual void _(Events.RowSelected<YourDAC> e)
{
YourDAC row = e.Row;
if(row == null) return;

if(row.TrueFalse != true)
{
row.TrueFalse = true;
}

else return;
}

This field value will hold until the screen is refreshed, however, when it is refreshed it will trigger the RowSelected handler again and set the value to true.

 

You could also update the field value within the handler that executes your logic, in this case my non-persisted bool is UsrCreditHold and use an if() to determine whether the logic is executed based on your field.

protected virtual void _(Events.RowPersisting<SOShipment> e, PXRowPersisting b)
{
b?.Invoke(e.Cache, e.Args);
SOShipment row = e.Row;
if (row == null) return;

SOShipmentCreditHold rowExt = row.GetExtension<SOShipmentCreditHold>();

if (rowExt.UsrCreditHold != true)
{
ARBalances remBal = SelectFrom<ARBalances>.
Where<ARBalances.customerID.IsEqual<P.AsInt>.
And<ARBalances.customerLocationID.IsEqual<P.AsInt>>>.View.Select(Base, row.CustomerID, row.CustomerLocationID);

if (remBal == null) return;

Customer customer = SelectFrom<Customer>.
Where<Customer.bAccountID.IsEqual<P.AsInt>>.View.Select(Base, row.CustomerID);
if (customer == null) return;

var creditLimit = customer.CreditLimit;
var balance = creditLimit - ((remBal.CurrentBal ?? 0) + (remBal.TotalOpenOrders ?? 0) + (remBal.TotalShipped ?? 0) - (remBal.TotalPrepayments ?? 0));


}


var query = SelectFrom<SOShipment>
.InnerJoin<Customer>
.On<Customer.bAccountID.IsEqual<P.AsInt>>
.InnerJoin<ARBalances>
.On<ARBalances.customerID.IsEqual<P.AsInt>>
.AggregateTo<GroupBy<SOShipment.customerID, Avg<Customer.creditLimit>>>.View.Select(Base, row.CustomerID, row.CustomerID);



foreach (PXResult<SOShipment, Customer, ARBalances> result in query)
{

SOShipment shipment = result;
Customer cust = result;
ARBalances arBal = result;

decimal? currentBalSum = arBal.CurrentBal ?? 0m;
decimal? totalOpenOrdersSum = arBal.TotalOpenOrders ?? 0m;
decimal? totalShippedSum = arBal.TotalShipped ?? 0m;
decimal? totalPrepaymentsSum = arBal.TotalPrepayments ?? 0m;
decimal? creditLimit = cust.CreditLimit ?? 0m;

decimal? bal = creditLimit - ((currentBalSum + totalOpenOrdersSum + totalShippedSum) - totalPrepaymentsSum);

if (balance < 0)
{
if(rowExt.UsrCreditHold != true)
{
e.Cache.SetValueExt<SOShipmentCreditHold.usrCreditHold>(rowExt.UsrCreditHold, true);



SOShipmentCreditHold.MyEvents
.Select(events => events.CreditLimitViolated)
.FireOn(Base, row);
}

}
}

}

This is particularly useful with event handlers that are called many times during a session but you may not want the logic executed every time.

 

I hope this helps someone!

1 reply

Chris Hackett
Community Manager
Forum|alt.badge.img
  • Acumatica Community Manager
  • May 7, 2025

Thank you for sharing this great information with the community ​@aiwan!