Select to view content in your preferred language

Script Works in Python Window; Fails with AddInButton

1559
10
Jump to solution
09-12-2017 10:51 AM
JoeBorgione
MVP Emeritus

It's been 24 hours so Joe must have another Python question...

When I run the following in the python window it runs just fine:

with arcpy.da.SearchCursor(fc,fields) as rows:
 ...         streets = [row[1] for row in rows]
...          street = ",".join(["'{}'".format(s) for s in streets])
...          num = int(row[0])
...          max = num + 10
...          min = num - 10
...          where = "FullStreet = ({}) AND numeric_hn <=({}) AND numeric_hn >= ({})".format(street,max,min)
...          arcpy.SelectLayerByAttribute_management ("apLayer","ADD_TO_SELECTION",where)

I should add that I set fc = a given layer file in the arcmap session and fields is set to a list of two fields in the order of ["numeric_hn", "FullStreet"]

When I copy and paste this snippet in the addin.py file and click my button, it returns nothing.  When I run it with the python window open, I get this error:

Traceback (most recent call last):
File "C:\Users\JBorgione\AppData\Local\ESRI\Desktop10.5\AssemblyCache\{03EE6876-2D0C-48D0-86A4-147490A59723}\AddressAddIn_addin.py", line 21, in onClick
streets = [row[1] for row in rows]
IndexError: tuple index out of range

I don't understand why or how row[1] can be out of range, and I especially don't understand why it works in the python window and not when called by a button on a toolbar that has been created using the Addin Manager....

import arcpy
import pythonaddins

class ButtonClass1(object):
    """Implementation for AddressAddIn_addin.CreateLayerButton (Button)"""
    def __init__(self):
        self.enabled = True
        self.checked = False
    def onClick(self):
        arcpy.MakeFeatureLayer_management("SampleAddressPoints","apLayer")

class ButtonClass2(object):
    """Implementation for AddressAddIn_addin.RunCursorButton (Button)"""
    def __init__(self):
        self.enabled = True
        self.checked = False
    def onClick(self):
        fc = "apLayer"
        fields = ["numeric_hn","FullStreet"]
        with arcpy.da.SearchCursor(fc,fields) as rows:
            streets = [row[1] for row in rows]
            street = ",".join(["'{}'".format(s) for s in streets])
            num = int(row[0])
            max = num + 10
            min = num - 10
            where = "FullStreet = ({}) AND numeric_hn <=({}) AND numeric_hn >= ({})".format(street,max,min)
            arcpy.SelectLayerByAttribute_management ("apLayer","ADD_TO_SELECTION",where)
            
            

Thoughts?

That should just about do it....
0 Kudos
10 Replies
JoeBorgione
MVP Emeritus

Darren-  following your lead, I changed the code to look like this (from the actual .py the addin reads):

class ButtonClass2(object):
    """Implementation for AddressAddIn_addin.RunCursorButton (Button)"""
    def __init__(self):
        self.enabled = True
        self.checked = False
    def onClick(self):
        fc = "apLayer"
        fields = ["numeric_hn","FullStreet"]
        streetlist = [row[1] for row in arcpy.da.SearchCursor(fc, fields)]
        street = ",".join(["'{}'".format(s) for s in streetlist])
        numlist = [row[0] for row in arcpy.da.SearchCursor(fc, fields)]
        num = int(numlist[0])
        max = num + 10
        min = num - 10
        where = "FullStreet = ({}) AND numeric_hn <=({}) AND numeric_hn >= ({})".format(street,max,min)
        arcpy.SelectLayerByAttribute_management ("apLayer","ADD_TO_SELECTION",where)
        

I really like the two separate cursors; for me they are a  lot easier to understand what's going on.  Since this application only works with one selected record the street variable should be able to be simplified to the way I define the num variable (sans the int() function).

As always, thanks, for your help and insight.

Darren WiensCurtis Price

That should just about do it....