custom number format

ksgirl

Registered User.
Local time
Today, 20:52
Joined
Jul 1, 2002
Messages
53
OK. Here is my problem. I need a number/text (I'm pretty sure I need a text) format that does the following: 02-00000. The first two digits are the last two digits of the year and the last five digits are incremented by one each time a new one is needed. This is what I've worked on so far:
=Format(Now(),"yy") & "-" & Format(.....this is where I need help!)
and have placed it in the default value of the field's properties in the table design view. So far I get the "02-" to show up!!! But I'm not sure if I need to use Dmax or what for the rest of the number format! I'm really clueless, so if anyone has any information to steer me in the right direction I would aprreciate it.
:confused:
~Nicole
 
If I generate this in a BeforeUpdate event how do you suggest I do this? I've searched through the forums and can't find much help. I've been given advice on this same topic and another Access Programer suggested to do what I stated in the first post....so now I'm confused! I ultimately want the table to generate these numbers like an autonumber format....just with the "02-" for the year!!! I know I can just go in and type that as a prefix to the autonumber, but I don't want to have to change that when the year turns over. There has to be a way to do this. Does anyone else have any suggestions????
 
ksGirl,
It is possible to do what you want, but as Pat suggested you should explore alternatives first, like using an internal autonumber and only displaying your built key on will (not storing it, much less even using it as a primary key)
Ex: use an internal autonumber and a textbox to display:
Format(Now(),"yy") & "-" & [ID]

Now, this will quickly show you the limits of this approach and why you should think carefully before using built ID.
Ex:
you have 3 records:
1 -> 02-0001
2 -> 02-0002
3 -> 02-0003
Now an user deletes record 1 and 3 and adds a new record. The new situation will become:
you have 2 records:
2 -> 02-0002
4 -> 02-0004

Other example
you have 3 records:
1 -> 02-0001
2 -> 02-0002
3 -> 02-0003
Now an user cancels a new record he/she was entering. Late he/she adds a new one. The new situation will become:
you have 3 records:
1 -> 02-0001
2 -> 02-0002
3 -> 02-0003
5 -> 02-0005

You cannot expect to have consisent sequential numbers that way.Does it mind to you?
If yes, then 1. you've already understood that you should NOT take the risk to build AND rely on them as primary keys. 2. I can show you a method to avoid such gaps but you should keep in mind that it is not 100% reliable in multi-users and replication environements.
 
Last edited:
I do not need consistent sequential numbers....all I need is a numbering field to display "02-00000". If one is deleted, say 02-00005, and the next one displayed is 02-00006....that is great! I just need a way of having an ID number that displays the current year as the first two digits and increments so that each ID has an unique value! I hope this helps! Let me know if you need more information!
~Nicole
 
Then, in the controlsource of a control on your form, put:
=Format(Now(),"yy") & "-" & left("00000",5-len(cstr([ID]))) & [ID]
where ID is the name of a textbox (eventually hidden) of your form, bound to the autonumber ID of your records.

but you will run into troubles if your autonumber happens to reach 100000 (which does't mean 100000 records as showed above)
 
Last edited:
So if I understand this correctly, the ID won't save in the table as the format I want? It will just display on the form? If this is the case, I don't want this to happen. I want to be able to save the ID with the "02-" or "03-" in front of it into the table. This is because there will be a historical table that has ID's clear back to 1980's so there will be "85-", "93-", etc...... I just want the new ID's to have the same format! Maybe I'm just making this too complicated. I know it can be done, I just need pointed in the right direction. Is there anyway this can be done? Thanks for all the help Alexandre....I appreciate it greatly!
~Nicole
 
The formula I provided to you can be used to store the result in your underlying table if you really want to. But you should not. Make a new field to store the year instead. Then, at any moment, you can retrieve the serial number by using the formula.
If you store the result of the formula, you duplicate data in your DB (Date and/or autonumber) to the least. Potentially, you also create room for inconsistancy among the data you stored since it is hard to ensure that under all cirumstances (updates, deletions, data import...) your built and stored serial number will be properly updated to reflect your Year field and your autonumber.

Now if you really want to do it, you CAN. This is just not a good idea.
To automatically store the year , there are various approaches available. I believe the easiest consists in (after creating the adequate field in your underlying table) setting the fied default value the default value to:
=Right(Year(Now(),2)) to only store the current year (my advice)

Now if your want to store your serial, it is more complicated because you can't refer to fields in the same table in a formula set at table-level.
You'll have for example to set a textbox bound to your serial field on your form, with the default value:
Format(Now(),"yy") & "-" & left("00000",5-len(cstr([ID]))) & [ID]
Or you can also do it using the Before Update event as Pat suggested...
But remember, whatever the method you will use, you will have difficulties to ensure that it won't fail under certain circumstances (ex: data import, action query, pasted records...)

Hope this helps
 
Last edited:
I know it is demanding much for someone like you, Rich. But try to keep serious an do some useful work, for a change. I don't know... For example, find Title for me! :)


BTW, I thought I had some understanding of French, but while I know what is 'bas' and 'bleu', 'bas-bleu' is something new to me. Is this another wild, progressist English concept? (like your unequalled measurement units system, or something of the kind...) :D
 
Last edited:
I guess I'm confused now. I am still extremely new to all of this, so be gentle! Let me give you a run down of my situation. I am an intern doing a project.....long summer to say the least. Anyway, they have a current system, but want something that is more user-friendly....this is where I come in....and they want me to do this on access. Currently the system they have has all the ID's generated from years past stored in the usual format. I am just trying to make my life simpler for when I have to transfer all the past ID's into the new system. I know I am going to have a historical table of all these ID's (where I just input the existing ones into a field in the "00-00000" format), but the new system needs to be able to generate such a number. I guess I don't understand why you say that...
"If you store the result of the formula, you duplicate data in your DB (Date and/or autonumber) to the least. Potentially, you also create room for inconsistancy among the data you stored since it is hard to ensure that under all cirumstances (updates, deletions, data import...) your built and stored serial number will be properly updated to reflect your Year field and your autonumber."

Why is not a good idea to store the year in front of the autonumber? That is how the other ID's are stored! Basically, a user will be able to access the database to either create a new Clearance, or to look at old Clearances by this ID. They will input 95-04672 etc....to look at that Clearance. Does this make sense?

I did try what you suggested, by adding the serial field and another text box to the form with the appropriate default value, and all I get in the new text box is "02". Maybe I need to get rid of the autonumber format with the current ID field and come up with a way to just increment the last five digits of the ID. I'm just lost! Thanks for all your help. If you have any other suggestions, it would be greatly appreciated.
~Nicole
 
Actually, old heavy one, I was being serious. I've seen many posts where posters insist on storing pk's /nos. in this way and have always wondered what advantage this gave db. design.
After your lurid explanation I now realise there is none, and further investigation is pointless.
bas_bleu is next in line for Poo_Bah:)
 
ksGirl,

I am going to tell you what I believe is the best to do and that I would most sincerily do if I were in your case. I had VERY painfull experiences with built-and-stored Primary keys when I worked on replicated DBs and sweared I would never go into this again.

I would:
1. Seek to save into an excel spreadsheets all tables holding those serial numbers that you have to import from the old DB.
This is because you will be able to easily do some string-processing there,
2. Using two formulas, split the serial number into two columns, and give names (ID and Year) to these columns: Right(A1;5) will give you the 5 digits number and Left(A1;2) the two digits year
Note that you could also import your tables directly into acces and use action queries for the same result, but this seems simpler.
3. Create your destination tables in Access with the fields:
- ID as an autonumber
- Year as an integer
... your other fields
4. Use the GetExternalData -> Import Menu to import your Excel spreadsheets into your tables.
5. If you did it well, the autonumber field should be filled with your 5 digits numbers, your Year field with the rest of your serial key and you will be able to apply the method I suggested from now on in your new database (ie use a formula to display, do not store, and set default value for theyear field)

Does this help?

Edit: Forgot something important. Actually the autonumber (ID) is not your primary key in this case. Instead, you would use a two-fields primary key made of Year and ID (select both fields in table design and make them a primary key. A key symbol should show on both lines if you suceeded)
 
Last edited:
BTW, you will notice that your autonumber will continue numbering starting from the highest value you imported in your table. And if that number is already high you will feel relieved to have followed my advice (because your 00-00000 format would have failed as soon as the autonumber reaches 100000).

Let me sum up why this is better than storing the 00-00000 serial:
- Method never fails even if the autonumber goes over 99999 (which can happen WITHOUT having 99999 records in your table, see my previous example)
- No data redundancy
- No risk to get unconsistent data if the user does something that does not trigger your build-and-store-my-serial-key strategy.
- No risk to create conflictual (duplicate when they ought to be unique) serial keys in multi-users or replication environments.

Please, tell me that you are less confused about this, now...:)
 
