Sequential record numbering within "parent" group

Posted on 2004-09-20
Last Modified: 2008-03-10
Greetings all...

I'm setting up a hierarchy of three related datasets. The governing entity is a PROJECT. A PROJECT may in turn contain multiple ZONES, and each ZONE may in turn contain multiple OBJECTS.

I'm experiencing a brain cramp. Typically I would let Access assign unique ID numbers (autonumbering) for each new ZONE that is created within a PROJECT, but in this case, it will be important for the users to have a "handle" for each ZONE which they can use in referencing any ZONE. This kind of easily identifiable "handle" would not really exist (unless of course the user was asked to assign the ID for each new ZONE), because with autonumbering, the assignment of new ZONES won't have any discernible pattern: the first ZONE for any PROJECT may be assigned ID #345, the second may be assigned #962, and so on.

Maybe I'm just worrying about aesthetics, but it would be nice to have the first ZONE assigned to any PROJECT receive ID #1, the second #2, and so on. So the "Big River" PROJECT has ZONES 1 - 15, the "Little River" PROJECT has ZONES 1 - 9, and so on. My gut feeling is that the only way to gain this sort  of autonumbering would be to set the ZONE ID field as LONG, automatically create ZONE 1 when the PROJECT is created, and then fire off a manual routine each time a new ZONE is created which would determine the MAX number that has already been assigned within that PROJECT and just increment it by 1. Index the ZONE table on both PROJECT ID and ZONE ID. Then repeat the same process in the OBJECT table, indexing that table on PROJECT ID, ZONE ID and OBJECT ID.

Do I think aright? Or am I forgetting an obvious element of functionality that Access provides that would handle this kind of repetitive numbering within "Parent" groupings?

Thanks, folks. I never cease to be amazed at the breadth and depth of talent out there, and I look forward to your feedback.

Question by:jofoco4
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
LVL 41

Expert Comment

ID: 12107156
You could use a manual procedure to assign your zone IDs, but I wouldn't recommend it. Autonumbers should never be visible to the user and shouldn't be have any meaning - the only thing you can rely on them for is to be unique within their own sequence.

However, you could determine which zone a particular record is, within its parent. An expression like this:
DCount("*","ZONES","[ZoneID]<" & Me!txtZoneID & " AND [ProjectID]=" & Me!txtProjectID)+1

on a form that contains the zone's autonumber in txtZoneID and the projectID in txtProjectID would tell you which zone that is in relation to its project. So for example, if project 12 has zone records 345, 346 and 347, the expression would display 2 for zone 346, since there is 1 zone with a lower number than itself for projectID 12. This would only work though if zones were never deleted from that project.

Expert Comment

ID: 12108514
I have an application where entities are added with an autonumber PK but also have a sequence number which is meaninful and which will not be changed unless the user changes it. (This might be a problem with the solution above- if a zone is deleted the others would get different numbers- is this what you want?)

When the user adds a zone I assign it a new sequence number in the BeforeInsert event, by finding the next available number. (If 1,2, and 3 have been used it will be 4, but if 2 has been deleted the new one will be 2.) I do this in a small routine that reads through a recordset that contains the entities that are children of the same parent. I also provide a button on the form to "compress" the numbers, so that if an entity has been deleted leaving the numbering as 1,2,4,5 it will move 4 and 5 down to fill the gap.

I can post code samples if it would be useful.

Author Comment

ID: 12112543
Thanks to you both, Shane and Clippit...

Shane, I absolutely agree with you in principle regarding the use of autonumbers. However, as you suggest, if zones are deleted (and this will inevitably happen, unfortunately) "the results might become unpredictable".

Clippit, it sounds like we're onto something here. And yes, a few code samples would defitely help me orient. The compression functionality is probably more than I'll need; I don't mind a deleted zone burning a numeric assignment as long as the results are (for example) 1, 2, 3, 5, 6 ... that would still be very workable within the environmental context.

Thanks to you both. I'll leave the question open for another day or two for Clippit and I to yak a bit more ...

Ransomware: The New Cyber Threat & How to Stop It

This infographic explains ransomware, type of malware that blocks access to your files or your systems and holds them hostage until a ransom is paid. It also examines the different types of ransomware and explains what you can do to thwart this sinister online threat.  


Accepted Solution

Clippit earned 250 total points
ID: 12114045

As I said, I set the "Sequence Number" in the BeforeInsert event. My code is pretty complex and probably does more than you need, so here's a simple version I just whipped up.

Option 1- DMax: Simple, but may be a performance problem:
Private Sub Form_BeforeInsert(Cancel As Integer)
  Me.Sequence_Number = DMax("[Sequence Number]", "EntityTest", BuildCriteria("ParentEntity", dbLong, Me.Parent.EntityID)) + 1
End Sub
(note the use of the seldom used function BuildCriteria to make the DMAX statement easier to build. In my scenario the form is a subform and the parent entity id is retreived from the parent form)

Option 2- slicker as it uses the form's recordset which is already open:
Private Sub Form_BeforeInsert(Cancel As Integer)
Dim rsFormData As DAO.Recordset
Dim intMax As Integer
Set rsFormData = Me.RecordsetClone
Do While Not rsFormData.EOF
  If rsFormData![Sequence Number] > intMax Then
    intMax = rsFormData![Sequence Number]
  End If

Me.Sequence_Number = intMax + 1

End Sub

Option 3: Use a text box on the form to calculate the existing max sequence (presumable the text box should be hidden):
Create a text box in the form footer with an experssion like:
=Max([Sequence Number])
Then make the code:
Private Sub Form_BeforeInsert(Cancel As Integer)
Me.Sequence_Number = Nz(Me.txtMaxSequence) + 1
End Sub

All these options assume records will always be added through the form.

Author Comment

ID: 12115874
Once again, many thanks for your thoughts...

Expert Comment

ID: 12118771
You're welcome- thanks for the grade.

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A simple tool to export all objects of two Access files as text and compare it with Meld, a free diff tool.
It’s been over a month into 2017, and there is already a sophisticated Gmail phishing email making it rounds. New techniques and tactics, have given hackers a way to authentically impersonate your contacts.How it Works The attack works by targeti…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
What’s inside an Access Desktop Database. Will look at the basic interface, Navigation Pane (Database Container), Tables, Queries, Forms, Report, Macro’s, and VBA code.

740 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question