I know there are several posts about this topic, but I haven’t been able to find the exact answer I’m looking for. I’m trying to update SysAgentSched.NextRunOn by one hour for DST. I have an In‑Transaction Data Directive that attempts to update this field.
However, when the BPM is triggered, the NextRunOn value does not update, while the SchedDesc field does (I’m only using it as a test field to confirm the update logic is running).
Below is a snippet of the code in the BPM. Does anyone know why SchedDesc updates, but NextRunOn does not?
using(var sysBO = Ice.Assemblies.ServiceRenderer.GetService<Ice.Contracts.SysAgentSvcContract>(Db))
{
SysAgentTableset sysTS = new SysAgentTableset();
sysTS = sysBO.GetByID("SystemTaskAgent");
foreach(var row in sysTS.SysAgentSched)
{
if(row.NextRunOn.HasValue)
{
nextRun = Convert.ToDateTime(row.NextRunOn);
if(row.AgentSchedNum == 6807495) // This is a test schedule
{
row.NextRunOn = nextRun.AddHours(1);
row.SchedDesc = "TestSched2";
}
row.RowMod = "U";
}
}
sysBO.Update(ref sysTS);
}
So I think your issue is that it’s an in-trans directive on the same table, and you’re calling a BO to update it within the directive. I think it probably is updating the NextRunOn, but since it’s in-trans, it updates again based on the original value.
So normally, it would process tasks on the schedule, then update NextRunOn based on the LastRun and the set interval.
With your BPM, it processes the tasks, updates NextRunOn based on your BPM, then updates NextRunOn based on LastRun and the set interval.
I’d also recommend moving this to an Epicor function. Since it’s in-tran on SysAgentSched, I would think that this would trigger every time a schedule executes. And since you’re calling the BO and not limiting to the row that’s being updated, all schedules would update each time one executes.
Thanks for the recommendation, Kevin. I recreated this in a function, but I’m seeing the same results. The SchedDesc updates correctly when the function is triggered, but NextRunOn does not. The test schedule is set to run daily at 8:00 AM, and I would expect it to update to 9:00 AM after the function completes.
So the problem is that this is one of the methods / tablesets that requires an Updated row AND an Unchanged Row (RowMod == ""). It’s pretty simple to create an unchanged row, but since you’re in a foreach loop, it would error out on you when you add a row. It doesn’t like when you add rows to a collection that you’re already looping through. It would send a Collection has been modified. Enumeration has failed error.
To avoid this error, you just have to change what you’re looping through. I added the Table “SysAgentSched” to a function and got a list of schedule IDs, and looped through that instead.
// Get List of Schedule IDs
var scheds = Db.SysAgentSched.Select( s => s.AgentSchedNum ).ToList();
CallService<SysAgentSvcContract>(svc =>
{
// Get full Tableset
var ts = svc.GetByID("SystemTaskAgent");
// Loop thru list of Schedules
foreach( int ID in scheds )
{
// Get the schedule row
var row = ts.SysAgentSched.FirstOrDefault( x => x.AgentSchedNum == ID );
if ( row == null ) continue;
if( row.AgentSchedNum == 6807495 )
{
// Add an Unchanged row
var rowCopy = ts.SysAgentSched.NewRow();
BufferCopy.Copy( row, rowCopy );
ts.SysAgentSched.Add( rowCopy );
// Set the Row fields
row.NextRunOn = Convert.ToDateTime(row.NextRunOn).AddHours(1);
row.SchedDesc = "UpdateTest4";
row.RowMod = "U";
}
svc.Update( ref ts );
}
});
My apologies, I was pulled into something else yesterday.
Thank you, Kevin! After adding the unchanged row, the NextRunOn is now updating as expected. How can I identify which methods or tablesets require both the unchanged and updated rows? Is it considered best practice to always include unchanged rows?