Self-generating Number

T

trafalgar1978

Good evening everyone,

I built a database to track reprocessing of parts that were fixed
where I work. We are required by instruction to serialize these parts
as they come back in the following format. Last 2 digits of the year
and then the # it came back as. An example of the Serial # is
08-0122. I want to make the database automatically add to this
number
and generate a new one each time a new record is created. i have
tried
several different ways to accomplish this but nothing has worked thus
far. Any help on this issue would be greatly appreciated.


Traf
 
T

trafalgar1978

Lord,

Yes that is exactly what I am looking to accomplish. Your help would
be immensely appreciated.
 
L

Lord Kelvan

the only way i can think of is using a form

and for the field that is that value you would use this setup

serialvaluetextbox.Value = Format(Date, "yy") & "-" &
Format(CInt(Right(DLast("[serialvalue]", "serialvaluetable"), 4) + 1),
"0000")

the people in the formscoding group may be able to help you implement
the above

i dont know how to set the autonumber format property to fo the above
someone else may know but as far as i know you cannot combine
datatypes ie date and int

hope this helps

Regards
Kelvan
 
R

Rick Brandt

Good evening everyone,

I built a database to track reprocessing of parts that were fixed
where I work. We are required by instruction to serialize these parts
as they come back in the following format. Last 2 digits of the year
and then the # it came back as. An example of the Serial # is
08-0122. I want to make the database automatically add to this
number
and generate a new one each time a new record is created. i have
tried
several different ways to accomplish this but nothing has worked thus
far. Any help on this issue would be greatly appreciated.


Traf

Best would be to *store* the value in two fields. A RecordDate field and a
RecordID field. You can then use an expression to *display* a value that
uses both fields as YY-0000.

This makes is much easier and much more efficient to calculate the next
numeric value when a record is created. To do so with a string field that
contains the single value "YY-0000" will be more difficult and slower.

With the two field approach you just use this for display...

=Format(RecordDate, "YY-") & Format(RecordID,"0000")

You set RecordDate's DefaultValue property to =Now() and to calculate the
next available value in a new record you use the BeforeUpdate event of the
form...

