Wednesday, February 24, 2016

Custom auto-numbering : no code nor add-on needed

In nearly every Dynamics CRM project, you will be asked, at a time or another, to add an auto-numbering field to an entity. If you are (very) lucky, you can use the out-of-the-box auto-numbering feature, included in entities like Case, Campaign or Order. But if you are less lucky (let's say 99% of the time), you will be asked to add this feature on another entity, system or custom.

Hopefully, you have several options for that, each with some advantages and drawbacks. You can use some add-ons, with great options like custom formatting but with some cost, and sometimes unknown maintainability over CRM upgrades. You can use plugins, based on a "counter" custom entity. This won't require any license, but some development (so design and tests), and each enhancement will require more and more coding.

The third option, that I will explain today, does not require any coding, nor add-ons, just a few customizations. It sure has some limitations, but I think it is interesting enough to be detailed.

So in this article, I will achieve the auto-numbering feature for the entity Contact. My field has to have this format : "CO" as a prefix and an incremental number, on 7 digits. For instance, the 421th created contact has to be : CO0000421.

I will introduce, step by step, the full method I used to do this. At the end of this demonstration, I will briefly explain the key points to notice, the advantages this method can introduce and also some limitations.

In order to achieve this with no code, say as a prerequisite, your CRM system has to be at least CRM 2015 ( You can use part of it with CRM 2013 (, but with reduced functionality. Before (CRM 2011 and less), it won't work.

Ready ? Let us begin :
  • First, create a new entity called "Counter", as below :
  • On this entity, create a Whole Number field, named Next Number, and a Single Line of Text field, named Prefix.

  • Then, still on this entity, add a calculated field, Single Line of Text, named Next String Id. Set the formula as below :

Note that this calculated field is only used for the formatting "Prefix"-"Number on 7 digits". Of course, the formula above is not finished ; it continues with "00", "0" and ends with Else Concat("Prefix", "NextNumber").
  • When the 3 fields are created, you can add the fields on the main form, the "Active Counters" view and publish the customizations.
  • Create now a real-time child workflow, based on the entity Counter. It will be used to increment the counter at each Contact creation. Design the workflow as below :

The properties of the "Update" Step :

  • Save and Activate your child workflow.
Now, you have created all your settings for your custom entity Counter. We will now add a counter on the Contact entity. Note that if you want to add this feature on Account entity (let's say AC0000421), you will have to start from here ; the first part has to be done only one time, the part coming next, once by entity.
  • On the Contact entity, add a N-1 relationship with the entity "Counter" we have just created. It can be Referential. Note that this relationship automatically creates a lookup field on the Contact entity. In my case, it is named Contact Counter (new_ContactCounterId) :
  • Create a Single Line of Text field, on Contact entity named Reference ID. In the end, this field will store the auto-numbered field of the contact record. Place it on the body of the main form and publish the customizations.

  • Now, go the Settings Area, Counters and create a new record on that entity, with following values. Note that the Next String Id field has the expected format.

  • Final step. Create a new real-time workflow (be careful not to use a background one), on the Contact entity with following design and steps :

  • Step 1 : Assigning the Lookup Field with the record created : Update on Contact with the following Properties :

  • Step 2 : Setting the Reference ID with the value stored in the associated (just before) record.

  • Step 3 : Increment the Next Number of the Counter record, using the child workflow :
  • Save and activate the workflow. And, maybe hard to believe, but you're good to go ! Let's try...
First, by creating a 3 contacts manually (2 with main form, 1 with Quick Create) :

Next, by importing (using a basic csv file and the Import Wizard) 421 contacts :

And you're automated numbering is achieved on Contact entity, using custom entities, calculated fields, and real-time workflows, and absolutely no code. Moreover, if you want to add an auto-numbering on the Account entity, you don't have to start from the beginning but by creating a custom relationship between the account entity and the counter entity, creating the record "Account" on the Counter entity and the real-time workflow on Account creation. And even more, you can add the Counter entity and the child workflow to an unmanaged solution, export it as a managed one and deploy it to several organizations.

But where is the magic there ? Why do we have to wait CRM 2015 to do this ? What is the reduced functionality with CRM 2013 ? I will discussed it now :
The key point of this method is the "real-time workflow" feature introduced by CRM 2013. You can see on this blog post from Auto-Numbering Workflows Real-Time vs Asynchronous all the explanations you need. In fact, the method exposed in this post inspired me for mine, I am just going a little step further with the formatting and the usage of calculated fields, introduced with CRM 2015. That's why with CRM 2013, you can only have an sequence number, without the formatting.

Of course, this method as a few drawbacks. First, the formula used by the calculated field will be the same for all the entities you want to enhance. But you can modify this by adding more fields on the Counter entity (examples : Suffix, Year etc.). Everything is in the formula. 
The other drawback I see is the usage of fixed record assignment in the workflow (by using the record Contact on the entity Counter). The problem of this is when deploying the workflow by importing a solution. To work instantly, you have to be sure that the record exists and that it has the same GUID in your target environment than in your source. You can manage this by using the Configuration Migration Tool or the Package Deployer (tools found in the Dynamics CRM SDK). Otherwise, your workflow will contain some errors and you'll have to correct it manually. By the way, if you have this kind of issues (called "Broken Reference"), I'm currently working on how to detect and correct them automatically, I will write another post about it shortly.

No comments:

Post a Comment