Data Directive - Update SysAgentSched Field

Hi,

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);
    
}

What table is your Data Directive on?

It’s on SysAgentSched.

Epicor fixed the DST problem with task scheduling . . .

1 Like

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.

1 Like

What version are you on? We are on Kinetic 2023.1 and still having issues with DST. :sob:

I believe they fixed in 2024.

2 Likes

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.

CallService<SysAgentSvcContract>(SysAgentSvc =>
{
    SysAgentTableset sysTS = SysAgentSvc.GetByID("SystemTaskAgent"); 
    
    foreach(var row in sysTS.SysAgentSched)
    {
        if(row.AgentSchedNum == 6807495)
        {   
            nextRun = Convert.ToDateTime(row.NextRunOn);
       
            row.NextRunOn = nextRun.AddHours(1);
            row.SchedDesc = "TestSched3";
            row.RowMod = "U";    
                   
        }
    }

    SysAgentSvc.Update(ref sysTS);
    
});

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 );
    }    
});
1 Like

My apologies, I was pulled into something else yesterday.

Thank you, Kevin! After adding the unchanged row, the NextRunOn is now updating as expected. :smiling_face_with_sunglasses: 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?

Yes It Is GIF

1 Like

I usually try it without and then add it if it looks like it should work but isn’t.

1 Like