Last edited:
Thanks Pat and Alexandre. I will tackle your suggestions in the morning! Alexandre- I do now understand why, but in my mind, and of course I'm naive about things, there should be a simpler way!!! I think having an ID this way is stupid too, but as Pat has mentioned, I really have no other options! I came into this internship not knowing anything about access and have self-taught myself along the way....that is probably my biggest problem. I guess that is what I deserve being an engineering student! I'm only here for five more weeks, and then they will pass this task onto someone else! So I have to tough it out for now! Fun, fun! I am very greatful I have found such a wonderful website and people like you to give people like me advice! Thanks again, and keep your eyes posted...I'm sure I'll have more questions involving this one!
~Nicole
 
I just feel like I'm making a fool of myself over this stupid question! And both of you have been wonderful in trying to help me, so I thought I would rack your brain some more. Ok....I think this might work. Let me give you a run down of what I've done:

In the table:
*two fields- 'Clearance ID' (autonumber) and 'Year' (default property set to =Format(Now(),"yy"))
?Do I need to set both of the fields to be primary keys?

In the form:
*Clearance ID field-
Control Source= [Clearance ID]
Default Value= [Year] & "-" & [Clearance ID]
Before Update= [Event Procedure]

Private Sub Clearance_ID_BeforeUpdate(Cancel As Integer)

