Hi Amit
Thanks again for your prompt and thoughtful response.
My pleasure
I think I'll continue using an Autonumber PK, but just to number the
record,
I'll add another numeric field whose value I calculate. Yes, I'm aware
that
this will cause some duplication, but I feel comfortable having an
Autonumber
PK.
I think there is nothing wrong with doing this, but some would advise that
you should use the "natural" key as your primary key if there is one
available.
Will this work in a multi-user environment though?
Yes, unless two users are asking for the next number at exactly the same
time. If this happens, and they get the same number, the first to save the
record will be successful and the second will get a "duplicate index" error.
So, you need to have some logic in your code to handle such an error and
"retry" to get the next available number.
And, what are the advantages of using this query over using (DCount +1) to
assign value to this control?
You said you wanted to fill the gaps in your numbers that were left after
deleting records. The DMax+1 method (NOT DCount!) will give you a number
one greater than the highest already in the table, but it will not fill the
gaps.
I'm not sure I understand this. If the SeqNum is being incremented by 1
right from the start, there shouldn't be any gaps. So, for example, if
currently, I have 5 records with SeqNum 1, 2, 3, 4, 5; and then do some
testing by adding 3 records (SeqNum = 6, 7, 8) and then delete these 3
records after testing, the next record added will/should have a SeqNum =
6.
Whereas in case of using an AutoNumber, it would be 9.
Ah! Do you mean that you would only delete records from the END of the
table. I assumed you were deleting them anywhere and therefore leaving gaps
in the numbers.
If you are only concerned with deleting records from the end of the table
after testing, the following function might be helpful. It works for both
local and linked tables, and resets the autonumber to (by default) the next
unused number.
Public Function ResetAutonumber( _
sTable As String, _
Optional sField As String, _
Optional lSeed As Long _
) As Long
'sTable = Table containing autonumber field
'sField = Name of the autonumber field
' (default is the first Autonumber field found in the table)
'lSeed = Long integer value you want to use for next AutoNumber
' (default is one more than the current maximum)
Dim cnn As Object 'ADODB.Connection
Dim cat As Object 'ADOX.Catalog
Dim col As Object 'ADOX.Column
Dim tbl As Object 'ADOX.Table
Dim sRemoteTable As String
On Error GoTo ProcErr
Set cat = CreateObject("ADOX.Catalog")
cat.ActiveConnection = CurrentProject.Connection
Set tbl = cat.Tables(sTable)
If tbl.Type = "LINK" Then
Set cnn = CreateObject("ADODB.Connection")
cnn.Open _
CurrentProject.Connection.ConnectionString & ";" & _
"Data Source=" & _
tbl.Properties("Jet OLEDB:Link Datasource")
cat.ActiveConnection = cnn
sRemoteTable = tbl.Properties("Jet OLEDB:Remote Table Name")
Set tbl = cat.Tables(sRemoteTable)
End If
If Len(sField) = 0 Then
For Each col In tbl.Columns
If col.Properties("AutoIncrement") Then
sField = col.Name
Exit For
End If
Next
If Len(sField) = 0 Then GoTo ProcEnd
Else
Set col = tbl.Columns(sField)
End If
If lSeed = 0 Then
lSeed = Nz(DMax(sField, sTable), 0) + 1
End If
col.Properties("Seed") = lSeed
ResetAutonumber = lSeed
ProcEnd:
On Error Resume Next
If Not cnn Is Nothing Then
cnn.Close
Set cnn = Nothing
End If
Set col = Nothing
Set tbl = Nothing
Set cat = Nothing
Exit Function
ProcErr:
MsgBox Err.Description
Resume ProcEnd
End Function