Use Arcpy to Unselect the currently selected Features in all layers

10560
14
10-15-2013 04:42 AM
OLANIYANOLAKUNLE
Occasional Contributor II
I have a script that unselects all the selected features in my Map view but it loops through each layer in the dataframe and this takes a lot of time. I want to write a script that would be as fast as the Unselect the currently selected Features in all layers within ArcMap itself? This is my code below;

mxd = arcpy.mapping.MapDocument("Current")
df = arcpy.mapping.ListDataFrames(mxd)[0]
for lyr in arcpy.mapping.ListLayers(mxd):
...     arcpy.SelectLayerByAttribute_management(lyr, "CLEAR_SELECTION")
...     
Runtime error  Traceback (most recent call last):   File "<string>", line 2, in <module>   File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\management.py", line 6461, in SelectLayerByAttribute     raise e ExecuteError: Failed to execute. Parameters are not valid. ERROR 000840: The value is not a Table View. ERROR 000840: The value is not a Raster Layer. ERROR 000840: The value is not a Mosaic Layer. Failed to execute (SelectLayerByAttribute).


Any Suggestions? Thanks
Tags (2)
14 Replies
T__WayneWhitley
Frequent Contributor
I don't believe the capability exists within arcpy to 'wholesale' clear all selected features in the active dataframe...the way you are currently using the method to clear each layer is pretty much it.  Unless you want to delve into ArcObjects...or, say, use the comtypes 'wrapper' to basically invoke the ArcObjects methods not readily available via arcpy.

Perhaps not the prime place to post about ArcObjects - I'll be brief though...
You raised an interesting topic (for which I see there have been no posted responses yet)...however, it is kind of intriguing that although continuing support for VBA is no longer provided (no new features), this code still works at 10.0 - I just tested the following on my 10.0 (and probably it still works at 10.1, and 10.2?...I have not yet migrated my VBA authorizations above 10.0 and will likely adapt something like this as VB.NET in the future).  Here is the working VBA code to clear all selected features for all layers in the active data frame --- just for 'honorable mention', and it's so clean and simple:
Sub ClearSelection()

Dim pApp As IApplication
Set pApp = Application

Dim pMxDoc As IMxDocument
Set pMxDoc = ThisDocument

Dim pMap As IMap
Set pMap = pMxDoc.ActiveView

Dim pAV As IActiveView
Set pAV = pMap

pMap.ClearSelection
pAV.Refresh

Debug.Print "done!"
End Sub



Enjoy,
Wayne
0 Kudos
XanderBakker
Esri Esteemed Contributor
I have a script that unselects all the selected features in my Map view but it loops through each layer in the dataframe and this takes a lot of time. I want to write a script that would be as fast as the Unselect the currently selected Features in all layers within ArcMap itself? This is my code below;

mxd = arcpy.mapping.MapDocument("Current")
df = arcpy.mapping.ListDataFrames(mxd)[0]
for lyr in arcpy.mapping.ListLayers(mxd):
...     arcpy.SelectLayerByAttribute_management(lyr, "CLEAR_SELECTION")
...     
Runtime error  Traceback (most recent call last):   File "<string>", line 2, in <module>   File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\management.py", line 6461, in SelectLayerByAttribute     raise e ExecuteError: Failed to execute. Parameters are not valid. ERROR 000840: The value is not a Table View. ERROR 000840: The value is not a Raster Layer. ERROR 000840: The value is not a Mosaic Layer. Failed to execute (SelectLayerByAttribute).


Any Suggestions? Thanks


Strange, if I run the (slightly changed) code it does run for me (in 10.2)

import arcpy
mxd = arcpy.mapping.MapDocument("CURRENT")
dfs = arcpy.mapping.ListDataFrames(mxd)
for df in dfs:
    for lyr in arcpy.mapping.ListLayers(mxd,"*",df):
        if lyr.isFeatureLayer:
            arcpy.SelectLayerByAttribute_management(lyr, "CLEAR_SELECTION")

    for tbl in arcpy.mapping.ListTableViews(mxd,"*",df):
        arcpy.SelectLayerByAttribute_management(tbl,"CLEAR_SELECTION")


What type of layers do you have in your TOC?

Kind regards,

Xander
0 Kudos
OLANIYANOLAKUNLE
Occasional Contributor II
Strange, if I run the (slightly changed) code it does run for me (in 10.2)

