Select to view content in your preferred language

Combo Box not returning a usable string...

2111
10
03-08-2016 08:16 AM
BrianKingery1
New Contributor II
0 10 2,111

I have made a Python add in toolbar that has 3 combo boxes with one button. The add in allows for a user to choose a layer, choose a field from the selected layer, enter a keyword, and then when the search button is pressed, a query is applied and the extent of the data frame is zoomed to selected features. Before I go on, the tool works perfectly just as I designed it except for when the field type is 'String'. Then to make it work the user must enter the keyword in quotes. My goal is to not have the user worrying about having to type stuff in quotes because then the user would have to know what the field type is for when they are searching and that is not the case.

The query that is applied is:

[HYDRANT_NO] = 24

The snippet of code is:

# Apply search query
where_clause    = "[" + CHOICE_field + "] = " + CHOICE_keyword
arcpy.SelectLayerByAttribute_management(newLayer, "NEW_SELECTION", where_clause)

This works because the field.type of HYDRANT_NO is not 'String'. In the below example, the user selects the LastName field which is a 'String' field.type. The first figure returns no results. The second image returns the expected number of results.

1. Does Not work

2. Does work - The actual word in the table is JONES and is handled in the code on how to handle it which is why it works.

I have taken into account that I am using a personal geodatabase and that matters when writing the where_clause since it differs from ArcSDE and file geodatabases. The way that I have written the query WORKS when I do it manually in ArcMap whether it is typed into the Python window or using the Select Layer By Attribute Tool. Below is how I wrote how to check the keywords for string. It works manually but not with the addin. I have also attached the full add-in which will show the variables that are referenced. I feel that I am either missing something so small or it doesn't work because it can't work that way.

try:
    # Make layer from feature class
    arcpy.MakeFeatureLayer_management(featureClass, newLayer)


    # Apply search query
    where_clause    = "[" + CHOICE_field + "] = " + CHOICE_keyword
    arcpy.SelectLayerByAttribute_management(newLayer, "NEW_SELECTION", where_clause)
    # Get count of how many records met query
    layerCount      = arcpy.GetCount_management(newLayer)
    count           = int(layerCount.getOutput(0))
    if count != 0:
        # Zoom to layer
        df.zoomToSelectedFeatures()
    elif count == 0:
        #where_clause = '[' + CHOICE_field + "] = '" + str(CHOICE_keyword) + "'"
        where_clause = '[' + CHOICE_field + "] = '" + CHOICE_keyword_string + "'"
        arcpy.SelectLayerByAttribute_management(newLayer, "NEW_SELECTION", where_clause)
        layerCount   = arcpy.GetCount_management(newLayer)
        count        = int(layerCount.getOutput(0))
        if count != 0:
            df.zoomToSelectedFeatures()
        elif count == 0:
            where_clause = '[' + CHOICE_field + "] = '" + CHOICE_keyword_string.upper() + "'"
            arcpy.SelectLayerByAttribute_management(newLayer, "NEW_SELECTION", where_clause)
            layerCount   = arcpy.GetCount_management(newLayer)
            count        = int(layerCount.getOutput(0))
            if count != 0:
                df.zoomToSelectedFeatures()
            elif count == 0:
                where_clause = '[' + CHOICE_field + "] = '" + CHOICE_keyword_string.lower() + "'"
                arcpy.SelectLayerByAttribute_management(newLayer, "NEW_SELECTION", where_clause)
                layerCount   = arcpy.GetCount_management(newLayer)
                count        = int(layerCount.getOutput(0))
                if count != 0:
                    df.zoomToSelectedFeatures()
                elif count == 0:
                    where_clause = '[' + CHOICE_field + "] = '" + CHOICE_keyword_string.capitalize() + "'"
                    arcpy.SelectLayerByAttribute_management(newLayer, "NEW_SELECTION", where_clause)
                    layerCount   = arcpy.GetCount_management(newLayer)
                    count        = int(layerCount.getOutput(0))
                    if count != 0:
                        df.zoomToSelectedFeatures()
                    elif count == 0:
                        for lyr in arcpy.mapping.ListLayers(mxd, "", df):
                            if lyr.name == newLayer:
                                arcpy.mapping.RemoveLayer(df, lyr)
                        # Add a pop up if no results
                        pythonaddins.MessageBox("0 records matching query", "NNWW Toolbar")                            
