Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Say I have an invoice object that has an internal unique ID and should get another invoice ID.

The format of the invoice ID should be: YY-MM-# where # increases with every invoice generated.

How can I create such an autoincrement number? I create an ID text field, but how to fill it? With a trigger? But how?

My basic idea was to compare a new invoice with the last one that was created. If it was created in an earlier month, start counting afresh.

How would you solve that problem? If possible, just using the formula field, or if not possible, with Apex, maybe with a trigger.

share|improve this question
Even if you could get the # to reset at the beginning of the month, would you really want your Invoice ID changing over time. So, if you created the Invoice in January 2013 the ID would be e.g. 2013-01-0000001 but then if you opened the same record again in February your ID would have changed to 2013-02-0000001. Given you're talking about Invoices I think you'll want a different approach to this. I think you need a Trigger to generate this number on insert. – Phil Hawthorn Jan 29 '13 at 16:35
@PhilHawthorn: Yes, you are right! Editing the invoice would spoil it. I should go for a trigger solution and edited the question. – mcbetz Jan 29 '13 at 16:45
I would take a look at this post, basically the same requirement in a different guise… – Phil Hawthorn Jan 29 '13 at 16:51

I did something similar to store a tracking number that started every day on the Case object, so something like might work for you. I used a field called Daily_Tracking_Number__c to store the number, and then a formula field to build the display format I wanted.

trigger ManageCases on Case (before insert) { 

    if(Trigger.isInsert && Trigger.isBefore){
} //end trigger

public with sharing class ManageCases {

//Tracking Numbers are reset each day, so we'll query for the current number and add to it   for the cases
public static void beforeInsert(Case [] cases) {

Decimal todaystrackingnumber;
//get the current number - there might not be one, so we'll query into a list

Case [] todayscases =  [Select Id, Daily_Tracking_Number__c from Case where CreatedDate = TODAY order by Daily_Tracking_Number__c Desc];

//if there is a case, then use the first one, since it is ordered by number
    if (todayscases.size() > 0) {
        todaystrackingnumber = todayscases[0].Daily_Tracking_Number__c + 1;
    else {
        todaystrackingnumber = 1;

//Now loop through the new cases and allocate a number

for (Case c: cases) {
c.Daily_Tracking_Number__c = todaystrackingnumber;
todaystrackingnumber ++;

} //end before insert

} //end class
share|improve this answer
if there are concurrent creates, this'll end up assigning duplicate tracking numbers. – superfell Jan 29 '13 at 18:36
By different users creating cases at the same time? Potentially - not sure how you avoid that though...maybe process them in a batch every few minutes? – BritishBoyinDC Jan 29 '13 at 20:01
Yes. you need another db row you can lock so that access to the "currentNumber" is correctly serialized. – superfell Jan 29 '13 at 20:39
@superfell: I just asked a question that relates exactly to your comments above: Would you mind taking a look and explaining how a db row lock would work with the code sample in the question? Thanks! – Paul Sasik Mar 27 '13 at 19:25

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.