No, I wouldn't do that...
The default value is calculated BEFORE even starting a new invoice. Therefore, two users who start creating a new invoice at approximately the same time will have the
same invoice number calculated!
You might be tempted to use the BeforeInsert event. Don't do that, as the DMax function only considers
saved records and more than one user could be currently entering new records - they would obtain the same value.
The solution is to allow only one user to generate a value at a given moment and additionally, prevent all other users from calculating a value BEFORE the record is saved to the database.
Create a dummy table with one field and some value in that field. It does not matter what field type or what data you have there.
In the form's module, declarations section, declare a recordset variable.
In the BeforeUpdate event of the form, open the recordset and start an edit in pessimistic mode. If any other user attempts to create an invoice number, he/she will encounter a 3260 error.
Calculate the next invoice number and put the value in the InvoiceNo field.
Close the recordset in the AfterUpdate event of the form.
In this way, each user will only get new invoice numbers-from saved records.
Action flow sequence:
User enters all relevant data
->BeforeUpdate event is triggered
->Check if it is a new record, and if yes
->Attempt to edit DummyTable
->If success, lock DummyTable and get next invoice number
->If failed
->If already retried, abort and deny saving the record
->Go back to attempt to edit the dummy table
->BeforeUpdate event ended
->AfterUpdate event is triggered (the record is saved)
->Release the DummyTable and let other users do their stuff
'==========Full Code=========================
Option Compare Database
Option Explicit
Dim rst As DAO.Recordset
Private Sub Form_BeforeUpdate(Cancel As Integer)
Const conRetries = 5
Dim i As Integer
On Error GoTo ErrHandler
If Not NewRecord Then Exit Sub
start:
Set rst=CurrentDb.OpenRecordset("Select * from DummyTable", dbOpenDynaSet,
dbPessimistic)
rst.Edit
Me.InvoiceNo = Nz(DMax("[Invoice]", "[tblName]"

+ 1, 1)
ExitHere:
Exit Sub
ErrHandler:
Set rst = Nothing
i = i + 1
If i = conRetries Then
Beep
If MsgBox(i & " attepmts failed. Retry?",vbYesNo + vbQuestion) = vbYes Then
i = 0
Resume start
Else
Cancel = True
Resume ExitHere
Else
Resume start
End If
End Sub
Private Sub Form_AfterUpdate()
Set rst = Nothing
End Sub
'=========End Code=====================
As a side note, you can keep the last generated number in the dummy table and get the value from there. This can speed up the process:
Instead of:
Me.InvoiceNo = Nz(DMax("[Invoice]", "[tblName]"

+ 1, 1)
you can have:
rst.Fields("FieldInDummyTable"

= rst.Fields("FieldInDummyTable"

+ 1
Me.InvoiceNo = rst.Fields("FieldInDummyTable"
and Update the recordset in the AfterUpdate event. However, you have to trap the error 'Update Without AddNew or Edit':
Private Sub Form_AfterUpdate()
On Error Resume Next
rst.Update
Set rst = Nothing
End Sub
As I said, it's faster, but you have to make sure nobody has access to the 'dummy table', otherwise you can have the numbering sequence reset.
Both ways, user won't know the invoice number until finishing the record.
Good luck,
![[pipe] [pipe] [pipe]](/data/assets/smilies/pipe.gif)
Daniel Vlas
Systems Consultant