Script tool with drop down list of multi values using ToolValidator

7282
13
Jump to solution
10-14-2021 06:43 PM
Aнастасия88
Occasional Contributor

Hello,

I need an idea on how to enable a drop down list in a script tool so that I can select multiple attribute values from a selected field.

Based on a code from ArcGIS blog, "Generating a choice list from a field", I managed to create a script tool with ToolValidator function to make a a drop down list.

A0328_0-1634261251130.png

But I cannot select multiple values with this code only. I can check the box of "Multiple values" in Parameters section. This makes multiple values windows but even if I select multiple values, the values won't be included as inputs. So, I feel the script in validation section needs to be modified but I am struggling with that.

Thanks in advance.

 

0 Kudos
13 Replies
Aнастасия88
Occasional Contributor

Thanks again for your help.

It looks like same as yours except my one is "Field value" and yours is "Field".

My validation code is like this:

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()
    self.fcfield = (None, None)

  def initializeParameters(self):
    """Refine the properties of a tool's parameters.  This method is
    called when the tool is opened."""
    return

  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 and self.params[1].value:
      fc, col = str(self.params[0].value), str(self.params[1].value)
      if self.fcfield != (fc, col):
        self.fcfield = (fc, col)
        self.params[2].filter.list = [str(val) for val in sorted(set(row.getValue(col) for row in arcpy.SearchCursor(fc, fields=col)))]
        if self.params[2].value not in self.params[2].filter.list:
            self.params[2].value = self.params[2].filter.list[0]

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

I am not sure the purpose of the last 2 lines (25, 26.  If you are providing the list of values to the tool from the field would that be in the initialize script?

Also if you are using a search cursor getting one value at a time,  there is no need to take a set of the returned value and sort it each time.  Get all the values, take its set, convert it to a list, then sort it

d = [2, 5, 5, 2, 6, 1, 3, 5, 4]  # emulate a searchcursor
# use a set comprehension
out = sorted(list({str(val) for val in d}))
out
['1', '2', '3', '4', '5', '6']

Beyond that, I can't pinpoint anything else


... sort of retired...
0 Kudos
Aнастасия88
Occasional Contributor

Thanks Dan, it works!

It seems like there is no need to put the last two lines as you mentioned.

Also, thanks for another advice for the better quality of the script.

0 Kudos
DanPatterson
MVP Esteemed Contributor

Glad it worked out


... sort of retired...
0 Kudos