Dim stNextNum As String

stNextNum = Format(Nz(DMax("[Clearance ID]",
"[Clearance Cover Page]", "Year = Format(Year(Now(),2))"),
0) + 1, "00000")

End Sub

Everything seems to be working fine, no errors at least. But it doesn't store in the table as the "00-00000" format. Plus, when I go to just search the current clearance table, (I have a query that runs the search and a message box pops up for you to enter in a Clearance ID), you just type in "1" not "02-00001" and it pulls up the whole Clearance. I would like for the user to type in the whole format...which I believe they will have to with the 'old' clearance IDs. Oh and when you are entering in a Clearance (on the first form), in the 'Clearance ID' field the number that appears is "00-00023"....somewhere along the lines the "02-" is missing. Am I over looking something? If you are too busy, don't worry about me....I'll just keep plugging away. But I do appreciate all your help. Thanks again.
~Nicole
 
1. You have to make a choice between Pat's suggestion and mine. They are fundamentally the same with one difference: Pat provided you with a formula that simulates an autonumber and WILL RESET for each different year (ex: 02_00001, 02-00002, 02-00003, 03-00001), but you will have to manage POTENTIAL DUPLICATE keys conflicts in multi-users environment, as she explained.
Mine won't reset (ex: 02_00001, 02-00002, 02-00003, 03-00004), but uses true increment autonumber (so you don't have to worry about duplicates. This is managed by Access)
If you decided to go for the autonumber, you can use a two-fields primary key as I suggested, but you do not really need to, since Access will take care of ensuring the uniqueness of the autonumber. It would be really necessary if you decided to use Pat's formula which do not produce unique numbers, but reset for each new years (In that case, only the association year + number may be unique)

2. Neither my nor Pat's suggestion will ever store a built serial key in 00-00000 format in your table. We both exposed extensively why this would be bad practice! Our suggestions will store separately the year and a sequential number, and DISPLAY your 00-00000 format serial. Your users won't see the difference.
Perhaps I was not clear on that, but Pat was: you won't let anyone fill the serial number. On the contrary you will disable/lock this control. Your serials are built automatically through the methods we suggested!
It is a VERY bad idea to let the users enter/modify primary keys! Among various reasons for that: you would have to write code to trap already existing keys entered by your user and get them corrected; You would have also to provide to your users an easy mean to know what keys have already been used...

