I’m using the ScheduleEngine adapter to reschedule jobs. Right now, I’m doing a “what if” to backward schedule a job and get back the new starting time, to backward schedule the job before it from that point, and repeat.
My immediate issue is that the resource ID gets changed from where MRP put it to the first resource on the resource group, resulting in jobs from 10 resources being rescheduled to a single resource. Machine 1 gets kind of busy.
It’s also becomes slower the more records you try to update, but maybe that’s because they’re all going on one resource.
Key code below.
Thanks,
Joe
Outside the loop:
schedEngine = new ScheduleEngineAdapter(oTrans);
schedEngine.BOConnect();
Inside the loop:
bool schedulingMultiJobActive = false;
bool minimizeWIPFlag = false;
bool allowMoveJobsAcrossPlants = false;
bool autoLoadParentJobs = false;
bool autoLoadChildJobs = false;
bool finished = false;
string txt = "";
string resourceID = this.grdScheduleList.Rows[i].Cells["ResourceTimeUsed_ResourceID"].Value.ToString();
schedEngine.GetSchedulingMultiJobFlags(out schedulingMultiJobActive, out minimizeWIPFlag, out allowMoveJobsAcrossPlants, out autoLoadParentJobs, out autoLoadChildJobs);
schedEngTableset = (ScheduleEngineDataSet)schedEngine.GetCurrentDataSet(DataSetMode.RowsDataSet); // best way to do this?
schedEngine.GetScheduleRecord();
System.Data.DataRow schEngRow = schedEngTableset.Tables["ScheduleEngine"].Rows[0];
// assign values to row
schEngRow["Company"] = this.grdScheduleList.Rows[i].Cells["ResourceTimeUsed_Company"].Value.ToString();
schEngRow["JobNum"] = this.grdScheduleList.Rows[i].Cells["ResourceTimeUsed_JobNum"].Value.ToString();
schEngRow["AssemblySeq"] = Convert.ToInt32(this.grdScheduleList.Rows[i].Cells["ResourceTimeUsed_AssemblySeq"].Value);
schEngRow["OprSeq"] = Convert.ToInt32(this.grdScheduleList.Rows[i].Cells["ResourceTimeUsed_OprSeq"].Value);
schEngRow["OpDtlSeq"] = Convert.ToInt32(this.grdScheduleList.Rows[i].Cells["ResourceTimeUsed_OpDtlSeq"].Value);
//schEngRow["StartDate"] = DateTime.Today;
//schEngRow["StartTime"] = 1;
schEngRow["EndDate"] = endDate;
schEngRow["EndTime"] = endTime;
schEngRow["WhatIf"] = true; // set temporary dates in list
schEngRow["Finite"] = false;
schEngRow["SchedTypeCode"] = "JA"; // also used "AA"
schEngRow["ScheduleDirection"] = "End"; // "Start";
schEngRow["SetupComplete"] = false;
schEngRow["ProductionComplete"] = false;
schEngRow["OverrideMtlCon"] = false;
schEngRow["OverRideHistDateSetting"] = 2;
schEngRow["ResourceGrpID"] = this.grdScheduleList.Rows[i].Cells["ResourceTimeUsed_ResourceGrpID"].Value.ToString();
schEngRow["ResourceID"] = resourceID;
**MessageBox.Show("resource ID " + resourceID); // shows the correct resource ID, but when executed defaults to first on RG**
schEngRow["RecalcExpProdYld"] = false;
schEngRow["UseSchedulingMultiJob"] = false;
schEngRow["SchedulingMultiJobIgnoreLocks"] = true;
schEngRow["SchedulingMultiJobMinimizeWIP"] = false;
schEngRow["SchedulingMultiJobMoveJobsAcrossPlants"] = false;
//Add system default flags
schEngRow["UseSchedulingMultiJob"] = schedulingMultiJobActive;
schEngRow["SchedulingMultiJobMinimizeWIP"] = minimizeWIPFlag;
schEngRow["SchedulingMultiJobIgnoreLocks"] = false;
schEngRow["SchedulingMultiJobMoveJobsAcrossPlants"] = allowMoveJobsAcrossPlants;
finished = false;
txt = "";
//Execute method using the schedEngTableset
schedEngine.MoveJobItem(out finished, out txt);
Outside the loop:
schedEngine.Dispose();
Since they all go to the same Resource in your code, I assume the scheduler does an extra step that you are missing or you need to modify your code to move the resource after scheduling.
I looked at the traces for Resource and Multi Resource Scheduling Boards and they use:
SetMachines
ChangeResource
They both take the Erp.BO.ScheduleEngineDataSet as an argument.
I’m using a dataset that looks just about like the traces. ChangeResource errors out with “Resource record not found.” I’m not seeing what looks bad about the info going in.
I’m running into the same problem. Setting the row dirty did not solve the issue.
The trace from the Multi Resource Scheduling Board shows the RowMod as A for using SetMachines and ChangeResource.
The one thing that looks odd is that it uses the SysRowID from a SchedulingBoard Record from the Scheduling Board Implementation. I tried that and got the same error though.
Here’s what we wound up with, and it seems to work okay for our application. As I recall, the big thing was getting the right kind of datarow to work with. Hope this helps.
Just to clarify my use case I am not bound to a grid. I am changing the resource on one to many job operations in the Resource Time Used table. (or rather trying to)
I tried the code above and it did not change the resource in existing records in the resource time used table.
I noticed that you do not call the ChangeResource method which I am seeing in stack traces from the multi resource scheduling board (and in your comments above).
As soon as I put that in it errored out with the “Resource not found” error that you were receiving before.
Still testing. I’ve tried this with the BO contract and same error. I’m matching what is in the trace but still it is happening.
We ran into this same issue. After struggling with it for a while, we figured it out. The base Epicor code when using the Multi-Resource Scheduling Board to reschedule a resource does not call GetScheduleRecord. We had assumed like you that we needed to call the thing that looked like the “GetANew…” method of the ScheduleEngineAdapter. However, the base Epicor code apparently calls ScheduleEngine.NewRow instead. For some reason calling GetScheduleRecord prior to calling ChangeResource will cause the “Resource not found” error.
This can be replicated in the BL Tester tool by calling GetScheduleRecord prior to calling ChangeResource. Even if the values in the row are good the ChangeResource call will fail. However, if in the BL Tester tool you clear the persistent data and just click into the dataset and create a row (mimicking a NewRow method call) the ChangeResource call will work so long as the row values are good.
So change:
schedEngine.GetScheduleRecord();
///your code to populate the field values
To:
System.Data.DataRow scheduleEngineRow = schedEngine.ScheduleEngineData.ScheduleEngine.NewRow();
///your code to populate the field values
schedEngine.ScheduleEngineData.ScheduleEngine.Rows.Add(scheduleEngineRow);