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.

  • 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. Commented Jan 29, 2013 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
    Commented Jan 29, 2013 at 16:45
  • 1
    I would take a look at this post, basically the same requirement in a different guise salesforce.stackexchange.com/questions/4289/… Commented Jan 29, 2013 at 16:51

1 Answer 1


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
  • 1
    if there are concurrent creates, this'll end up assigning duplicate tracking numbers.
    – superfell
    Commented Jan 29, 2013 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? Commented Jan 29, 2013 at 20:01
  • 1
    Yes. you need another db row you can lock so that access to the "currentNumber" is correctly serialized.
    – superfell
    Commented Jan 29, 2013 at 20:39
  • @superfell: I just asked a question that relates exactly to your comments above: salesforce.stackexchange.com/questions/10089 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
    Commented Mar 27, 2013 at 19:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .