Generating Numbers automatically

G

Gary

I'm using Access 2002.
I have a field called Job No.
It is a text (data type). The reason being that there is an "I" in front of
each number i.e. I1234 I1235 etc
The problem is that when the user enters a new record, he/she has to know
what the last recorded job no. is present in the database, in order to then
assign the next sequential job no. So its a manual process.
I don't want to seperate the "I" component from the Job No. field in order
the make the field an autonumber datatype.
Is there some code I could use to allow the system to somehow automatically
assign the next sequential number incorporating the prefix "I" to each
number ?
thank you for any help.
 
G

Guest

You could try this:

Private Sub AddRecord_Click()
DoCmd.GoToRecord , , acNewRec
Me!IDControl = "I" & (Mid(DMax("[ID]", "[ID Table]"), 2) + 1)
End Sub

This goes in the On Click event of a button on your form (I assumed you are
entering records in a form, NOT in a table). It assumes that the button is
named (not labeled) "AddRecord". Substitute your ID control name for
"IDControl", your Job No source field name for "ID" and your source table
name for "ID Table".

There are other places to put the Job No creator (such as in double click
for the Job No control itself or with another button called, say, "Assign Job
No", etc.). You decide where it is best to put it. I just wanted to suggest
a formulation. Others may discuss where best to put it. And others may
suggest you put am "CInt" around the value extraction (it works without it,
however, but bthere may be some side issues).

Good luck,

HTH Joe
 
G

Guest

Oh, and one other issue. I had assumed (perhaps incorrectly, but falling
back on my experience with job number assignments) that you are fixed
formatting the numeric portion of the JN. That is I00001, I00002, etc., not
I1, I123, I3, etc. If it is *not* fixed format, then the formula has to be
adjusted to make the numeric part an integer *before* incrementing. Let me
know and I'll work up the revision - unless someone beats me to it. <g>
 
G

Guest

Gary: I don't mean to make a career out of this <g> but I'm not happy with
my first solution. You might rather try this (it fits more cases of job
numbers):

Add a field to the query feeding the form - call it, say, "Job Number Part:
Int(Mid([Job No],2))". This will provide the integer part separately.

Then use this calculation to create the new Job Number:

Me!IDControl = "I" & (DMax("[Job Number Part]", "[JN Query]") + 1)

Sub your Job Number control name for IDControl and source query name for "JN
Query" .

I apologize for stumbling on this one. I'll try to do better next time. <bg>
 
G

Guest

Gary: Well, I picked up my brain off the floor and rebooted it and now think
I got the syntax right from my *first* reply. (Simpler than moding the query)


Me!IDControl = "I" & (DMax("Int(Mid([ID], 2))", "[ID Table]") + 1)

Substitute this in the first post sub routine. I tested this and it works
(gosh I hope so by now) no matter the number format.

Sorry to all you guys for so many posts. I'll *not* do this again.
 
G

Guest

Gary:

While simply looking up the maximum existing value of the column and adding
1 will work fine in a single user environment, in a networked multi-user
environment there is the possibility of a conflict. One means of avoiding
this is to store the last value in a separate database which is opened
exclusively to get the next number. The following is the module I use for
this. The external database is tblCounter.mdb with a single column,
NextNumber of long integer number data type. In this code the external
database is assumed to be in the same folder as the back end .mdb file
containing the tables. Note that the code uses DAO, so you'll need a
reference to the DAO object library (Tool|References on the VBA menu bar).
Some day I'll get round to writing an ADO version.

I your case, assuming the format required is I followed by four digits, you
could call the GetNextNumber function from the form's BeforeInsert event
procedure with:

Me.[Job No] = "I" & Format(GetNextNumber,"0000")

Note that this behaves like an autonumber column in that any discarded
numbers are not re-used.

''''module begins''''
Option Compare Database
Option Explicit

Dim dbsCounter As DAO.Database, rstCounter As DAO.Recordset

Public Function GetNextNumber() As Long

Const NOCURRENTRECORD As Integer = 3021

Set rstCounter = dbsCounter.OpenRecordset("tblCounter")

On Error Resume Next
With rstCounter
.Edit
' insert new row if table is empty
If Err = NOCURRENTRECORD Then
.AddNew
!NextNumber = 1
.Update
GetNextNumber = 1
Else
' update row and get next number in sequence
!NextNumber = !NextNumber + 1
.Update
GetNextNumber = rstCounter!NextNumber
End If
End With


End Function

Public Function ConnectPath() As String

Dim dbs As DAO.Database, tdf As DAO.TableDef
Dim strConnectString As String, strDbName As String, intSlashPos As
Integer

Set dbs = CurrentDb

For Each tdf In dbs.TableDefs
If tdf.Connect <> "" Then
strConnectString = tdf.Connect
End If
Next tdf

intSlashPos = 1
strDbName = strConnectString
Do While intSlashPos > 0
intSlashPos = InStr(strDbName, "\")
strDbName = Right(strDbName, Len(strDbName) - intSlashPos)
Loop

ConnectPath = Mid(strConnectString, 11, Len(strConnectString) _
- (10 + Len(strDbName)))

End Function


Public Function OpenCounterDb(strCounterDb) As Boolean

' Opens external Counter database exclusively
' Returns True if able to open external database

Dim n As Integer, I As Integer, intInterval As Integer

' make 10 attempts to open external database exclusively
DoCmd.Hourglass True
SysCmd acSysCmdSetStatus, "Attempting to get new number"
On Error Resume Next
For n = 1 To 10
Err.Clear
Set dbsCounter = OpenDatabase(strCounterDb, True)
If Err = 0 Then
Exit For
Else
intInterval = Int(Rnd(Time()) * 100)
For I = 1 To intInterval
DoEvents
Next I
End If
Next n
SysCmd acSysCmdClearStatus
DoCmd.Hourglass False

If Err = 0 Then
OpenCounterDb = True
End If

End Function

Public Function CloseCounterDb()

On Error Resume Next

' close recordset and external databse if open
rstCounter.Close
dbsCounter.Close

Set rstCounter = Nothing
Set dbsCounter = Nothing


End Function
''''module ends''''
 
G

Guest

Gary:

Ooops! The external database is called Counter.mdb; tblCounter is its one
and only table. Full code to get a new number would thus be:

''''code begins'''
On Error GoTo Err_Handler

Dim strCounterDb As String, lngID As Long

strCounterDb = ConnectPath() & "Counter.mdb"

'attempt to get next number
If Not OpenCounterDb(strCounterDb) Then
MsgBox "Unable to get ID number at present.", vbInformation, "Error"
End If

Me.[Job No] = "I" & Format(GetNextNumber,"0000")

' close external counter database if open
CloseCounterDb

Exit_Here:
Exit Sub

Err_Handler:
MsgBox Err.Description, vbExclamation, "Error"
Resume Exit_Here
''''code ends''''

Sorry for any confusion.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top