You will need to turn on the "Show Codeblock" checkbox in the Field Calculator in order to set some global variables that can be shared across all iterations of the calculation (ie, for all records) and so that you can define a function to perform the calculations which can access these global variables.
This allows the field calculator to maintain some data about previous calculations which can be used in subsequent calculations.
I have just tested the following and it worked OK for me:
Pre-Logic Script Code:
owners = {}
nextID = 1
def getID(name):
global owners
global nextID
if name not in owners:
owners[name] = nextID
nextID += 1
return owners[name]
Expression (Map_ID = ):
getID( !LandOwner! )
How it Works:
owners
is a dictionary which stores an ID for each unique LandOwner.
nextID
is an integer that stores the lowest positive integer that has NOT already been used as an ID for a LandOwner (starting with 1
).
The function getID
makes these two global variables available within its scope, and gets passed in the name of the LandOwner
for this this current calculation is being run.
If the name
does not already have an ID assigned to it in the owners
dictionary, it assigns the next available ID to it, ie nextID
, AND increments nextID
to the next lowest unused integer.
Then it simply returns the ID number assigned to the passed in LandOwner
's name
.
The expression simply calls the getID()
function, passing it the value of the LandOwner
name for the current record being calculated. This is received by the function in it's name
parameter.
NB: There is no need to sort the records. This works whether the LandOwner
s are sorted or not. In fact, I'm not sure if the field calculator pays any attention to the sort order.