Re: Automatic Sequential Numbering of Non-Sequential Items (READ JUN 9 2021 FOLLOW-UP)

3036 2
Showing results for 
Search instead for 
Did you mean: 

This setup allows Airtable to automatically number collections of items that may not be in sequential order. Item length can be either fixed or variable, with only minor changes needed to the core system to accommodate the latter.

To borrow from the thread that inspired this endeavor, say you’re building product codes that have a variant sub-code, and want that sub-code to automatically increment each time an item of a given product code is added in a new record. However, it needs to auto-increment each product’s sub-code separately, even when product codes are added out of order.

For example, the first product code is 001, and its initial sub-code is 1, so the full combined code is 001-1. When you add a new variation of product 001, the sub-code bumps up by 1, creating 001-2.

Now a new product is introduced with code 002. Because it’s the first of its kind, its full combined code is 002-1. If we then introduce a third variant of product 001, it would end up with a combined code of 001-3.

So far our full product codes, in the order they were created, look like this:


For a small list, creating these manually might not be a problem, but most people don’t use Airtable with small lists. :winking_face: It would be much easier to manage if the variant codes would auto-increment each time we add a new product code.

This independent sequential numbering requires some knowledge of how many of each item came before the current one, no matter how far back in the list those previous items might live. Because each Airtable record is independent, not having any “knowledge” of any other records in the same table, there’s no direct way to reference other records to make this count. However, with a little table and field trickery (inspired by the work of @W_Vann_Hall), this can be done. The core method requires items of a fixed length, but with a minor adjustment it will also work to track items of varying lengths.

Here’s a sample base that you can copy if you wish to dig into the guts of the system, which are described below.

Core Solution
Only two tables are required:

  1. The main table recording the items to be tracked.
  2. A [Control] table with a single record.

The data requirements for this setup are:

  1. The primary field in the main table must be an Autonumber field.
  2. Every record in the main table must be linked to the lone record in the [Control] table.
  3. The character length of the data in the field containing the base items to be tracked must be the same for every record. The exact length isn’t important, but it must be consistent. For example, if you’re going to use a five-character base code, the content of that code can be pretty much anything as long as it’s unique (obviously), and always five characters long in every record. The good news is that the field type can be any number of things, including (but not limited to) Single line text, Single select, Date, Duration, Phone Number, or even a link from another table

Here’s a cropped look at the [Fixed Length] table in the sample base:


Here’s a rundown of how the system works. All field names are from [Fixed Length]:

  • First, a unique character is added to the base item (see the {Unique Base} field), in order to prevent accidental crossover between base items when a SUBSTITUTE is run later in the process. My sample base uses a vertical bar, but anything else can be used instead as long as it’s not part of any of the base codes.
  • These unique items are looked up in the [Control] table, and that collection is then looked up back in the main table (see the {Lookup} field).
  • That lookup is then condensed into a string, and only the leftmost portion kept, with the length based on multiplying the record’s autonumber value by the {Unique Base} length (see the {Truncated} field). For example, if {Unique Base} is four characters long, this field will only keep the first four characters of the mashed-together lookup for the first record. For the second record, it will keep the first eight characters, and so on. This creates a record-by-record tally of everything that has been added.
  • The {Substitute} field then takes that tally and removes all instances of {Unique Base}, leaving everything else except that item.
  • The length of {Substitute} is subtracted from the length of {Truncated}, then divided by the length of {Unique Base}, and we have the unique number to assign to the listed item (see the {Variant} field)
  • The variant number is combined with the base and any desired separators in the {Final} field.

The four helper fields in the main table can be hidden once everything is set up. Because the numbers assigned in the Autonumber field are maintained even when reordering records, the variant numbers remain properly assigned even after records are moved around.

Variable Length Items
The same basic system also works with items of varying lengths. However, because of that variation, we can’t use the items themselves to track their count. Instead, we need to track another fixed-length item that’s tied to that primary item. For this, I created a new table, with the item names in the primary field, an autonumber field adjacent to that, and a formula field that padded the autonumber with leading zeroes to create a unique fixed-length ID for each item. Because these IDs are only going to be used in various formulas, I also added the vertical bar character here instead of doing so in the main table.

