1

I have a python toolbox with a tool that takes two arguments. First parameter is GPFeatureLayer and the second is Field of Integer type. I would like to set the second parameter to a specific field if it exist within the layer but I am unable to figure out a way to do it correctly.

My code looks like this:

def getParameterInfo(self):
    param0 = arcpy.Parameter(
        displayName="Input lines",
        name="in_lines",
        datatype="GPFeatureLayer",
        parameterType="Required",
        direction="Input")
    param0.filter.list = ["Polyline"]

    param1 = arcpy.Parameter(
        displayName="ID source",
        name="in_id_source",
        datatype="Field",
        parameterType="Required",
        direction="Input")
    param1.filter.list = ["Integer"]
    param1.parameterDependencies = [param0.name]
params = [param0, param1]
return params

Later in the code I would like to set parameter 1 to field "OID_SOURCE" as a default value if it exists. However, the following code is not working:

def updateParameters(self, parameters):
    if parameters[0].value:
        fields = arcpy.Describe(parameters[0].valueAsText).fields
        index = None
        for i in range(0, len(fields)):
            if fields[i].name == "OID_SOURCE":
                index = i
        parameters[1].value = fields[index]
    return

This makes the parameter 1 always empty. I tried using this:

parameters[1].value = fields[index].name

But that yelds error "Invalid field type". I do understand why the version with "fields[index].name" is not working as I am trying to asssing String to a Field.

But I am wondering is there any way preset the the parameter with specific field if it exists?

2 Answers 2

1

There is a workaround that maybe you won't like it, but I will post it anyway:

Instead of using "Field" as the second parameter, I use "GPString"

def getParameterInfo(self):

    param0 = arcpy.Parameter(
    displayName="Input lines",
    name="in_lines",
    datatype="GPFeatureLayer",
    parameterType="Required",
    direction="Input")

    param1 = arcpy.Parameter(
    displayName="ID source",
    name="in_id_source",
    datatype="GPString",
    parameterType="Required",
    direction="Input")

    return [param0, param1]

def updateParameters(self, parameters):

    if parameters[0].altered:
        fields = arcpy.ListFields(parameters[0].value)
        fil = []
        for field in fields:
            if field.type == "Integer":
                fil.append(field.name)
                if field.name == "OID_SOURCE":
                     parameters[1].value = field.name

        parameters[1].filter.type = "ValueList"
        parameters[1].filter.list = fil 

    return

Then in the execute you can get the Field:

def execute(self, parameters, messages):

   inFC = parameters[0].value
   f = parameters[1].value

   fObj = None #The Field you want

   fields = arcpy.ListFields(inFC)
   for field in fields:
      if field.name == f:
         fObj = field   

   return
1
  • Thank you. This solution actually works rather well. The part with finding the field in layer in "execute" functions is not necessary as for most usages the string representation of field name is acceptable.
    – Jan Caha
    Oct 20, 2016 at 14:31
1

If you know the field name is "OID_SOURCE" and just want to check that it exists before setting it as parameters[1].value then check a list of the field names and if found set your parameter:

fields = {x.name for x in arcpy.Describe(parameters[0].valueAsText).fields}
if "OID_SOURCE" in fields:
    parameters[1].value = "OID_SOURCE"
1
  • I tried that before and it does not work. The toolbox outputs an error "Invalid field type" because this way I am trying to use String ("OID_SOURCE") but the parameter is actually Field datatype.
    – Jan Caha
    Sep 21, 2016 at 12:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.