If Me.NewRecord Then
Me.RecordID = Nz(DMax("RecordID", "TableName", "Year(RecordDate) =
Year(Date())"), 0) + 1
End If

Broken down the expression finds the highest existing RecordID for records
created this year and adds 1 to it. Zero is substituted for the lookup to
account for the first record of each new year.

The WHERE argument in the above example was used because it is shorter and
easier to understand. A more verbose, but more efficient WHERE argument
would be...

"RecordDate >= DateSerial(Year(Date()), 1, 1) AND RecordDate <
DateSerial(Year(Date()) + 1, 1,1)"
 
B

Bob Barrows [MVP]

Good evening everyone,

I built a database to track reprocessing of parts that were fixed
where I work. We are required by instruction to serialize these parts
as they come back in the following format. Last 2 digits of the year
and then the # it came back as. An example of the Serial # is
08-0122. I want to make the database automatically add to this
number
and generate a new one each time a new record is created. i have
tried
several different ways to accomplish this but nothing has worked thus
far. Any help on this issue would be greatly appreciated.
Do the numbers need to reset to 1 at the beginning of each year?
If not:
Add an autonumber field to the table (call it partcount). Add a field that
defaults to the current year (call it partyear) - set the default property
in design view to Year(Date())). Now a simple expression gives you your
serial number:

right([partyear],2) & "-" & right("0000" & [partcount], 4)

If the numbers need to reset to 1 at the beginning of each year, then I
would suggest creating a table (call it LastSerial) with two fields:
partyear and partcount (the latter should not be an autonumber field).
Select both fields in Design view and click the toolbar button to designate
both to be the primary key of the table. Save it.

Then in the Modules tab, create a new module and add this VBA function (this
has not been tested and may contain typos) to build your serial #:

public function GetSerial() As String
dim db as database,rs as dao.recordset
dim newserial as string,sql as string,errmsg as string
dim t as single, errnum as int

set db =currentdb
sql = "select partyear,partcount from lastserial " & _
"where partyear=year(date())"
db.begintrans
t=timer
do until errnum=0
if timer - t > 30 then
errmsg = "Time out while trying to retrieve next serial #"
errnum=-1
exit do
else
on error resume next
set rs=db.openrecordset(sql,,dbdenywrite,dbpessimistic)
errmsg=err.number & ": " & err.description
errnum = split(errmsg,":")(0)
end if
loop
if errnum <> 0 then
msgbox errmsg
GetSerial = "error"
db.rollback
else
if rs.eof then
rs.addnew
rs(0) = year(date())
rs(1) = 0
rs.update
end if
rs.edit
rs(1) = rs(1) + 1
rs.update
newserial = right(rs(0,2) & right("0000" & rs(1),4)
rs.close
GetSerial = newserial
db.commit
end if
set db=nothing
end function

You can call this function in a form to assign the next available serial #
to a part.
 
J

Jeff Boyce

A potential problem in using an Access "Autonumber" field is that they are
only intended to be used as unique row identifiers. They are not guaranteed
to be sequential, and are generally unfit for human consumption.

A common approach to generating sequential numbers is to build a small
procedure that grabs the maximum value already used (rather than the
"Last"), then adds 1. If the annual reset is needed, the code checks for
the maximum sequence number for the year of the current date (i.e., Date()),
then adds 1 to that number.

Regards

Jeff Boyce
Microsoft Office/Access MVP


Bob Barrows said:
Good evening everyone,

I built a database to track reprocessing of parts that were fixed
where I work. We are required by instruction to serialize these parts
as they come back in the following format. Last 2 digits of the year
and then the # it came back as. An example of the Serial # is
08-0122. I want to make the database automatically add to this
number
and generate a new one each time a new record is created. i have
tried
several different ways to accomplish this but nothing has worked thus
far. Any help on this issue would be greatly appreciated.
Do the numbers need to reset to 1 at the beginning of each year?
If not:
Add an autonumber field to the table (call it partcount). Add a field that
defaults to the current year (call it partyear) - set the default property
in design view to Year(Date())). Now a simple expression gives you your
serial number:

right([partyear],2) & "-" & right("0000" & [partcount], 4)

If the numbers need to reset to 1 at the beginning of each year, then I
would suggest creating a table (call it LastSerial) with two fields:
partyear and partcount (the latter should not be an autonumber field).
Select both fields in Design view and click the toolbar button to
designate both to be the primary key of the table. Save it.

Then in the Modules tab, create a new module and add this VBA function
(this has not been tested and may contain typos) to build your serial #:

public function GetSerial() As String
dim db as database,rs as dao.recordset
dim newserial as string,sql as string,errmsg as string
dim t as single, errnum as int

set db =currentdb
sql = "select partyear,partcount from lastserial " & _
"where partyear=year(date())"
db.begintrans
t=timer
do until errnum=0
if timer - t > 30 then
errmsg = "Time out while trying to retrieve next serial #"
errnum=-1
exit do
else
on error resume next
set rs=db.openrecordset(sql,,dbdenywrite,dbpessimistic)
errmsg=err.number & ": " & err.description
errnum = split(errmsg,":")(0)
end if
loop
if errnum <> 0 then
msgbox errmsg
GetSerial = "error"
db.rollback
else
if rs.eof then
rs.addnew
rs(0) = year(date())
rs(1) = 0
rs.update
end if
rs.edit
rs(1) = rs(1) + 1
rs.update
newserial = right(rs(0,2) & right("0000" & rs(1),4)
rs.close
GetSerial = newserial
db.commit
end if
set db=nothing
end function

You can call this function in a form to assign the next available serial #
to a part.

--
Microsoft MVP - ASP/ASP.NET - 2004-2007
Please reply to the newsgroup. This email account is my spam trap so I
don't check it very often. If you must reply off-line, then remove the
"NO SPAM"
 
B

Bob Barrows [MVP]

Jeff said:
A potential problem in using an Access "Autonumber" field is that
they are only intended to be used as unique row identifiers. They
are not guaranteed to be sequential, and are generally unfit for
human consumption.

True, I addressed this issue in a post I made yesterday. I did not consider
that to be relevant here because the OP made no mention of a need to avoid
gaps.
A common approach to generating sequential numbers is to build a small
procedure that grabs the maximum value already used (rather than the
"Last"), then adds 1. If the annual reset is needed, the code checks
for the maximum sequence number for the year of the current date
(i.e., Date()), then adds 1 to that number.

I believe my second solution addressed this. I know you are aware of the
pitfalls in your recommended approach due to multi-user activity and how to
avoid them so I will let you address them.
 

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