tags:

views:

66

answers:

2

I need to generate unique invoice numbers for my Access (2010) database. The numbers should be in the format year+sequential number, e.g. 20101447 for the 1447th invoice of 2010. I looked around for a while, but a lot of the Google results suggest using an autonumber and I'm quite certain that's not a very solid way of doing it. (because autonumbers are only guaranteed to be unique, nothing else)

The database isn't going to be used by multiple users at once for now, but I don't feel like going with a totally hacked together solution either.

EDIT I also found this website that discusses sequential numbering using the DMax function. Scenario #2 is exactly what I had in mind, and I think it's good enough for my use case. I'll make sure the user is notified in the rare (for me) event that the database got changed before completely entering and saving a new invoice.

EDIT2 FYI: The numbering scheme isn't a fiscal requirement, but just our custom numbering. I didn't want to change without a good reason to.

+3  A: 

If you have the ability to change the database schema:

  • Add a sequential number field and a year field.
  • To get the invoice number, combine these values appropriately.
  • When inserting, you will have to get the current year and then query the database for the maximum sequential number where year = current year.
  • Use these values on your insert.

If you can't change the database schema:

  • Get the max invoice number where invoice number starts with current year
  • Increment the invoice number.
  • Use these values on your insert.

EDIT

If you can add another table, have a table that stores the 'max' sequential number for each year. Every insert will lock the table, get the value and then increment it. Think of it as your invoice number generator table.

Edward Leno
This can lead to duplicate values if there is more than one user.
Remou
Maybe this could be avoided with a two-field index set to "no duplicates" and actually verifying the data got inserted correctly whenever a new invoice is created. But that was why I was asking, my Access knowledge is still pretty shaky at best.
CarstenN
It would be better to store the last number in a separate table, the number can be retrieved from the table and added to the record in the before insert event. You would need to lock the table. Various aspects of this are addressed in the link I posted, although it is probably over-complicated for your present needs.
Remou
Agreed, if you can add another table, have a table that stores the 'max' sequential number for each year. Every insert will lock the table, get the value and then increment it.
Edward Leno
+2  A: 

Solutions complete with sample code

How To Implement Multi-user Custom Counters in DAO 3.5 Ignore the 3.5 version number in this article. Use whatever version of DAO is appropriate to your version of Access.

How To Implement Multiuser Custom Counters in Jet 4.0 and ADO 2.1 The current version of ADO in Windows XP SP3 is 2.8 so ignore the ADO 2.1 part and use ADO 2.8. Although 2.1 will still work.

Also what happens on January 2nd when someone enters an invoice which is supposed to be dated December 31st? And this will happen.

Tony Toews
Interesting but way out of my ballpark right now, I'm afraid.
CarstenN
What is "way out of your ballpark"? The issue of the December invoice entered in January? Or the issue of using the cited code? You will have to use code because of the requirement to restart the counter each calendar year. The only question is exactly how you implement it.
David-W-Fenton
As I said earlier, I'm wary of adding complexity that I don't fully understand/need. Both links discuss properly implementing custom counters in multiuser environments. My problem was dealing with a much lower level problem.
CarstenN
Is it not a multi-user context? If it is, then you need to do it the way the cited articles say, or you're bound for problems.
David-W-Fenton