import arcpy
mxd = arcpy.mapping.MapDocument("CURRENT")
dfs = arcpy.mapping.ListDataFrames(mxd)
for df in dfs:
    for lyr in arcpy.mapping.ListLayers(mxd,"*",df):
        if lyr.isFeatureLayer:
            arcpy.SelectLayerByAttribute_management(lyr, "CLEAR_SELECTION")

    for tbl in arcpy.mapping.ListTableViews(mxd,"*",df):
        arcpy.SelectLayerByAttribute_management(tbl,"CLEAR_SELECTION")


What type of layers do you have in your TOC?

Kind regards,

Xander


Yeah, your code works but it takes the same time with what I have to go through each of the layers one after the other? I want something as fast as the  " to Unselect the currently selected Features in all layers" in ArcMap
0 Kudos
TimWitt
Frequent Contributor
Sadly this is not possible, you need to cycle through each layer 😞
0 Kudos
T__WayneWhitley
Frequent Contributor
Yes that is good code Xander posted; however I think what confused him was your question wasn't related to the error in the code you posted.

No you do not have the same access with arcpy as you do with the system ArcMap button to 'Clear Selected Features'.

Maybe you can rig something to access ArcObjects with comtypes...but I think that's beyond the scope of this thread?


Enjoy,
Wayne
0 Kudos
XanderBakker
Esri Esteemed Contributor
Wayne is right, ArcObjects will be the way to go. It is possible to use COM objects (ArcObjects) in Python.
If you want to know a bit more, the following links may be helpful:

http://forums.arcgis.com/threads/2567-Accessing-ArcObjects-through-Python
http://www.pierssen.com/arcgis/upload/misc/python_arcobjects.pdf
http://stackoverflow.com/questions/12190807/com-objects-arcobjects-in-python

Good luck,

Xander
0 Kudos
T__WayneWhitley
Frequent Contributor
I'd like to post again both a VBA snippet and the Python comtypes equivalent... I don't know why I did not shorten the code in post #2 above to clear all selected features in the view (the current view, otherwise known as the 'focus map') to that listed below, effectively the same:
Sub ClearSelection()

Dim pMxDoc As IMxDocument
Set pMxDoc = ThisDocument

pMxDoc.FocusMap.ClearSelection
pMxDoc.ActiveView.Refresh

End Sub


Basically, the above is a VBA subroutine (called by the name ClearSelection) that sets a document object to the currently loaded mxd, clears the selection in the entire 'focus map', and refreshes the view (to show all feature selections have been cleared).
I don't think you can test this code any longer at 10.1, but you can at 10.0 if you've authorized (for free, and depending on availability) the VBA 'extension' with ESRI.

That's about as simple as you can write ArcObject code,  using VBA...  Only reason I wanted to show that is for comparison purposes, particularly for anyone interested in migrating VBA code to Python, using comtypes.  I am yet relatively unfamiliar with comtypes but figured if there's a place to at least start the 'test drive', this oh-so-simple sample would be as good as any.  So, without further ado, here it is - I am sure you can see the similarities:
import Snippets
import comtypes
from Snippets import CType

a = Snippets.GetApp()
from comtypes.gen.esriArcMapUI import *

mxDoc = CType(a.Document, IMxDocument)
mxDoc.FocusMap.ClearSelection()
mxDoc.ActiveView.Refresh()


Once everything is loaded, it is fast... also, once the document obj mxDoc is instantiated, only the last 2 commands need be executed on successive feature selection clearing.  Of course, to be able to launch this, you need to install comtypes, downloaded from SourceForge.  You also need a Snippets module - thanks very much for the 10.0-adapted module by Corey Blakeborough
of SSP Innovations and Mark Cederholm who wrote the original.  The adapted version (which I used in the above 'clear selection' snippet) is at the link below:

http://www.sspinnovations.com/sites/default/files/assets/assets/SCRIPTS/Snippets.py


All I've got for now...this is just a very thin opening to the heap of things you can do with ArcObjects.

Enjoy,
Wayne
0 Kudos
MattSayler
Occasional Contributor II
Comtypes is probably the only solution where it will be as fast as the button.

If that's not an option for whatever reason, you could keep track of the layers with selected features in a list and loop through that instead of hitting every layer. Still not great, but better.
0 Kudos
ChrisSnyder
Regular Contributor III
Via a Python solution, how about checking for any selected features before you try to unselect? Which may be faster or may be slower than not checking... Describe is pretty fast, so it might be worth the extra overhead.

if len(arcpy.Describe(lyr).fidSet) > 0:
    arcpy.SelectLayerByAttribute_management(lyr, "CLEAR_SELECTION")


BTW: Good to meet you last week Matt S.!
0 Kudos