# How to calculate unique IDs starting from highest current ID

I have been using a python script in field calculator in ArcGIS 10.2 to add unique IDs automatically, however there are two things I would like to improve this process:

1. Each ID also has letters at the beginning to identify what it is (ex. SL is streetlight) Currently I calculate the ID and then go back into field calculator and add 'SL'+(field) to append the text, is there a way I can put this right in my code?

2. When I add a new feature I need to check what the current highest ID is so it can go from there. This is made more difficult because when I sort by ascending/descending, the field is text and therefore 12 would come before 2. Is there a way to automatically calculate the highest existing ID?

Code in field calculator-

Codeblock:

rec=0
def autoIncrement():
global rec
pStart = #last unique ID
pInterval = 1
if (rec == 0):
rec = pStart
else:
rec = rec + pInterval
return rec

Basin:

autoincrement()
• Is there a field containing the letters (e.g. SL)? How are you going to know which row contains a certain set of letters?
– Aaron
Commented Sep 12, 2014 at 20:03
• This sounds like it should probably be written as two questions, with each specifying the GIS software and version being used, as well as some details about "the python script" that you have been using. Ideally this would just be a code snippet that works to demonstrate the aspect that you are trying to modify.
– PolyGeo
Commented Sep 12, 2014 at 20:09
• I'm thinking you could use the re library and sub function (see stackoverflow.com/questions/1249388/…), and store the number in a list, then use max(list) to get the maximum value (tutorialspoint.com/python/list_max.htm). However as @PolyGeo points out without knowing your platform, it's hard to really provide an answer. Commented Sep 12, 2014 at 20:10
• I have updated with your questions PolyGeo. Aaron, in some layers there are different attributes, but mostly there is only one type of asset in each layer, so all rows use the same letters. Commented Sep 16, 2014 at 18:22

If you are using a geodatabase, you can use Attribute Assistant to do this if the sequential number is assigned regardless of the prefix letters, i.e., you do not restart at 1 for each set of prefix letters, but simply append the prefix letters to a number that is sequential and unique for each record in the entire table. Attribute Assistant is available as part of the Local Government Information Model which you can download with the Address Data Management add-on (press the Open button to get the download). This link is for the 10.2 version, but you need to download the version that matches your ArcGIS version.

The Attribute Assistant DynamicValue table contains the rules that manage updates of your data during an edit session. For example, rules can be triggered by the Create event, which applies both to features you draw or the newest split off feature(s) created by a split event for lines or polygons. Rules could also be triggered separately by attribute modifications, geometry modifications, or manual requests, or any combination of the four trigger events.

You could use the Generate_ID method rule in response to a Create event to read the next sequential number and assign it to the field from the GenerateID table. The GenerateID table must be present in your map and unversioned if it an SDE table.

Then Attribute Assistant could follow that during a Create event by using the Expression Method rule to apply a vb script expression that appends a prefix to the UniqueID field based on another field that contains the 2 letters, i.e., [PREFIX] & [UNIQUEID]. If the 2 letters are interpreted from other values (i.e. "Street Light" in one field equals an "SL" prefix), then the expression would only work if the translation can be contained in a 254 character vb script conditional expression. For example:

IIF([CATEGORY] = "Street Light", "SL", IIF([CATEGORY] = "Utility Pole", "UP", "")) & [UNIQUEID]

If you have too many category translations it is best to add a field with the 2 letter version of the category and use the COPY_LINKED_RECORD method to populate it from a Lookup table that does the translation prior to running the EXPRESSION.

Once the DynamicValue table rules are set up and you have added the DynamicValue table, GenerateID table and any lookup table to your map, all you have to do is edit within an edit session and the ID will be generated if you use a template that assigns the category value. If you always manually assign the category value you can trigger an Expression during a Modify Attributes event to test if the prefix has already been applied to the unique number and assign it if it hasn't been. An expression like the following should work if all your prefixes are 2 letters long:

IIF([PREFIX] = LEFT([UNIQUEID], 2), [UNIQUEID], IIF(ISNUMBER(LEFT([UNIQUEID], 2)), [PREFIX] & [UNIQUEID], [PREFIX] & LEFT([UNIQUEID], LEN([UNIQUEID]) - 2))

Anyway, Attribute Assistant is a powerful way to automate attribute updates that should always remain in synch with the edits you make to your data and that occur in a logical order in response to editor events.

• Attribute Assistant can solve another common problem of being able to detect geometry changes since the last run of a geoprocessing operation. It can automatically update the common XY coordinate values for a feature with the X_COORDINATE or Y_COORDINATE rules and it can date stamp the geometry change in a date field with an Expression of now() or date() that is triggered whenever a Create Event or a Modify Geometry event occurs. Commented Sep 13, 2014 at 19:53
• Thanks a lot, this information is great! I had never heard of attribute assistant. Commented Sep 16, 2014 at 19:08
• So we are moving to the Canadian Municipal Data Model (LGIM for Canada) and I am trying to use the Attribute Assistant. I have the tables in my new geodatabase, but when I try to edit them I get an error about the Global ID, which ArcGIS adds on its own! Not sure how to fix this... The error is "GetConfigDataTable: Input string was not in a correct format. Couldn't store [input] in GlobalID Column. Expeted type is Int32." Help! Commented Oct 24, 2014 at 17:09
• See question above here: gis.stackexchange.com/questions/119672/… Commented Oct 24, 2014 at 18:21