0

How do I ensure the same selection is not made on param[2] and param[3] both of which are populated from the same field using tool validation?

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)

        # Get the unique values of the field 'col' in the feature class 'fc'
        unique_values = [str(val) for val in
                            sorted(
                                set(
                                    row.getValue(col)
                                        for row in arcpy.SearchCursor(fc, None, None, col)
                                )
                            )
                        ]

        # Assign the unique_values list to parameters 2 and 3
        self.params[2].filter.list = unique_values
        self.params[3].filter.list = unique_values

    # Set the default values of parameters 2 and 3 to the first item in the list
    if self.params[2].value not in self.params[2].filter.list:
      self.params[2].value = self.params[2].filter.list[0]
    if self.params[3].value not in self.params[3].filter.list:
      self.params[3].value = self.params[3].filter.list[0]

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

You can add an error message in validation in updateMessages. You can also do some sanity checking and try to use a non-conflicting value in updateParameters:

    ...
    # Set the default values of parameters 2 and 3 to the first item in the list
    if self.params[2].value not in self.params[2].filter.list:
      self.params[2].value = self.params[2].filter.list[0]
    if self.params[3].value not in self.params[3].filter.list:
      if self.params[3].filter.list[0] != self.params[2].value:
        self.params[3].value = self.params[3].filter.list[0]
      else:
        self.params[3].value = self.params[3].filter.list[-1]

  def updateMessages(self):
    """Modify the messages created by internal validation for each tool
    parameter.  This method is called after internal validation."""
    if self.params[2].value == self.params[3].value:
        self.params[3].setErrorMessage("Values cannot be the same")
   ...

You could also filter out the selected value from the third parameter in updateParameters:

    # Assign the unique_values list to parameters 2 and 3
    self.params[2].filter.list = unique_values
    self.params[3].filter.list = sorted(set(self.params[3].filter.list) - set([self.params[2].value]))
  • Brilliant! Thanks Jason! I went ahead with the updateMessages approach. Works like a charm. – wtgeographer Mar 25 '14 at 13:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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