I want to select out the records from A.shp if the where clause is satisfied. First, get the unique values (e.g., [2011,2012,2013,2014]) from a field (e.g., Year) and the field is from the A.shp, and then give the user to select the values as he wants. Suppose he is interested in the dataset from the year 2011 and 2012. Based on the values selected, delete other records (Year == 2013 or 2014 in this case) in the A.shp.
The code below has several problems.
1. Select All and Unselect All option in the tool window don't work.
2. The select out values don't change if the user unchecked several of them.
3. The UpdateCursor part removes all records rather than reflecting the user interests.
import arcpy
class Toolbox(object):
def __init__(self):
"""Define the toolbox (the name of the toolbox is the name of the
.pyt file)."""
self.label = "Toolbox"
self.alias = ""
# List of tool classes associated with this toolbox
self.tools = [Tool]
class Tool(object):
def __init__(self):
"""Define the tool (tool name is the name of the class)."""
self.label = "Tool"
self.description = ""
self.canRunInBackground = False
def getParameterInfo(self):
"""Define parameter definitions"""
#fc
fc = arcpy.Parameter(
displayName="FC:",
name="fc",
datatype="Feature Class",
parameterType="Required",
direction="Input")
# Plat category field parameter
fld = arcpy.Parameter(
displayName="Field from the Plat Features",
name="fld",
datatype="Field",
parameterType="Required",
direction="Input")
fld.parameterDependencies = [fc.name]
# MultiValue
values = arcpy.Parameter(
displayName="Values",
name="values",
datatype="String",
parameterType="Required",
direction="Input",
multiValue=1)
params = [fc, fld, values]
return params
def isLicensed(self):
"""Set whether tool is licensed to execute."""
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].value and parameters[1].value:
fc = str(parameters[0].value)
col = str(parameters[1].value)
vals = sorted(set(row[0] for row in arcpy.da.SearchCursor(fc,[col]) if row))
parameters[2].filter.list = vals
parameters[2].value = vals
return
def updateMessages(self, parameters):
"""Modify the messages created by internal validation for each tool
parameter. This method is called after internal validation."""
return
def execute(self, parameters, messages):
"""The source code of the tool."""
values = parameters[2].valueAsText
list = values.split(';')
for x in list:
arcpy.AddMessage(x)
fc = parameters[0].valueAsText
field = parameters[1].valueAsText
with arcpy.da.UpdateCursor(fc,[field]) as cursor:
for row in cursor:
if not row[0] in list:
cursor.deleteRow()
return
Any suggestion?
Best Answer
This is because you are resetting the values every time there is a value set for parameter 0 and 1 (done in the line
parameters[2].value = vals
). Comment this line out.I think this sounds a bit odd that you are actually removing features that user doesn't want to work with. Isn't it easier just to filter them out or create a new dataset that will contain the data user would like to work with? There is a risk your users will be deleting things and be unaware of this.
Anyways, this is the code that will remove all rows from the features class that were not selected by user:
Some notes:
never name your variables using built-in Python keywords such as
class
orpass
;never name your variables using built-in Python data types such as
list
ordict
;If you have a variable named
list
it might bite you later. The reason why all features are deleted in your tool is because you are resetting the values in the parametervalues
essentially unselecting all of them (will will forceUpdateCursor
to delete all rows).