Product Configurator: Smart String Constructed from Inputs+Auto generated Sequence Number

We are working on Product Configurator for Quote Entry and able to generate new Part/Rev based on inputs from the product configurator. Now along with the new generated string we also want sequence number to be generated.
For example, New generated string is 81-I2-ZZ-. We want 81-I2-ZZ-1001

You can store the next number in a UD table and increment it each time the configurator is saved. In my example each product group has its own series of numbers, the next number is stored in a User Defined Field (NextPartNumber_c). This is defined in a User Defined Method with a parameter of ProductGroup passing in the product group and a return type of Int. This could easily be done with a UD table

Erp.Contracts.ProdGrupSvcContract boProdGrup = null;
Erp.Tablesets.ProdGrupTableset dsProdGrup = new Erp.Tablesets.ProdGrupTableset();
int nextNumber = 0;
using(boProdGrup = Ice.Assemblies.ServiceRenderer.GetService < Erp.Contracts.ProdGrupSvcContract > (Db))

dsProdGrup = boProdGrup.GetByID(ProductGroup);

var rec = (from r in dsProdGrup.ProdGrup select r).FirstOrDefault();
if(rec != null)
	nextNumber = (int)rec["NextPartNumber_c"];
	rec.SetUDField<int>("NextPartNumber_c", nextNumber + 1);
	rec.RowMod = "U";
	boProdGrup.Update(ref dsProdGrup);

return nextNumber;

Some issues you’ll need to address:

  • When to assign/reserve the next sequence number
  • Should a new Sequence number be used if the part is reconfigured?

Controlling the Seq number might be best if you use them to make truly unique P/N’s.
For example,

  • The first time the configurator’s P/N would be81-I2-ZZ, it is set to 81-I2-ZZ-1001.
  • The next time a configuration yields a P/N 81-I2-ZZ, it would be 81-I2-ZZ-1002.
  • If a following configuration yields a P/N 81-J3-XX, it would be 81-J3-XX-1001,
    instead of 81-J3-XX-1003 (with no earlier 81-J3-XX-xxxx numbers)

So you’d track the last used value for each P/N the configurator would have yielded.

Thank you for your response. We have two product types, Standard and Out-Standard. Each have different initial code type, for example Standard have 81-I2-XXXX, 71-I2-XXXX and so on. Similarly for Out-Standard we have 81-I2-ZZ-XXXX, 71-I2-ZZ-XXXX. So for each product we need to have there own sequence number starting with 1001. So yes we want to make it unique as u mentioned.
Any suggestion how we can achieve this? We are new to Product Configurator.

Hello Jkinneman, Thank you for your response. I created UD field in QuoteDtl_UD table and followed your code. But we are getting the following error " error CS1503: Argument 1: cannot convert from ‘method group’ to ‘string’ "

Is it okay to have gaps in the -XXXX segment?

Because you will have to reserve that number during quote generation (so that two quotes don’t choose the same number),you’ll have to reserve the number prior to returning the part number from the configurator.

I’d setup a UD table with the Key1 field holding the part of the P/N prior to the sequential suffix, and Number01 holding the next value.

For example, UD21 would look something like:
(after being used several times)

Company  Key1      Key2  Key3  Key4  Key5  Number01
MC       81-I2                             1005
MC       71-I2                             1010
MC       81-I2-ZZ                          1003

In the UD table above, a sequential number was reserved for three specific part numbers.

  • 81-I2 has been used 4 prior times (making the next number to use 1005)
  • 71-I2 has been used 9 prior times
  • 81-I2-ZZ has been used 2 prior times

The configurator code would query the UD table to get the next value (Number01) where Key1 == PartNumber (prior to your addition of the sequence number). Say you queried it for Key1 = ‘81-I2’, it would return 1005. You’d then update that UD record with Number01 = 1006 (the next number after 1005), and append the returned value to your part number, yielding 81-I2-1005

If no record is found, assume it is new, and use 1001, then create the entry in the UD table for
Key1 = PartNumber, and Number01 = 1002

