-1

I am using the following code to determine if something is selected within a layer:

if arcpy.Describe("layername").FIDSet:

It is working fine and running the following code when I first open ArcMap and run the script, but once I change MXD it stops working, and the FIDset returns empty, even though there are polygons selected as before.

Has anybody run into this/a similar problem before?

Edit:

Full syntax (on an Addin button):

mxd = arcpy.mapping.MapDocument('current')
desc=arcpy.Describe("PDS Temp")

if desc.FIDSet:
    lyrs = arcpy.mapping.ListLayers(mxd,"",arcpy.mapping.ListDataFrames(mxd)[0])
    fileName1 = mxd.filePath.split("\\")[-1]
    fileName = fileName1.split(".")[0]
    for layer in lyrs:
        if layer.longName == 'PDS Temp':
            fields = arcpy.ListFields(layer, "","String")
            rows = arcpy.UpdateCursor(layer) 
            for row in rows:
                    for field in fields:
                            if field.name == "Search_Reference":
                                row.setValue(field.name,fileName)
                    rows.updateRow(row)
                    print "Search Ref Updated Successfully"
else:
    print "nothing selected"
del mxd
  • 1
    A "layer" is a property of a map document. Changing the map document would naturally refresh the layer list. This is a bit like saying the silverware drawer is missing when you visit a neighbor's house and look to the left of the stove and only find pencils, coupons, and rubber bands. – Vince Dec 3 '15 at 11:49
  • Can you edit and post more of the code, showing how you are getting layer reference and mxd reference? – artwork21 Dec 3 '15 at 12:52
  • 1
    Can you post the entire python add-in class for your button? I suspect that add-ins have a similar issue to the interactive window of keeping their entire variable state when a new map is loaded. There is a chance that even the layer references stay referencing the last layer, not the current layer so even though you redefine desc, it still ends up referencing the old 'PDS Temp' instead of the new 'PDS Temp' – blord-castillo Dec 3 '15 at 14:23
  • 1
    So this is the onClick function ? I would actually move the mxd declaration to the init function and use self.mxd instead of mxd. From some quick tests, if you use keyword "current" it always references the current document even across loads. Don't delete mxd at the end of your function. If this is wrapped in the onClick function, then you should not need to do any deleting of variables at the end. – blord-castillo Dec 3 '15 at 14:37
  • 1
    For each map doc. you are running this against, is there a layer called PDS Temp? Also, are you setting the env. workspace variable somewhere before your desc=arcpy.Describe("PDS Temp") statement? – artwork21 Dec 3 '15 at 14:40
1

I think this is what you are trying to achieve based on what you posted. I switched to using os.path to parse your filename and using an arcpy.da cursor using a with statement instead of the cursor you were using (and not cleaning up appropriately at the end, which might have kept a handle to the old PDS Temp active). You also do not need to iterate over field names, just give it the one field name that you are changing since you change it for every row anyway. I added in a test for the presence of the field name, just in case.

I suspect that your cursor not being closed was doing something weird with the PDS Temp reference, so that you are somehow still referencing the PDS Temp in the last map document. Not sure though, since I do not know the behavior of Add Ins very well.

The code sample below is untested (I don't have the python add-in wizard installed). As I noted with my comment, your one print statement should print a whole bunch. I have no idea where print statements in add-ins output to. One other thing to consider is defining self.desc in __init__ and then clearing out self.desc at the end of onClick so that desc is not reinitialized with every click.

Note: Change ButtonClass to be the appropriate class name for your button that you got from the python add-in wizard.

import arcpy
from os.path import basename
from os.path import splitext

class ButtonClass(object):
    def __init__(self):
        self.enabled = True
        self.checked = False
        self.mxd = arcpy.mapping.MapDocument('current')
    def onClick(self):
        desc = arcpy.Describe("PDS Temp")
        if desc.FIDSet:
            lyrs = arcpy.mapping.ListLayers(self.mxd, '', arcpy.mapping.ListDataFrames(self.mxd)[0])
            fileName = splitext(basename(self.mxd.filePath))[0]
            for layer in lyrs:
                if layer.longName == 'PDS Temp' and len(arcpy.ListFields(layer, 'Search_Reference')):
                    edit = arcpy.da.Editor(layer.workspacePath)
                    edit.startEditing(False, False) #Assumes unversioned data
                    edit.startOperation()
                    try:
                        with arcpy.da.UpdateCursor(layer, ['Search_Reference']) as cursor:
                            for row in cursor:
                                row[0] = fileName
                                cursor.updateRow(row)
                                #The next line will print for every row you update!
                                print('Search_Reference updated successfully.')
                    except:
                        raise
                    finally:
                        edit.stopOperation()
                        edit.stopEditing(True)
        else:
            print('Nothing selected.')

EDIT: An alternate way to do this, with the button being enabled and disabled based on there being an edit selection available.

import arcpy
import pythonaddins
from os.path import basename
from os.path import splitext

class ButtonClass(object):
    def __init__(self):
        self.enabled = False
        self.checked = False
        self.mxd = arcpy.mapping.MapDocument('current')

    def onClick(self):
        fileName = splitext(basename(self.mxd.filePath))[0]
        lyrs = arcpy.mapping.ListLayers(self.mxd, '', arcpy.mapping.ListDataFrames(self.mxd)[0])
        for layer in lyrs:
            if layer.longName == 'PDS Temp' and len(arcpy.ListFields(layer, 'Search_Reference')):
            arcpy.CalculateField_management(layer, 'Search_Reference', '"{0}"'.format(fileName, "PYTHON")
        else:
            print('Nothing selected.')

class ExtensionClass(object):
    def __init__(self):
        self.enabled = True

    def enableCheck(self):
        # tool1 is the tool ID (without the namespace prefix) for your button add-in
        # Should probably use self.currentLayer as well to make sure you have the right layer
        if len(self.editSelection) == 0:
            tool1.enabled = False
        else:
            tool1.enabled = True
            arcpy.RefreshActiveView()
        return

    def onStartEditing(self):
        self.enableCheck(self)
        return

    def onStopEditing(self):
        # tool1 is the tool ID (without the namespace prefix) for your button add-in
        tool1.enabled = False
        arcpy.RefreshActiveView()
        return

    def onEditorSelectionChanged(self):
        self.enableCheck(self)
        return
  • Thanks for taking the time. Apparently that method isn't supported in an edit session? 'RuntimeError: The operation is not supported within an edit session.' I need to be editing to have a selection though surely? – James Dec 3 '15 at 15:28
  • No, you don't at all. Hold on and I will fix that. – blord-castillo Dec 3 '15 at 15:29
  • Okay, I added in an edit session with arcpy.da.Editor. This will only work for unversioned datasets. If you are working with versioned datasets, you need to change edit.startEditing(False,False) to edit.startEditing(False,True). If you have a mix of verisoned and unversioned, it gets really complicated. – blord-castillo Dec 3 '15 at 15:37
  • Wait, 'not supported within an edit session'? Okay, that's weird if that's what it said. Do you have an edit session open while you are trying to do this? If so, then your cursors are not going to work. (And my changes above will not help you, though they also should not hurt anything.) – blord-castillo Dec 3 '15 at 15:40
  • I do yes, have an edit session open for the GDB in which the feature class 'PDS Temp' is. My previous code definately works the first time, thereafter it doesn't error, it just doesnt edit anything because it doesnt get anything from arcpy.Describe("PDS Temp") the second time around. – James Dec 3 '15 at 15:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.