I have some simple ArcPy script tool validator code that is giving me grief. I am using desktop at 10.3.1. I'm open to whatever help can be offered to get this to work as intended.
I have two parameters for my script tool. The first is the type of product to be created, the second is the scale of the product. Digital Map / No scale required are the default values defined in the Tool Validator code.
If it is a paper product, the user selects the appropriate scale from the drop-down list. The problem I can't solve is that if the user changes the value in parameter 0 to paper map, the list of scales becomes available but the value is still the default ("No scale required") so an error is thrown because that option is not in the scale list. The error clears when I select the scale from the list, but I want only those choices available and obviously don't want the error to appear at all.
Likewise if I then change parameter 0 back to Digital Map the "No scale required" value appears but the error message is thrown again because that value is not in the scale list, which is somehow still appearing. There is no way to clear the error at this point.
I'd really appreciate help with how to get these different combinations to appear and change as intended without any errors. If they pick Paper, only the scales appear. If they switch back to Digital, only the "No scale required" value appears. And so on. I can't guarantee the user's behaviour so I'd like for it to be bulletproof.
import arcpy
class ToolValidator(object):
def __init__(self):
self.params = arcpy.GetParameterInfo()
def initializeParameters(self):
# Define the list of product types the user can choose from
self.params[0].filter.list = ["Digital Map", "Paper Map"]
self.params[0].value = "Digital Map"
return
def updateParameters(self):
if self.params[0].value == "Digital Map":
self.params[1].value = "No scale required"
if self.params[0].value == "Paper Map":
self.params[1].filter.list = ["1:10,000", "1:25,000"]
return
def updateMessages(self):
return
Solved! Go to Solution.
Try the following for the tool validator:
import arcpy
class ToolValidator(object):
def __init__(self):
self.params = arcpy.GetParameterInfo()
def initializeParameters(self):
return
def updateParameters(self):
if self.params[0].value == None:
self.params[0].value = "Digital Map"
if self.params[0].valueAsText == "Digital Map":
self.params[1].filter.list = ["No scale required"]
else:
self.params[1].filter.list = ["1:10,000", "1:25,000"]
if self.params[1].value not in self.params[1].filter.list:
self.params[1].value = self.params[1].filter.list[0]
return
def updateMessages(self):
return
For testing, I used Desktop 10.5. I set the script tool parameters as type string, and populated the map type filter with the digital or paper map options. I did not set the filter list for the map scale.
I find it a little easier to use a Python toolbox. You don't have to go to the properties dialog box to edit a tool validator; everything fits into one script. My test version:
import arcpy
class Toolbox(object):
def __init__(self):
self.label = "Toolbox"
self.alias = ""
self.tools = [Tool]
class Tool(object):
def __init__(self):
self.label = "Tool"
self.description = ""
self.canRunInBackground = False
def getParameterInfo(self):
MapType = arcpy.Parameter(
displayName="Map Type",
name="MapType",
datatype="String",
parameterType="Required",
direction="Input")
MapType.filter.list = ["Digital Map", "Paper Map"]
MapType.value = "Digital Map"
MapScale = arcpy.Parameter(
displayName="Map Scale",
name="MapScale",
datatype="String",
parameterType="Required",
direction="Input")
MapScale.filter.list = ["No scale required"]
MapScale.value = "No scale required"
params = [MapType, MapScale]
return params
def isLicensed(self):
return True
def updateParameters(self, parameters):
"""Modify the values and properties of parameters before internal
validation is performed. This method is called whenever a parameter
has been changed."""
if parameters[0].valueAsText == "Digital Map":
parameters[1].filter.list = ["No scale required"]
else:
parameters[1].filter.list = ["1:10,000", "1:25,000"]
if parameters[1].value not in parameters[1].filter.list:
parameters[1].value = parameters[1].filter.list[0]
return
def updateMessages(self, parameters):
return
def execute(self, parameters, messages):
"""The source code of the tool."""
return
Hope this helps.
Try the following for the tool validator:
import arcpy
class ToolValidator(object):
def __init__(self):
self.params = arcpy.GetParameterInfo()
def initializeParameters(self):
return
def updateParameters(self):
if self.params[0].value == None:
self.params[0].value = "Digital Map"
if self.params[0].valueAsText == "Digital Map":
self.params[1].filter.list = ["No scale required"]
else:
self.params[1].filter.list = ["1:10,000", "1:25,000"]
if self.params[1].value not in self.params[1].filter.list:
self.params[1].value = self.params[1].filter.list[0]
return
def updateMessages(self):
return
For testing, I used Desktop 10.5. I set the script tool parameters as type string, and populated the map type filter with the digital or paper map options. I did not set the filter list for the map scale.
I find it a little easier to use a Python toolbox. You don't have to go to the properties dialog box to edit a tool validator; everything fits into one script. My test version:
import arcpy
class Toolbox(object):
def __init__(self):
self.label = "Toolbox"
self.alias = ""
self.tools = [Tool]
class Tool(object):
def __init__(self):
self.label = "Tool"
self.description = ""
self.canRunInBackground = False
def getParameterInfo(self):
MapType = arcpy.Parameter(
displayName="Map Type",
name="MapType",
datatype="String",
parameterType="Required",
direction="Input")
MapType.filter.list = ["Digital Map", "Paper Map"]
MapType.value = "Digital Map"
MapScale = arcpy.Parameter(
displayName="Map Scale",
name="MapScale",
datatype="String",
parameterType="Required",
direction="Input")
MapScale.filter.list = ["No scale required"]
MapScale.value = "No scale required"
params = [MapType, MapScale]
return params
def isLicensed(self):
return True
def updateParameters(self, parameters):
"""Modify the values and properties of parameters before internal
validation is performed. This method is called whenever a parameter
has been changed."""
if parameters[0].valueAsText == "Digital Map":
parameters[1].filter.list = ["No scale required"]
else:
parameters[1].filter.list = ["1:10,000", "1:25,000"]
if parameters[1].value not in parameters[1].filter.list:
parameters[1].value = parameters[1].filter.list[0]
return
def updateMessages(self, parameters):
return
def execute(self, parameters, messages):
"""The source code of the tool."""
return
Hope this helps.
Based on Randy Burton 's reply, I used the following code in the validator which does exactly what I want. Thanks Randy!
import arcpy
class ToolValidator(object):
def __init__(self):
self.params = arcpy.GetParameterInfo()
def initializeParameters(self):
self.params[0].filter.list = ["Digital Map", "Paper Map"]
self.params[0].value = "Digital Map"
return
def updateParameters(self):
if self.params[0].value == None:
self.params[0].value = "Digital Map"
if self.params[0].valueAsText == "Digital Map":
self.params[1].filter.list = ["Not applicable"]
self.params[1].value = "Not applicable"
self.params[1].enabled = False
else:
self.params[1].filter.list = ["1:10,000", "1:25,000"]
if self.params[1].value not in self.params[1].filter.list:
self.params[1].value = self.params[1].filter.list[0]
self.params[1].enabled = True
return
def updateMessages(self):
return