You could probably make a User Defined method that accepts an input of a string (your Part Number), and returns the updated Part number (while maintaining the UD table)

in pseudo code…

string Sequenced_PartNum(string pn){
    int nextnum=0;
    Query UD table where Key1 == pn
    if (no record found)
       nextnum = 1001;
       create UD record where Key1 = pn, Number01 = nextnum + 1;
       return(pn + "-" + nextnum.ToString();
    else {
       nextnum = Number01;
       update UD record where Key1 = pn, setting Number01 = nextnum + 1;
    return(pn + "-" + nextnum.ToString(); // actually, some form that lets you specify "0000"

You would NOT want the UD field on quoteDtl as we want to know the last used number. If on Quote Detail we would start from zero each time.

What we want to happen is if we enter quote 123 Line 1 and we get a sequence number of 1 we would want to get 2 on quote 124 Line 1 and 3 on quote 124 Line 2. To so that we need to store the last used number in a common location.

We want a UD field on a separate table that will remember for us the last used number. In my example I put the UD field on the product group table so I could have a different sequence number for each product group.

I’d have to see your code to see where the error might be.

I implore you NOT to TRY to come up with a process to avoid gaps in sequence numbers for part numbers. There will ALWAYS be a way for someone to break the sequence.

1 Like

@ckrusen I tried your code but getting two errors. I have attached screenshot for reference. Thank You!!


The “code” I posted wasn’t really code. It was more like an outline of the steps to do.
Sorry for the confusion. I’ll work on getting you the real code.

Im not much familiar with c# in epicor environment. I was working on other programs which does not need coding. I got your pseudo concept so I’ll try from my end too. Codes from side would be great help for me. Thanks in advance.

The following works for UD11

It gets the value in UD11.Number01 where Key1 = the “base part number”. If the record doesn’t exist, it creates it with the Number01 set to 1001.

If it does exist (the else part of the if…else), it adds one to the value retrieved, and updates that record.

Finally it returns the value (an integer) to be used by your configurator

Here’s the User Defined Method Maint screen (code is below)

Method Code (click arrow to show)
// Enter valid C# code and do not forget this method returns a string value.

int nextNum = 0;

var UD11svc = Ice.Assemblies.ServiceRenderer.GetService<UD11SvcContract>(Db);
UD11Tableset ds = new UD11Tableset();

var udRow = 
	(from ud11 in Db.UD11 
		where ud11.Company == Context.CompanyID && ud11.Key1 == Inputs.txtBasePartNum.Value
		select ud11).FirstOrDefault();

if (udRow == null){	// No record for the base partnum supplied
	nextNum = 1001;
	UD11svc.GetaNewUD11(ref ds);
	ds.UD11[0].Key1 = Inputs.txtBasePartNum.Value;
	ds.UD11[0].Number01 = nextNum;
	UD11svc.Update(ref ds);
else{		// record found
	nextNum = System.Convert.ToInt32(udRow.Number01)+1;
	(from r in Db.UD11 
		where r.Company == Context.CompanyID && r.Key1 == Inputs.txtBasePartNum.Value
  	select r).ToList().ForEach(x => x.Number01 = nextNum);


I tested with a very simple configurator

Here’s the code for the OnClick function of the button

int outp = 9999;
outp = UDMethods.NextSequence();
Inputs.txtCalculatedPN.Value = Inputs.txtBasePartNum.Value + "-" + outp.ToString();

Here it is in action:

Values before running the configurator


UD Seq

And UD values after the test


Notice that a row was added for base P/N 81-I2-XX, because it didn’t exist before the test.


Very important note … The sequence number will increment every time the UD function is called. So re-configuring a configured part, will increment the counter again - unless you check that the suffix has already been assigned, and skip getting the next number.

Also, The UD table actually holds the last number used. The UD Method ads one to that, updates the table, then returns the new number.

@ckrusen Thanks a lot. This is what I was actually looking for. Thank you for providing the solution in detail. I really appreciate the time you gave to solve my problem. Thanks once again :slightly_smiling_face: