ArcPy – Create Filter Parameter in Python Script from Unique Field Values

arcpyfilterparameterspython-script-tool

I currently have a python script tool that reads in a feature class and (among other processes) subsets the feature class based on a value in one field, 'REGION'. Instead of having all subsets created, I'm now seeking to be able to run the tool for certain regions and am trying to figure out how to have a parameter in the tool give a drop down list of the unique values within the REGION field. I've gotten up to the point where I can select the region (which I don't even need as a parameter since it will never change and always be based off of REGION), but I'm stumped on how to have a parameter of a drop down of a list of unique values in REGION.

Here is a the code I'm trying to use. I've been looking at http://desktop.arcgis.com/en/arcmap/10.5/analyze/creating-tools/customizing-script-tool-behavior.htm but don't quite understand how to have the set of REGION values appear in the python tool GUI.

import arcpy
from arcpy.sa import *

featureClass = arcpy.GetParameterAsText(0) 

class ToolValidator(object): 
        def _int_(self):
            self.params = arcpy.GetParameterInfo()

        def initializeParameters(self):
            return

        def updateParameters(self):
            rows = arcpy.da.SearchCursor(featureClass, REGION)
            self.params[0].filter.list = sorted(list(set(r.getValue('REGION') for r in rows)))
            del rows
            return

        def updateMessages(self):
            return

def new_feature_class():    
# 1. For each feature class selected create a new feature class for every unique region within it.
    for j in featureClasses.split(';'):  
        def unique_values(table, field):
            with arcpy.da.SearchCursor(table, field) as cursor:
                return sorted({row[0] for row in cursor})

        uniqueRegionList = unique_values(j, 'REGION')
        print (uniqueRegionList)

        for i in uniqueRegionList:
            in_features = j
            out_feature_class = str(i) + str(timePeriod) + in_features[-5:] 
            where_clause = " \"REGION\" = '%s'" % (i)

            arcpy.Select_analysis(in_features, out_feature_class, where_clause)
            print(out_feature_class)
new_feature_class()

Edited to add Validation 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."""
    return

  def updateParameters(self):
    rows = arcpy.da.SearchCursor(featureClass, REGION)
    self.params[1].filter.list = sorted(list(set(r.getValue('REGION') for r in rows)))
    del rows
    return

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

enter image description here
enter image description here

Best Answer

At the moment your ToolValidator code is trying to apply a filter list to your first parameter (featureClasses).

You need to add a third parameter of type string (e.g. Region Value), then in your ToolValidator change this

self.params[0].filter.list = sorted(list(set(r.getValue('REGION') for r in rows)))

to

self.params[2].filter.list = sorted(list(set(r.getValue('REGION') for r in rows)))

You may also want to pull the bit of code that creates the unique list of REGION values out of the def updateParameters(self): block otherwise it will fire every time any of the parameters is altered which could cause performance issues.

Related Question