4

My goal is to grab a bunch of feature classes, select the first feature class, list the fields, and return that list to parameter 1 as a filtered list.

My ArcGIS toolbox is setup with 2 parameters.

The first parameter is a multivalue featureclass

The second parameter is a string with filter set to: "Value List" which is empty. I'm hoping to populate this. When I run the following code:

def updateParameters(self):

    if self.params[0].value: #when user inputs feature classe(s)

      fcs = self.params[0].value.value # getting list of fcs as string?

      spl = fcs.split(";") #splitting list of fcs

      fields = arcpy.ListFields(spl[0]) #getting list of fields from 1st featureclass

      self.params[1].filter.list = fields #return list of fields to param 1

When I input the fcs into param 0, I get this error:

ERROR updateParameters Execution Error: Runtime error : 'ValueTable' object has no attribute 'value'

2
  • 2
    I've seen your other posts and I get how you want the dialog to work, but whats the end goal? You originally wanted to select a GDB, which the FC from that get put into the 2nd param. Then in the 3rd param you want to list fields from all those FC, or fields from one selected FC? And then what? On execute what will happen with whatever FC(s) and whatever Field(s) is 'selected'?
    – KHibma
    Apr 3, 2014 at 14:03
  • I've directed the user that all data in that particular field must have the same schema, which is why it is okay to select whatever FC Apr 3, 2014 at 14:37

3 Answers 3

5

The code you require is:

  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."""
    if self.params[0].value:
        fcs = self.params[0].value.exportToString()
        spl = fcs.split(";")
        desc = arcpy.Describe(spl[0])
        fields = desc.fields # A list of of Field objects
        list = []
        for f in fields:
            list.append(f.name) # Transfer name to new list
        self.params[1].filter.list=list
    return

The help file suggests you DO NOT use ListFields but use Describe instead.

5

Even though you may have your answer, here was my take on it based on what I thought you were doing.

Param 1 = Input GDB

Param 2 = Input FC (multivalue)

Param 3 = Input Fields (multivalue)

enter image description here

Validator code

  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."""

    if self.params[0].value:
      #Populate the list of FC from the GDB
      arcpy.env.workspace = self.params[0].value
      fcList = arcpy.ListFeatureClasses() 
      self.params[1].value = fcList

      if self.params[1].value:
        fcs = self.params[1].value.exportToString()

        fieldList = []
        # Loop through every FC and get each field
        for fc in fcs.split(';'):
          desc = arcpy.Describe(fc)
          for field in desc.fields:
            if field.name not in fieldList:
              fieldList.append(field.name)
        self.params[2].value = fieldList   

    return
3

I was able to figure it out using ListFields, the problem was I forgot ListFields returned objects, not strings.

Working Code:

def updateParameters(self):
  """Modify the values and properties of parameters before internal
  validation is performed.  This method is called whenever a parmater
  has been changed."""

  if self.params[0].value:

    fcs = self.params[0].value.exportToString()

    split = fcs.split(";")

    fields = arcpy.ListFields(split[0])

    l = [f.name for f in fields]

    self.params[1].filter.list = l

  return

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.