Multi-Step Field Calculate

909
5
08-12-2020 03:09 PM
JoanneStarr
New Contributor III

I am trying to use python to calculate a field first to put sequential numbers, then pad with leading zeros, then finally to concatenate with a code for each data layer. I set the parameters as the layer, the field, and the 4 digit code.  The script that I am using is below. I keep getting an error 539 in the add leading zeros function which says the IDPK_Field is not defined. I am not the best at python, any help would be appreciated! 

import arcpy

arcpy.env.overwriteOutput = False

# Script parameters
Input_Layer = arcpy.GetParameterAsText(0)
IDPK_Field = arcpy.GetParameterAsText(1)
CALField = arcpy.GetParameterAsText(2)

# Local variables:
Updated_Input_Table = Input_Layer
Updated_Input_Table__2_ = Updated_Input_Table
Updated_Input_Table__3_ = Updated_Input_Table__2_


#Add Sequental Number
arcpy.CalculateField_management(in_table=Input_Layer, field=IDPK_Field, expression="autoIncrement()", expression_type="PYTHON3", code_block="""rec=0
def autoIncrement():
    global rec
    pStart = 1
    pInterval = 1
    if (rec == 0):
        rec = pStart
    else:
        rec = rec + pInterval
    return rec""")


#Add Leading Zeros
arcpy.CalculateField_management(in_table=Updated_Input_Table, field= IDPK_Field, expression="str(IDPK_Field).zfill(6)", expression_type="PYTHON3", code_block="")


#Add layer Code
arcpy.CalculateField_management(in_table=Updated_Input_Table__2_, field=IDPK_Field, expression="CALField + IDPK_Field", expression_type="PYTHON3", code_block="")‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
5 Replies
JoeBorgione
MVP Emeritus

What type of field is IDPK_Field?  In your Autoincrment() function you treat it as numeric.  In line 30 you cast it as a string with str() but that's only a temporary cast.  Perhaps you could copy and paste the actual error it throws, but my guess is it's due to line 34 where you are trying to add two variable values together and it's getting lost somewhere.

That should just about do it....
RandyBurton
MVP Alum

A couple of suggestions:

First, delete lines 10-13, and just use the variable "Input_Layer" as the in_table for all the FieldCalculator calls.

Second, the code block should be able to all your calculations in one pass.  I'm not exactly sure of your table layout, but perhaps something like:

# CALfield = 'xyz' # does this come from another field?

rec = 0
def autoIncrement(CALfield):
	global rec
	pStart = 1
	pInterval = 1
	if (rec == 0):
		rec = pStart
	else:
		rec = rec + pInterval
	return CALfield + str(rec).zfill(6)

# xyz000001‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

If the calculation is more complicated, then you may wish to use an UpdateCursor.

Regarding the specific error, "IDPK_Field is not defined", you may need to check if the user correctly selected an existing field in the "Input_Layer".  The tool validator code section can be used to assist in this operation.  Since you want to update the IDPK_Field, this is a text field of sufficient length, correct?

JoanneStarr
New Contributor III

Hi Randy,

That was helpful! It really is just a simple field calculate, I'm just not very good at Python.

I figured out the error being not defined, but now I am getting "TypeError: autoIncrement() missing 1 required positional argument: 'CALfield'"

I want to use three parameters that are set within the tool, the CALfield is just a 4 letter code that identifies a certain layer, it is not in the original table at all, it is only gained through the set parameter. Basically, I need a code that takes a field, creates a sequential number with 6 digits, then adds the 4 letter code as set in the parameter. I feel like it should be real easy, but I keep getting roadblocked!

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

The new error message is saying that autoIncrement is a function with 1 required parameter but no argument is being passed to it.  You would need to modify line #17 to include a reference to the field

expression="autoIncrement(!{}!)".format(CALField)

0 Kudos
JoanneStarr
New Contributor III

I got it to run withour errors, but it doesn't actually do what I want it to do.

Input layer = Airfield accident zone

IDPK_Field= AirfieldAccidentIDPK (blank field, text 50 characters)

CALField = AAPZ (user defined, not in table anywhere, set as a parameter)

The final result is giving me AAPZAirfieldAccidentIDPK rather than AAPZ000001

If I run just the first part of the script, it creates the sequential numbers correctly. But once the second part is ran, it gets rid the newly created sequential numbers and gives me the name of the IDPK field

import arcpy

# To allow overwriting the outputs change the overwrite option to true.
arcpy.env.overwriteOutput = False

# Script parameters
Input_Layer = arcpy.GetParameterAsText(0)
IDPK_Field = arcpy.GetParameter(1)
CALField = arcpy.GetParameterAsText(2)


# Local variables:
Updated_Input_Table = Input_Layer


# Process: Add Sequental Number
arcpy.CalculateField_management(in_table=Input_Layer, field=IDPK_Field, expression="autoIncrement()", expression_type="PYTHON3", code_block="""rec = 0
def autoIncrement():
     global rec
     pStart = 1
     pInterval = 1
     if (rec == 0):
          rec = pStart
     else:
          rec = rec + pInterval
     return str(rec).zfill(6)""")


arcpy.CalculateField_management(in_table=Input_Layer, field=IDPK_Field, expression='"' + CALField + str(IDPK_Field) + '"', expression_type="PYTHON3", code_block="")
0 Kudos