3. Did you consider Pat's advice regarding negotiating the year format with your customers? (code the year on 4 digits instead of 2). This is something I had hesitated to recomand also. Although not vital, it is practical.

4. Your form Clearance_ID control is not ok. First call it txtSerial, for example, to avoid any confusion with the Clearance_ID field which is only an incrementing number, not the entire serial you want to display. Then, with the method we suggested, you would not use a bound control since your built serial key would not actually be stored in your database. You would just display it on the fly. So txtSerial should be an unbound textbox with acontrol source set to : = [txtYear] & "-" & [txtClearance ID]

5. I suggested to use the default value =Right(Year(Now(),2)) for your txtDate bound control, and not for txtSerial, as an easy mean to store the current year in your underlying table whenever a new record is created.

6. I don't know where you took Format(Year(Now(),2))
I suggested Format(Now(),"yy") and Right(Year(Now(),2)) (unconsistent me ;))
and Pat's: Format(Date(),"yy")
All give the same result. Pat's formula is somewhat more efficient.

7. The above mentionned = [txtYear] & "-" & [txtClearanceID]
in txtSerial implies that you should have two other controls on your form called txtYear and txtClearanceID (note the prefixes to help to distinguish between controls and fields, and to identify a textbox)
These are bound (to Year and ClearanceID) controls, which may be invisible. Why using invisible text boxes ? There would be other ways to get the Year and ClearanceID corresponding to the current record of the underlying table, but this is a very simple way to have them at disposal automatically.

8. Avoid spaces in you field and table names: use Clearance_ID or ClearanceID and ClearanceCoverPage etc.

Please, tell me if I am speaking Chinese. I know my poor English can be confusing. You may get clearer explanations from Pat or others.
 
Last edited:
Alexandre, your English is great, and I am learning so much more than I would have on my own. I also understand why I have to make two separate fields to achieve what I want. My only concern is when I input the old data into the system. Right now, I am just making a temporary database, with only a few records (lets say 10 or so) in each of the tables. To get all the gliches worked out before we input all the old data...... With these Clearance ID's, they are generated at random (or incremented, I'm not sure) for each year. So, for example, 02-05873 might be similar to the 98-05873, with the year just being different. I don't believe this occurs very often, and yes they are in our terms "duplicate" numbers, so that is why I have been asking all these questions. I guess what I'm really wanting, I can't seem to achieve. I am needing the user to have to type in the whole "00-00000" format, so that they can access all the records. I believe with Pat, that in assuming that autonumber will not be useable in my case, but what other options do you think I have? Do you see my frustration? I haven't attempted any of your suggestions yet, but I will tackle them this morning, and of course let you know my progress! Thanks again.
~Nicole
 
AHHHHHHHHHHHHHHHHHHHHHHHHHHHHH! You don't know how happy I am that it works!!! I made some adjustments such as:
with the unbounded 'txtSerial' text box so that it displays "00-00000" (it was dropping the leading zeros on the autonumber field) I changed the control source to =[txtYear] & "-" & Format( [txtClearance ID], "00000")....and everything works like a charm. Thanks for all your help!!!!!!!!!!! Now I have to go through all the other forms I have, and change their properties to display this new ID....so it is going to take me a while, but I'm glad I had your expertise in helping me solve this extremely frustrating problem!!!!! I am going to leave the conversion suggestions for who ever takes this project over, that you (Pat) suggested, but you might see someone on here in a couple months wanting some advice!:D

Thanks again!
~Nicole
 
Before going for an autonumber (as per my suggestion) instead of Pat's incrementing number formula, did you take into account the point Pat just made that if your orginal (old) dataset may contains serials with an identical right part for two different years (ie 01-00006 and 02-00006) then using an autonumer would not allow you to import your old data in your new DB? (since autonumbers must be unique)
 

Users who are viewing this thread

Back
Top Bottom