Checking via ArcPy if ArcMap is in edit session?
Here's a generic function based on this post.
Maybe this is a little more kludgy than the ArcObjects solution, but it sure seems like a lot less hassle! Simple is better than complex. Except when it isn't.
Example usage:
if CheckEditSession(tbl):
print("An edit session is currently open.")
code:
def CheckEditSession(lyr):
"""Check for an active edit session on an fc or table.
Return True of edit session active, else False"""
edit_session = True
row1 = None
try:
# attempt to open two cursors on the input
# this generates a RuntimeError if no edit session is active
OID = arcpy.Describe(lyr).OIDFieldName
with arcpy.da.UpdateCursor(lyr, OID) as rows:
row = next(rows)
with arcpy.da.UpdateCursor(lyr, OID) as rows2:
row2 = next(rows2)
except RuntimeError as e:
if e.message == "workspace already in transaction mode":
# this error means that no edit session is active
edit_session = False
else:
# we have some other error going on, report it
raise
return edit_session
My solution to this problem was to use the extensions available for the Arcpy Addin Toolbar. I added an extension that listens for an edit session to begin or end. I have all of my buttons on the bar set to :self.enable = False" to start with and then these buttons are then either enable or disabled by starting or stop an edit session.
class Active_Edit_Session(object):
"""Implementation for NEZ_EDITS_addin.Listen_for_Edit_Session (Extension)"""
def __init__(self):
self.enabled = True
def onStartEditing(self):
button_3100.enabled=True
def onStopEditing(self, save_changes):
button_3100.enabled=False
class LFM_3100(object):
"""Implementation for LFM_3100.button_3100 (Button)"""
def __init__(self):
self.enabled = False
self.checked = False
def onClick(self):
......
I'm posting another answer because I've learned a new method for checking the status of the Editor in ArcMap using ArcObjects and Python together. My answer borrows heavily from the work done by Mark Cederholm as referenced in this post: How do I access ArcObjects from Python?, and code examples provided by Matt Wilkie in his "Snippits.py" file. You will need to follow the instructions provided in the first answer to download and install comtypes and then get a copy of the Snippets.py script. I am posting a copy of the essential functions from that script below.
When the function ArcMap_GetEditSessionStatus() is called, it will check the current state of the Editor in ArcMap and return true or false. This lets me check if a user is prepared to use my tool or if they need to be prompted to start an edit session. The downside to this method is the requirement to install comtypes before ArcObjects can be used in Python, so sharing a tool that requires this package in a multi-user office environment might not be possible. With my limited experience I'm not sure how to bundle it all together for easy sharing as an Esri Python tool add-in. Suggestions for how to do this would be appreciated.
#From the Snippits.py file created by Matt Wilkie
def NewObj(MyClass, MyInterface):
"""Creates a new comtypes POINTER object where\n\
MyClass is the class to be instantiated,\n\
MyInterface is the interface to be assigned"""
from comtypes.client import CreateObject
try:
ptr = CreateObject(MyClass, interface=MyInterface)
return ptr
except:
return None
def CType(obj, interface):
"""Casts obj to interface and returns comtypes POINTER or None"""
try:
newobj = obj.QueryInterface(interface)
return newobj
except:
return None
def CLSID(MyClass):
"""Return CLSID of MyClass as string"""
return str(MyClass._reg_clsid_)
def GetApp(app="ArcMap"):
"""app must be 'ArcMap' (default) or 'ArcCatalog'\n\
Execute GetDesktopModules() first"""
if not (app == "ArcMap" or app == "ArcCatalog"):
print "app must be 'ArcMap' or 'ArcCatalog'"
return None
import comtypes.gen.esriFramework as esriFramework
import comtypes.gen.esriArcMapUI as esriArcMapUI
import comtypes.gen.esriCatalogUI as esriCatalogUI
pAppROT = NewObj(esriFramework.AppROT, esriFramework.IAppROT)
iCount = pAppROT.Count
if iCount == 0:
return None
for i in range(iCount):
pApp = pAppROT.Item(i)
if app == "ArcCatalog":
if CType(pApp, esriCatalogUI.IGxApplication):
return pApp
continue
if CType(pApp, esriArcMapUI.IMxApplication):
return pApp
return None
def GetModule(sModuleName):
"""Import ArcGIS module"""
from comtypes.client import GetModule
sLibPath = GetLibPath()
GetModule(sLibPath + sModuleName)
def GetDesktopModules():
"""Import basic ArcGIS Desktop libraries"""
GetModule("esriFramework.olb")
GetModule("esriArcMapUI.olb")
#My added function for checking edit session status
def ArcMap_GetEditSessionStatus():
GetDesktopModules()
GetModule("esriEditor.olb")
import comtypes.gen.esriSystem as esriSystem
import comtypes.gen.esriEditor as esriEditor
pApp = GetApp()
pID = NewObj(esriSystem.UID, esriSystem.IUID)
pID.Value = CLSID(esriEditor.Editor)
pExt = pApp.FindExtensionByCLSID(pID)
pEditor = CType(pExt, esriEditor.IEditor)
if pEditor.EditState == esriEditor.esriStateEditing:
print "Edit session active"
return True
else:
print "Not in an edit session"
return False