BPM Custom Code to sort open Op list by OprSeq

Hi All, I can’t seem to figure out how to get this to work assuming I even can. I have a UD_Field that gets updated by BPM with custom code to list open operations by OpCode. There is no sort and when looking at it it’s just random. I want the list to display the operation code but in the proper open operation sequence. 10, 20, 30 40 and so on. But to dispaly as Laser, Weld, Machine, OutSide Sub.

This is what I have…

foreach (var iJobOper in 
    (from rJobOper in ttJobOper
      select rJobOper)
  ) {
  var xJobOper = iJobOper;

  foreach (var iJobAsmbl in 
      (from rJobAsmbl in Db.JobAsmbl
        where string.Compare(rJobAsmbl.Company, xJobOper.Company, true) == 0 
          && string.Compare(rJobAsmbl.JobNum, xJobOper.JobNum, true) == 0 
          && rJobAsmbl.AssemblySeq == xJobOper.AssemblySeq 
        select rJobAsmbl)      
    ) {
    var dbJobAsmbl = iJobAsmbl;

    var xOpCode_List = "";

    foreach (var idbJobOper in
            (from rdbJobOper in Db.JobOper
             where string.Compare(rdbJobOper.Company, dbJobAsmbl.Company, true) == 0
                 && string.Compare(rdbJobOper.JobNum, dbJobAsmbl.JobNum, true) == 0
                 && rdbJobOper.AssemblySeq == dbJobAsmbl.AssemblySeq
                 && rdbJobOper.JobComplete == false
                 && rdbJobOper.OpComplete == false
             orderby xJobOper.AssemblySeq, rdbJobOper.OprSeq   
             select rdbJobOper)
        ) {
      var dbJobOper = idbJobOper;

      if (xOpCode_List == "")
        xOpCode_List = dbJobOper.OpCode;
      else
        xOpCode_List = xOpCode_List + ", " + dbJobOper.OpCode;

    }

    dbJobAsmbl.OpenOp_c = xOpCode_List;

  }

}

EDIT: I wrapped your code in grave accents to highlight it correctly, so I can read it… Details are in the reply dialog before you type.

To get the output in that order use orderby fieldname ascending is assumed You can google C# linq orderby.

Depending on where and how often this is called then with(nolock) and possibly joining into one call to the Db to make one list would be best.

1 Like

I can’t seem to figure out where to get the orderby placed. I’ve tried a few places and it doesn’t take it. Not sure what C# linq is. I’m not a programmer, self-taught.

You want it ordered by OprSeq, but listing only the OpCode? It looks like you’re already sorting by OprSeq in your rdbJobOper query. It’s not coming through in that order?

ok, C# linq is what custom code is primarily in Epicor now. Where are you trying to get this sort done? Maybe you don’t need some of that code at all.

If you want to upload the bpm and what the output is supposed to be we can figure it out.

It is not, they are random.

Ok, I’ll need to take some C# linq classes. I keep getting asked for more custom tasks that require custom code. Thank you!

So this is on OpComplete, but not in MES? What is this supposed to do?

I started a “Code Camp” thread, that may help. We haven’t tackled LINQ specifically, but it’s on the todo list.

There is quite a bit of LINQ in there already I believe, at least in the comments.

1 Like

When an operation get’s completed or any change made to JobOper table, it writes the list of open operations to OpenOp_C field. This field is then used on dashboards for production to reivew jobs and they can see what operations by OpCode are still open. It shows the open Ops, just not putting them in any order when you view on dashboard they are random. Listing op 10, 20 and so on doesn’t help determine if it’s getting machined next or need to go for outside sub for example.

I have a routine that does this same process, but on the fly in a dashboard.

Export and upload your bpm and we can take a look. Your version just says 10. The earliest I have to work in is 10.2.400.

We are on 10.2.200, but I’ll have .700 available very soon. Are routines new in Kinetic?

They have existed since 10.2, but the last ones are in 11.1, so the tt to ds changed somewhere along the line.

If you want us to look upload the bpm.

Greg can’t move very well, give the man something to do!

Work From Home Sport GIF by UFC

Yes, I do. Thank you was pulled in 9 directions, yeehaaa!

OpenOpList.bpm (33.2 KB)

For my jobs it seems to get the correct ordering, but they are fairly simple. I took your routine and made as few changes as possible (rowmod was changed, so it did not run twice) and one I made closer to how I would write it and both produced the same list.

Can you add the write lines or use the below to see if your data somehow does not get ordered.

Since this is on a DD and is going to get hit a lot, I would bring all of the JobOpers records and only the fields needed from the Db once and then iterate that to make the list.

I added the comment at the top because I can’t stand seeing code in the action pane.
The start and end show when the routine begins and ends. The list shows me in the severlog what is happening in the code.

image

/* calc open ops */

Ice.Diagnostics.Log.WriteEntry("Start Orig Calc");

foreach (var iJobOper in
(from rJobOper in ttJobOper where !rJobOper.Unchanged()
select rJobOper)
) {
  var xJobOper = iJobOper;

  foreach (var iJobAsmbl in
  (from rJobAsmbl in Db.JobAsmbl
  where string.Compare(rJobAsmbl.Company, xJobOper.Company, true) == 0
  && string.Compare(rJobAsmbl.JobNum, xJobOper.JobNum, true) == 0
  && rJobAsmbl.AssemblySeq == xJobOper.AssemblySeq
  select rJobAsmbl)
  ) {
    var dbJobAsmbl = iJobAsmbl;

    var xOpCode_List = "";

    foreach (var idbJobOper in
    (from rdbJobOper in Db.JobOper
    where string.Compare(rdbJobOper.Company, dbJobAsmbl.Company, true) == 0
    && string.Compare(rdbJobOper.JobNum, dbJobAsmbl.JobNum, true) == 0
    && rdbJobOper.AssemblySeq == dbJobAsmbl.AssemblySeq
    && rdbJobOper.JobComplete == false
    && rdbJobOper.OpComplete == false
    orderby xJobOper.AssemblySeq, rdbJobOper.OprSeq
    select rdbJobOper)
    ) {
      var dbJobOper = idbJobOper;

      if (xOpCode_List == "")
      xOpCode_List = dbJobOper.OpCode;
      else
      xOpCode_List = xOpCode_List + ", " + dbJobOper.OpCode;
      
      Ice.Diagnostics.Log.WriteEntry($"OList {idbJobOper.OprSeq}-{idbJobOper.OpCode} {idbJobOper.QtyCompleted:0}");

    }

    dbJobAsmbl.Character02 = xOpCode_List;
    Ice.Diagnostics.Log.WriteEntry($"OList {xOpCode_List}");

  }

}

Ice.Diagnostics.Log.WriteEntry("Exit Orig Calc");



A little ocd isn’t a bad thing.

When you start flipping the light switch 27 times before you leave a room you may have a problem.

I changed it to a method and modified when it updates. Still doesn’t sort correclty.
image

I know you’ve spent a couple of days on this but another option is to do the query in a BAQ and use string_aggregate to generate your string.

1 Like