1

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?

PolyGeo
65.5k29 gold badges115 silver badges349 bronze badges
asked Mar 20, 2017 at 18:45

1 Answer 1

3
  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.

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.

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
  1. The UpdateCursor part removes all records rather than reflecting the user interests.

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:

def execute(self, parameters, messages):
 """The source code of the tool."""
 values = parameters[2].valueAsText
 values_to_remove = values.split(';')
 for x in values_to_remove:
 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 values_to_remove:
 cursor.deleteRow()
 return

Some notes:

  • never name your variables using built-in Python keywords such as class or pass;

  • never name your variables using built-in Python data types such as list or dict;

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 parameter values essentially unselecting all of them (will will force UpdateCursor to delete all rows).

answered Mar 26, 2017 at 16:54

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.