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
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
-
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– Jan Caha2016年10月20日 14:31:16 +00:00Commented Oct 20, 2016 at 14:31
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"
-
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– Jan Caha2016年09月21日 12:04:46 +00:00Commented Sep 21, 2016 at 12:04