except:
    for lyr in arcpy.mapping.ListLayers(mxd, "", df):
        if lyr.name == newLayer:
            arcpy.mapping.RemoveLayer(df, lyr)
    # Add a pop up if no results
    pythonaddins.MessageBox("0 records matching query", "NNWW Toolbar")                
10 Comments
DarrenWiens2
MVP Honored Contributor

I believe you should use: AddFieldDelimiters—ArcPy Functions | ArcGIS for Desktop

...which will place the correct quotes around the field, given the feature class name (and figuring the datasource type on its own).

BrianKingery1
New Contributor II

I will give it a shot and let you know if I can get it to work. Hopefully it is just as simple as this:

where_clause    = """{0} = '{1}'""".format(arcpy.AddFieldDelimiters(newLayer, CHOICE_field), CHOICE_keyword)

BrianKingery1
New Contributor II

So funny thing...I changed the code to the following and it will now work for strings, but only strings. I can't search for OBJECTIDs or any integers which is what worked in the first place.

BrianKingery1
New Contributor II

try:

    # Make layer from feature class

    arcpy.MakeFeatureLayer_management(featureClass, newLayer)

   

    # Apply search query

    where_clause    = """{0} = '{1}'""".format(arcpy.AddFieldDelimiters(featureClass, CHOICE_field), CHOICE_keyword)

    arcpy.SelectLayerByAttribute_management(newLayer, "NEW_SELECTION", where_clause)

    # Get count of how many records met query

    layerCount      = arcpy.GetCount_management(newLayer)

    count           = int(layerCount.getOutput(0))

    if count != 0:

        # Zoom to layer

        df.zoomToSelectedFeatures()

    elif count == 0:

        #where_clause = """{0} = {1}""".format(arcpy.AddFieldDelimiters(featureClass, CHOICE_field), int(CHOICE_keyword))

        where_clause    = "[" + CHOICE_field + "] = " + CHOICE_keyword               

        arcpy.SelectLayerByAttribute_management(newLayer, "NEW_SELECTION", where_clause)

        layerCount   = arcpy.GetCount_management(newLayer)

        count        = int(layerCount.getOutput(0))

        if count != 0:

            df.zoomToSelectedFeatures()

        elif count == 0:

            for lyr in arcpy.mapping.ListLayers(mxd, "", df):

                if lyr.name == newLayer:

                    arcpy.mapping.RemoveLayer(df, lyr)

            print '0 records found'

            # Add a pop up if no results

            pythonaddins.MessageBox("0 records matching query", "NNWW Toolbar")

except:

    for lyr in arcpy.mapping.ListLayers(mxd, "", df):

        if lyr.name == newLayer:

            arcpy.mapping.RemoveLayer(df, lyr)

    # Add a pop up if no results

    pythonaddins.MessageBox("0 records matching query", "NNWW Toolbar")

WesMiller
Regular Contributor III

It might be that you have quotes around '{1}' which makes it a string

BrianKingery1
New Contributor II

BrianKingery1
New Contributor II

The first where_clause is for the string and then if it is not a string with no results coming back, then I declare the where_clause variable back to what it was in the first place, and its not catching

DarrenWiens2
MVP Honored Contributor

Just FYI, this style works for me:

>>> where_clause = """{0} = {1}""".format(arcpy.AddFieldDelimiters(featureClass,'FID'),int(10))

... arcpy.SelectLayerByAttribute_management(newLayer,"NEW_SELECTION",where_clause)

WesMiller
Regular Contributor III

To add to Darren's I think you could also

testChoice = str(CHOICE_keyword)

if testChoice.isdigit():

  where_clause    = """{0} = {1}""".format(arcpy.AddFieldDelimiters(featureClass, CHOICE_field), CHOICE_keyword)

else:

  where_clause    = """{0} = '{1}'""".format(arcpy.AddFieldDelimiters(featureClass, CHOICE_field), CHOICE_keyword)

BrianKingery1
New Contributor II

Can't say that the solution is pretty but since it kept throwing errors where I wanted the the if/else statements to take over, I used try/except inside of a try/except and it worked exactly how I want. Thanks for the assistance.

About the Author
GIS consultant and administrator. Contact me at...Work email: Brian.Kingery@timmons.com Personal email: briankingery87@gmail.com Cell: 757.810.6198 Twitter: https://twitter.com/briankingery87 Website: http://www.timmonsgis.com