Back in the main table, the base items became links to records in that other table, with a lookup field pulling in each item’s unique ID, and then the rest of the system flows as outlined above, operating on that ID instead of the item itself. Once the item’s unique number is calculated, it’s combined with the original item.

Here’s a sample lookup table for this variable-length system (the [Presidents] table in the sample base):


And here’s the main portion of the [Variable Length] table:


61 Replies 61

This is perfect! Thanks!!

5 - Automation Enthusiast
5 - Automation Enthusiast

Hey @Justin_Barrett, thank you for your amazing work here !
I’m using this method to make a pallet tracking base, where there is pallet 1 of 2, 2 of 2 etc…
The issue I have is there is almost 12k pallet to track and each one is created via a script from the customer database and I won’t be on the field to do the trick and each pallet must be linked to the controler manually. (I’m fairly new to the airtable world) I tried some sort of wizzardry with zappier to automatically link every new record created, but it doesn’t works.

Is there a way to easilly link every new record created to the controler ?

Welcome to the community, @Thibaut_FERRI! :grinning_face_with_big_eyes: I’m a little less inclined to use this system these days thanks to Airtable’s scripting and automation features, but it’ll still work if you want to use it. In terms of linking every new record to the control record, this can be done using Airtable’s automation system.

The trigger will be the creation of a new record. The action step will be an “Update record” action, where you update that record with the link to the desired control record. You can get the control record’s ID by right-clicking on it and choosing “Copy record URL”. In the automation update step, paste that full URL into the link field you’re updating, then delete everything except the actual record ID (e.g. recXXXXXXXXXXXXXX). Save and activate the automation, and all new records will auto-link to the control record.

5 - Automation Enthusiast
5 - Automation Enthusiast

Thank you very much, great community ! :grinning_face_with_big_eyes:
I still have a little issue with this one :
I’d like to update the record in the control table when a record is created in the Etiquettes table. as you said I’ve used the control record’s ID in the record id field, but what to put in the fields “etiquette field” ?
On the etiquette table, the link to control is named “Link2Control”

Cheers guys, thank’s for the support 😃

The value in the “Record ID” field of the action should be the record ID from the record that triggered the automation. Delete that current value, then click the + symbol on the right end, and pick the triggering record’s record ID.

5 - Automation Enthusiast
5 - Automation Enthusiast

Thank you for your time, patience and explanations.
I figured I went the other way around (tried to update the control record instead of the created one).
I’m still struggling a bit with english as it’s not my mothertongue.

Once again, thank you for your work.
Cheers from the land of the baguette.

4 - Data Explorer
4 - Data Explorer

Hi @Justin_Barrett, this post is amazing.

I’m really new to Airtable and what you explain here is pretty advance to me. Although, I was able to understand what you explain I’m far to implement it to a specific use case I want.

I would really appreciate if you could give some directions with the following.

How can I modify your base (fixed length option) to have a sequence number that resets for every new year?

For example


It is for an invoice generator I would like to create using Airtable and Google docs templates.

I did dive into this post as well (Sequential Number, Resetting Daily ) but, as I said, my knowledge is far from being able to update these bases with success.

Thank you very much for your help!

4 - Data Explorer
4 - Data Explorer

Hey @Justin_Barrett. You can omit my previous message. I figured it out but replacing the Base field in the main table with a formula that extracts the year from a “Created date” field and everything works as desired. Thanks again for sharing this post.

It’s been a little more than two years since I wrote the original post that kicked off this thread. While it was fun playing with that solution (and even using variations of it for other things), and gratifying to hear how it has helped other Airtable users, I feel the need to make something clear:

I no longer recommend the method described in this thread

Why not? Simply because there are far better ways of doing this now that weren’t available at the time I developed the original solution. Today I’d recommend an automation that runs a script. Yes, there will be a slight delay while waiting for the automation to run, but it’s still far more flexible and far less error-prone (provided that the script is written well) than my original solution.

One of these days I might put together a sample script that could be used in an automation to do this, but I’m afraid that’s pretty far down my priority list. If anyone else wants to share their scripts here, feel free!

Thank you for the formula-based solution.
I am looking forward to your script-based solution in a near future. Hope you will share your wisdom with us!