Select by attributes based on multivalue parameter

855
6
Jump to solution
11-27-2017 02:56 PM
LyleShakespear
New Contributor III

New to Python.  I'm attempting to create a python script that will allow a user to select a parcel (a parameter input by user), select all other parcels within a specified distance of the selected parcel, and then export the selection.  I've gotten the code to work when the user inputs one parcel id.  However, there are times when the user will need to select multiple parcels.  I've changed the parameter to multivalue so that multiple inputs are accepted but the code needs some help to be able to handle the multiple inputs.  Here's what I have:

# Import system modules
import arcpy
import arcpy.mapping


mxd = arcpy.mapping.MapDocument ('CURRENT')
df = arcpy.mapping.ListDataFrames(mxd,"Layers")[0]
lyr = arcpy.mapping.ListLayers(mxd, "Parcels")[0]

taxid = arcpy.GetParameterAsText(0)

# Overwrite pre-existing files
arcpy.env.overwriteOutput = True

# Selects the parcel of interest
arcpy.SelectLayerByAttribute_management("Parcels", "NEW_SELECTION", '"TAX_IDTXT" = ' + "'" + taxid + "'")

Obviously this is only a small portion of the code but this is the part that I'm struggling with.  How do I get the code to accept multiple inputs from the user?  From other forum posts people have suggested a whereClause.  I've experimented with some code below without success.  I think an issue is with the TAX_IDTXT field.  I'm not sure how to tell it to search the TAX_IDTXT field in the Parcels layer.  Any ideas?

#Build the where clause
whereClause = "{0} in ('TAX_IDTXT')".format("TAX_IDTXT", "','".join(taxid.split(';')))

#Select(input, output, whereClause)

if int(arcpy.GetCount_management(lyr).getOutput(0)) > 0:

arcpy.SelectLayerByAttribute_management(lyr, "NEW_SELECTION", whereClause)

0 Kudos
1 Solution

Accepted Solutions
XanderBakker
Esri Esteemed Contributor

A couple of comments here:

  • The where clause does not seem to be constructed correctly look below what you could do:
taxid = 'a123'
taxids = taxid.split(';')
where = '"TAX_IDTXT" IN ' + "('{0}')".format("','".join(taxids))
print where

taxid = 'a123;b456;c789'
taxids = taxid.split(';')
where = '"TAX_IDTXT" IN ' + "('{0}')".format("','".join(taxids))
print where

taxid = ''
taxids = taxid.split(';')
where = '"TAX_IDTXT" IN ' + "('{0}')".format("','".join(taxids))
print where

This will yield:

"TAX_IDTXT" IN ('a123')
"TAX_IDTXT" IN ('a123','b456','c789')
"TAX_IDTXT" IN ('')

The other point is that you should not check with a GetCount, since if there is no selection it will return the count of all the features. I would also expect to see a Select Layer By Location—Help | ArcGIS Desktop with the appropriate search distance to select the features within a certain distance.

View solution in original post

6 Replies
DanPatterson_Retired
MVP Emeritus

run the tool manually as you want it, then go to Geoprocessing Results, and export what you see as a python script/snippet.  You will get the required syntax to complete the task script-wise.  Many of the tools return a semi-colon delimited string which may need to be converted to a list by splitting on the semi-colon.

in_stuff = "a;b;c;d"

out_stuff = in_stuff.split(";")

for stuff in out_stuff:
    print("do stuff with {}".format(stuff))
    
do stuff with a
do stuff with b
do stuff with c
do stuff with d
LyleShakespear
New Contributor III

When you say run the tool manually are you talking about the python window in ArcMap.  When I try that it tells me there is  a parsing error.

0 Kudos
DanPatterson_Retired
MVP Emeritus

Just run Select by attributes in ArcMap first to get the syntax which is appropriate when that tools's process is converted to a python script.

When you run it with one input, it will probably look like what you have

arcpy.SelectLayerByAttribute_management("Parcels", "NEW_SELECTION", '"TAX_IDTXT" = ' + "'" + taxid + "'")

But you don't know what it will look like when you have multiple things to select.  So, by doing it manually and getting the script syntax for the last parameter of the tool, you will have saved yourself a lot of time trying to figure it out on your own.  Doesn't hurt to try.

0 Kudos
XanderBakker
Esri Esteemed Contributor

A couple of comments here:

  • The where clause does not seem to be constructed correctly look below what you could do:
taxid = 'a123'
taxids = taxid.split(';')
where = '"TAX_IDTXT" IN ' + "('{0}')".format("','".join(taxids))
print where

taxid = 'a123;b456;c789'
taxids = taxid.split(';')
where = '"TAX_IDTXT" IN ' + "('{0}')".format("','".join(taxids))
print where

taxid = ''
taxids = taxid.split(';')
where = '"TAX_IDTXT" IN ' + "('{0}')".format("','".join(taxids))
print where

This will yield:

"TAX_IDTXT" IN ('a123')
"TAX_IDTXT" IN ('a123','b456','c789')
"TAX_IDTXT" IN ('')

The other point is that you should not check with a GetCount, since if there is no selection it will return the count of all the features. I would also expect to see a Select Layer By Location—Help | ArcGIS Desktop with the appropriate search distance to select the features within a certain distance.

LyleShakespear
New Contributor III

Thank you Xander!  It was the where clause as you mentioned.  I think I was trying to do it backwards, as well as an issue with the last part of the where clause.

This will be very helpful as I continue to learn python.  Thanks again.

XanderBakker
Esri Esteemed Contributor

Glad it worked for you!

0 Kudos