Sorry, I got the two of you mixed up; I meant 'Bruce's reply'.
As regards the DefaultValue property, for simplicity I was unduly brief
in
my explanation as it’s a little more complex in fact. The behaviour if
you
set it to an expression of the type you posted in the properties sheet
is
in
my experience as follows:
1. If a series of new records are inserted in the form it updates the
value
correctly for each new record.
2. If a record prior to the latest one is deleted then this obviously
leaves a gap in the sequence, correctly so for most purposes (it is of
course
possible to 'fill the gaps' with a more complex solution if that should
be
required).
3. However, if a new row is inserted, then deleted in the same session
of
the form before a further record is inserted then the DefaultValue
property
remains static so the next number is 2 after the last number in the
table
rather than 1 after. Now, its arguable that this is correct behaviour
as
there is no difference in principle between deleting the latest record
and
a
prior one in the sequence. However, in practice that would for most
purposes
be regarded as incorrect behaviour, as most people would want the
number
following the latest row existing in the table as of now to be
inserted,
rather than the number following the latest record which existed before
its
deletion. It might be thought that its unlikely that this situation
would
arise, but Murphy's Law states otherwise!
So neither solutions are 'incorrect', but setting the value in code
seems
to
me to safely answer the more usual requirements for this sort of thing.
The above is really a question of the 'mechanics' of the application,
however, and not overly significant. What's more important is the need
to
control the uniqueness of the year/incrementing number value
combination
in
the table definition, which does require the current year value to be
inserted at a column position in each row. This does mean that the
table
is
not properly normalized of course as the DateField column is
functionally
dependent on only one part of the key, not 'the key, the whole key and
nothing but the key, so help me Codd'. But I can't see any way to
avoid
that
(though I'm more than happy to be corrected if otherwise).
Another possible solution of course is not to have a current year or
incrementing number column at all, but to compute the serial numbers
within
each year on the fly from the date column. I suspect this would be
inappropriate, however, as the numbers would vary as rows were deleted
from
the table or if a row were inserted out of date sequence, so as part of
a
fixed identifier would be useless.
Ken Sheridan
Stafford, England
:
For some reason I don't see Robert's reply in my newsreader. Your
response
to my comments (including Robert's reply, is the first I have seen).
I'm not sure what you're saying about the Default Value property on
the
property sheet. If you're saying the Default Value property remains
the
same for all records until the form is closed and reopened, that has
not
been my experience.
message
You'll need to set the DefaultValue property in code. If you set it
in
the
properties sheet its value will remain static until the form is
closed
and
reopened again. Set it in the form's Current event procedure with:
Me.NumInc.DefaultValue = _
"""" & Nz(DMax("[NumInc]", "[tblMain]", _
"Year([DateField]) = " & Year(Date)), 0) + 1 & """"
Note that the DefaultValue property is a string expression
regardless
of
the
data type of the field in question so should be wrapped in quotes
characters
as above. In fact in this case it wouldn't make any difference if
the
quotes
characters were omitted, but in other circumstances they are
crucial,
particularly with a date/time data type.
BTW the control Robert meant you could hide was the NumInc control,
not
the
unbound control which concatenates the current year value with the
formatted
NumInc value.
Another point is that you won't be able to use the DateField and
NumInc
fields as the primary key as this would not prevent duplicate NumInc
values
within one year. You would need to create another field,
CurrentYear
say,
with a DefaultValue property of Year(Date()) and use this and NumInc
as
the
composite primary key. In which case the above code could be
changed
to:
Me.NumInc.DefaultValue = _
"""" & Nz(DMax("[NumInc]", "[tblMain]", _
"[CurrentYear] = " & Year(Date)), 0) + 1 & """"
The CurrentYear field need not be shown on the form of course.
Ken Sheridan
Stafford, England
:
Thanks for the information. I tried it exactly like you described
and
even
tried it with a blank database using your exact names but I'm even
greener
than green and didn't get it to work.
The box you said I could hide says 2008-39448 Whenever I press Add
Record
button I get #Error in both boxes.
I'm trying to learn Access but it doesn't seem to be willing...
That wouldn't be autonumber as the term is used in Access.
Autonumber
is
an automatically generated number that is almost certain to be
unique,
but
it is for use by Access, and in most cases will not be seen by
the
user.
Also, it cannot be guaranteed not to leave gaps in the numbering
sequence.
If it is possible to avoid gaps it is very, very difficult.
However, what you want can be done with an expression. First,
though,
there is no need to store the year if there is a date field in
the
record.
I will call that field DateField, and the incrementing number
NumInc.
For
purposes of this reply, they are both in a table named tblMain,
which
is
the Record Source for a form.
On the form, bind a text box to the NumInc field (that is, select
NumInc
as its Control Source). This is done on the text box property
sheet.
To
see the Property Sheet, open the form in design view, right click
on
the
text box, and select Properties. This will open a box with five
tabs
(if
it is not already open): Format, Data, Event, Other, and All.
Click
the
Data tab to find the place to set the Control Source. You may
already
know about the Property Sheet, but you identify yourself as a
beginner,
so
there it is just in case. Also on the Data tab is Default Value.
This
applies only to new records. In the Default Value row add the
expression:
=Nz(DMax("NumInc","tblMain","Year([DateField]) = " &
Year(Date())),0) +
1
You can hide this text box. In another text box, set the Control
Source
to:
=Year([DateField]) & "-" & Format([NumInc],"0000")
Look up the functions Nz, DMax, Year, Date, and Format in Help to
learn
more about what is going on here. In general, the first
expression
is
telling Access to find the largest value in the NumInc field in a
record
in which the year in DateField is the same as the current year,
and
to
add
one to that number. Nz is for the first record of the year.
There
is
no
maximum value, so the DMax result is null. Instead of Null,
Access
uses a
0 as the value, and adds 1 to it.
The second expression combines the Year from DateField, a hyphen,
and
the
number formatted with leading zeros as needed for numbers less
than
1000.
Hello, I'm new to access and trying to learn by reading and
trying...
I would like to use a primary key ID in a table that would be
the
current
year - 0001 and then auto count up for each record.
2008-0001
2008-0002
Then 1/1/2009 start
2009-0001
2009-0002
and so on.
If this is a stupid idea I would like to do this in another
field
in
the
table.
I'm also looking for a way to Close a record so it can't be
changed
without first reopening the record.
Thanks,
Robert
[email protected]