I am trying to list fields from a feature class list in script tool validation. First user selects the data frame from the list then FC populates in next box and fields of the FC in next box. I have code up to populating the FC list and working fine. but after that i'm trying list fields from the FC and getting error.

here is the code

import arcpy
class ToolValidator(object):
  """Class for validating a tool's parameter values and controlling
  the behavior of the tool's dialog."""

  def __init__(self):
    """Setup arcpy and the list of tool parameters."""
    self.params = arcpy.GetParameterInfo()

  def initializeParameters(self):
    """Refine the properties of a tool's parameters.  This method is
    called when the tool is opened."""
    try:   # this works
        mxd = arcpy.mapping.MapDocument('CURRENT')
        dflist = [df.name for df in arcpy.mapping.ListDataFrames(mxd)]
        self.params[1].filter.type = "ValueList"
        self.params[1].filter.list = dflist
        del mxd
        arcpy.AddError("\nMust run this tool in ArcMap, not ArcCatalog")

    self.params[2].enabled = True


  def updateParameters(self):
    """Modify the values and properties of parameters before internal
    validation is performed.  This method is called whenever a parameter
    has been changed."""
    mxd = arcpy.mapping.MapDocument('CURRENT')

    if self.params[1].value:
        self.params[2].enabled = True

        df = arcpy.mapping.ListDataFrames(mxd, self.params[1].value)[0]
        # creates an empty dictionary
        if df:
            layerList = [lyr.name for lyr in arcpy.mapping.ListLayers(df) if not lyr.isGroupLayer]
            uniqueList = list(set(layerList))
            self.params[2].filter.list = uniqueList

# Up to this it working and problem is from below code

    if self.params[2].value:
        self.params[3].enabled = True

        df = str(self.params[1].value)   
        lyrList = arcpy.mapping.ListLayers(mxd, "", df)  
        for lyr in lyrList:  
            if lyr.supports("dataSource") and lyr.name == str(self.params[2].value):  
                for field in arcpy.ListFields(lyr.dataSource):  
                    uniqueList = list(set(field))
                    self.params[3].filter.list = uniqueList            


  def updateMessages(self):
    """Modify the messages created by internal validation for each tool
    parameter.  This method is called after internal validation."""

1 Answer 1


There could be two issues here:

This line: for field in arcpy.ListFields(lyr.dataSource): this is returning a Field Object which you are adding to list which you then feed into your param[3]. I'm guessing param[3] is of type string? So you need to feed into you uniqueList field.name.

Also this line looks odd to me: uniqueList = list(set(field)). field is a field object which you are adding to a set then converting to a list. This list gets overwritten on the next loop of for. I think your logic is flawed here.

Your Answer

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

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