In the last article, “How to Use a D365 Numbers Sequence“, you learned that a number sequence is a system generated unique value. Additionally, you learned how to set up and use them. In this article, learn how you can develop a D365 number sequence to your own field using X++. And how to add one to a parameters form. Using a number sequence provides a consistent look and feel to the primary field on your form. As well as saving the user time in coming up with a unique value themselves.
Overview
To begin, there are a number of steps that need to be followed in order to develop a D365 number sequence. For this reason, I will first provide an overview of the important steps. Then, go into the detail of each step.
First, we need to identify which field on which table and form will use the number sequence.
Secondly, we need to create a class that extends NumberSeqApplicationModule. This class will contain the code needed to add a row to the ‘Number sequence’ tab on a parameters form. This ‘number sequence reference‘ allows the user to specify which ‘number sequence code‘ should be used for that field.
Thirdly, we need to run a runnable class (job) to have the system process the class from step two. This will create the ‘number sequence reference‘ row.
Fourthly, we need set the ‘number sequence reference‘ to a ‘number sequence code‘, which defines the format of the number sequence.
Fifthly, we need to override the ‘create‘ method on the data source on the form that will use the number sequence. Then, add code to get a new number from the associated number sequence every time a new record is created.
Identify The Field
First, we need to identify which field on a table should use a number sequence. In a previous article, you learned how to create a table in D365. In this article, as an example, we will reuse that table.
Notice, the table is named ‘TutCar‘. ‘Tut‘ is short for Tutorial. Additionally, it has two fields: CarId, and Description. The field CardId has the Extended Data Type property set to ‘TutCarId‘.
As a reminder, Extended Data Types (EDTs) are separate objects created in Visual Studio, that contain many properties, such as string size and label. Any field on a table, that uses this EDT, will inherit those same properties.
In order to develop a D365 number sequence, you must use a string field that has an Extended Data Type. In this example, the EDT is named TutCarId. This name is important to remember in the following steps.
Develop NumberSeqApplicationModule Class
Next, to develop a D365 number sequence, in Visual Studio create a new class that extends NumberSeqApplicationModule. This class will contain the code needed to add a row to the ‘Number sequence’ tab on a parameters form. This ‘number sequence reference‘ allows the user to specify which ‘number sequence code‘ should be used for that field.
For example, I named mine ‘TutCarIdNumSeq‘.
public class TutCarIdNumSeq extends NumberSeqApplicationModule
{
}
buildModulesMapSubsciber Method
Next, add the following method and code. It isn’t really important to understand this method. It is used to add your EDT to the list of number sequence references. Replace, the text inside ‘classnum(TutCarIdNumSeq)’ which the name of your class.
[SubscribesTo(classstr(NumberSeqGlobal),delegatestr(NumberSeqGlobal,buildModulesMapDelegate))]
static void buildModulesMapSubsciber(Map numberSeqModuleNamesMap)
{
NumberSeqGlobal::addModuleToMap(classnum(tutCarIdNumSeq), numberSeqModuleNamesMap);
}
numberSeqModule Method
In the last article, you learned that number sequence codes are setup, then tied to number sequence references that are on the parameters forms in each module. Before going further, we need to decide which ‘Module’ of the system, this number sequence should be setup in. Typically, whichever module contains the menu item that opens the form that this field is used should be the module used.
In my example, the form TutCar, shows the data in the table TutCar. And, this form exists in the Accounts Receivable module in D365. Therefore, I will add code that uses the ‘Cust’ value of the ‘NumberSeqModule‘ enum.
public NumberSeqModule numberSeqModule()
{
return NumberSeqModule::Cust;
}
Notably, it can be a little tricky to understand which enum relates to which module. However, you can look on the ‘label’ of the enum in Visual Studio until you find a match.
loadModule Method
Lastly, a key step in order to develop a D365 number sequence is to define what scope and parameters should be used. Add the ‘loadModule‘ method following the example below. Then, replace ‘TutCarId‘ in the example, with the name of your EDT. Also, add ‘Reference help‘ text that will help the user know which number sequence they are setting up. This should be changed to use a Label, instead of plain text.
protected void loadModule()
{
NumberSeqDatatype datatype = NumberSeqDatatype::construct();
datatype.parmDatatypeId(extendedTypeNum(TutCarId));
datatype.parmReferenceHelp(literalStr("Unique key used for the cars."));
datatype.parmWizardIsContinuous(false);
datatype.parmWizardIsManual(NoYes::No);
datatype.parmWizardFetchAheadQty(10);
datatype.parmWizardIsChangeDownAllowed(NoYes::No);
datatype.parmWizardIsChangeUpAllowed(NoYes::No);
datatype.parmSortField(1);
datatype.addParameterType(NumberSeqParameterType::DataArea, true, false);
this.create(datatype);
}
To explain, the other parameter values can also be changed based on your needs. However, the above code shows the most common values.
Final NumberSeqApplicationModule Class
Ultimately, in order to develop a D365 number sequence, your class should look similar to this. I have bolded the pieces that you need to change for your specific scenario.
public class TutCarIdNumSeq extends NumberSeqApplicationModule
{
protected void loadModule()
{
NumberSeqDatatype datatype = NumberSeqDatatype::construct();
datatype.parmDatatypeId(extendedTypeNum(TutCarId));
datatype.parmReferenceHelp(literalStr("Unique key used for the cars."));
datatype.parmWizardIsContinuous(false);
datatype.parmWizardIsManual(NoYes::No);
datatype.parmWizardFetchAheadQty(10);
datatype.parmWizardIsChangeDownAllowed(NoYes::No);
datatype.parmWizardIsChangeUpAllowed(NoYes::No);
datatype.parmSortField(1);
datatype.addParameterType(NumberSeqParameterType::DataArea, true, false);
this.create(datatype);
}
public NumberSeqModule numberSeqModule()
{
return NumberSeqModule::Cust;
}
[SubscribesTo(classstr(NumberSeqGlobal),delegatestr(NumberSeqGlobal,buildModulesMapDelegate))]
static void buildModulesMapSubsciber(Map numberSeqModuleNamesMap)
{
NumberSeqGlobal::addModuleToMap(classnum(TutCarIdNumSeq), numberSeqModuleNamesMap);
}
}
Create Runnable Class (Job)
After adding the new class that extends NumberSeqApplicationModule, we need to actually run the loadModule method inside of it. As a result, this will create a record in the ‘Number sequence’ tab of the parameters form in the module we specified.
First, open Visual Studio and Create a new solution and project. Secondly, right click on the project, and select Add>New Item. Thirdly, select Dynamics 365 Items, on the left, and then select ‘Runnable Class (Job)‘ from the list. Fourthly, enter in a name. Finally, click the ‘Add‘ button to the add the job to your project.
In this example, I named my job ‘TutLoadCarIdNumSeq‘.
class tutLoadCarIdNumSeq
{
/// <summary>
/// Runs the class with the specified arguments.
/// </summary>
/// <param name = "_args">The specified arguments.</param>
public static void main(Args _args)
{
tutCarIdNumSeq tutCarIdNumSeq = new tutCarIdNumSeq();
tutCarIdNumSeq.load();
}
}
Notice, I simply am instantiating the class that I created in the previous step. And then I call the ‘load‘ method. This method exists on the base class, and will call the ‘loadModule‘ method on child class.
Next, right click the class in your Visual Studio project, and select ‘Set as Startup Object‘.
Finally, click the ‘Start’ button to run the job, and create the number sequence reference.
Set The D365 Number Sequence Reference
After running the job, go the parameters form you added the number sequence reference to. Then, go to the ‘Number sequence‘ tab and verify that a new row is shown.
In my example, I see the new number sequence reference show on the ‘Accounts receivable parameters’ form.
Next, if you already have one created, feel free to populate the number sequence reference with a number sequence code. Otherwise, go to Organization administration>Number sequences>Number sequences. Then click the ‘Generate‘ button to run the wizard.
After reading the ‘Welcome’ message, click the ‘Next’ button.
In the Setup section, you will see that the system has automatically identified that a number sequence code needs to be created for each company in the system. Click the ‘Next‘ button.
Finally, review the ‘Completed’ page, and click ‘Finish’.
Back on the number sequence list page, use the filters to find the number sequence code that was generated by the wizard. In my case, the system generated ‘Acco_21395‘ for the company I am in.
Then, go back to the parameters form, and validate that this number sequence code with the number sequence reference.
Override The Create Method
Until now, the number sequence was not fully defined and setup for use. But now, we can complete the final step needed to develop a D365 number sequence. Whenever, a new record is created on our form, we want the system to generate a new unique number.
First, open the form. For example, open TutCar.
Next, right click on the data source that contains the field that has the Extended Data Type (EDT) that we tied the number sequence to. Select ‘Override‘, then ‘Create‘.
Add the following code to the ‘create‘ method.
public void create(boolean _append = false)
{
TutCarId tutCarId;
NumberSequenceReference numberSequenceReference;
super(_append);
numberSequenceReference = NumberSeqReference::findReference(extendedTypeNum(TutCarId));
if (numberSequenceReference)
{
tutCarId = NumberSeq::newGetNum(numberSequenceReference).num();
TutCar.CarId = tutCarId;
}
}
Replace the EDT inside the code ‘extendedTypeNum(TutCarId)‘ with the name of your EDT.
To explain, first this method finds the number sequence reference associated with this EDT. Then the code calls the ‘num()‘ method to get the next number. Finally, the code assigns that value to the newly created record on the data source.
Testing The D365 Number Sequence
Straightaway, we get to the fun part. Testing to see that the number sequence we have setup works as expected.
After compiling the code, open the form associated with table that uses the number sequence. Click the ‘New’ button to create a new record. The field should be populated with a value that follows the format defined by the number sequence.
Conclusion
In this article you learned how to develop a D365 number sequence. While there are a number of steps involved, they are the same each time. Therefore, feel free to come back to this guide any time you need to develop a new number sequence. Then, follow the steps. Replacing where you need to, for your Extended Data Type. I hope you learned something new today.
Very nice post… appreciate if you can create own parameters table and form and add the sequence number there rather than adding at AR module
Let me see if I can creat an article that explains that.
Thank You Peter, I appreciate all the tutorial and Videos you have uploaded. Yours is the best material on internet without any nonsense.
I have the same Request. This tutorial is perfect for creating a number sequence front end for users.
Though as a developer we are also asked to auto generate number sequence when multiple lines are being processed through batch Job.
Awesome post. The best explanation without nonsense.
Do we need to run the Job on Tier 2 environment also when we deploy this custom number sequence from dev to Test(Tier 2) environment?
Great question. I don’t believe so but I need to double check that. I believe that when you promote the package with the code to the tier 2 environment the process of promoting the code handles the running of scripts like this to refresh and load things like this.
Hi. Any updates on this? If this is automatically run on TIER 2 then maybe we could also run similar on DEV?
You should not need to run the job for a tier 2. It should run when you promote the code package. Let me know if you have any issues.
In a dev environment you should run the job directly to test the change. Otherwise, you can take a backup of a tier 2 environment with the data in it and restore it to a dev machine. So it doesn’t have to be run on every environment.
Thank you for sharing this insightful tutorial on developing a Dynamics 365 Number Sequence! Your step-by-step guide provides a clear and comprehensive walkthrough for anyone looking to implement number sequences effectively within Dynamics 365.
Thank you for you kind words! I appreciate them!