1

I developed a Python toolbox in ArcGIS 10.3. Everything in this toolbox works correctly. I just have one problem: Every time I click on the value table (ex:click 1 in below image), then click on anywhere in toolbox (ex:click 2) the toolbox and data frame are refreshed. It's very annoying for users. The refreshing process continues until the user closes the toolbox. Refreshing is enabled after select a feature (select by attribute in my code). How can I get rid of refreshing toolbox?


I edited my code. I used SearchCursor to list values in value tables and used SelectByAttribute function outside the if statement.As @Hornbydd mentioned the problem is SelectByAttribute.I think if SelectByAttribute runs only once then if parameters[0].value altered, this function run again The refresh problem will solve.But how to force SelectByAttribute to run once ?

import arcpy




class Toolbox(object):
    def __init__(self):
        """Define the toolbox (the name of the toolbox is the name of the
        .pyt file)."""
        self.label = "Toolbox"
        self.alias = ""

        # List of tool classes associated with this toolbox
        self.tools = [Tool]


class Tool(object):
    def __init__(self):
        """Define the tool (tool name is the name of the class)."""


        self.label = "b"
        self.description = ""
        self.canRunInBackground = False

    def getParameterInfo(self):
        """Define parameter definitions"""
         # line point parameter
        params0 = arcpy.Parameter(
        displayName="Line point",
        name="line_point",
        datatype="GPFeatureLayer",
        parameterType="Optional",
        direction="Input")
        params0.filter.list = ["Polyline"]

        # point parameter
        params1 = arcpy.Parameter(
        displayName="point",
        name="point_point",
        datatype="GPFeatureLayer",
        parameterType="Optional",
        direction="Input")
        params1.filter.list = ["POINT"]

        # Table
        params2 = arcpy.Parameter(
        displayName="Table",
        name="table",
        datatype="GPTableView",
        parameterType="Required",
        direction="Input")
        # line code
        params3 = arcpy.Parameter(
        displayName="Line Code",
        name="Line_Code",
        datatype="GPLong",
        parameterType="Required",
        direction="Input")
        #  Direction

        params4 = arcpy.Parameter(
        displayName="Direction",
        name="Direction",
        datatype="GPString",
        parameterType="Required",
        direction="Input")
        params4.filter.type="ValueList"

        #  value table
        params5 = arcpy.Parameter(
            displayName='Values',
            name='values',
            datatype='GPValueTable',
            parameterType='Required',
            direction='Input')
         # Table output
        params6 = arcpy.Parameter(
        displayName="Tableoutput",
        name="tableoutput",
        datatype="GPTableView",
        parameterType="Derived",
        direction="Output")
        params6.parameterDependencies = [params2.name]


        params5.columns = [['Long', 'point Code'],['GPString','point Name'],['GPString','Rank']]
        params5.filters[2].type="ValueList"

        params = [params0,params1,params2,params3,params4,params5,params6]
        return params

    def isLicensed(self):
        """Set whether tool is licensed to execute."""
        return True

    def updateParameters(self, parameters):
        fielddelimi1 = arcpy.AddFieldDelimiters(parameters[0].value, "Number")
        sql_exp1 = "{0} = {1}".format(fielddelimi1,parameters[3].value)
        fielddelimi2 = arcpy.AddFieldDelimiters(parameters[0].value, "PathType")
        sql_exp2 = u"{0} = '{1}'".format(fielddelimi2,u'\u0631\u0641\u062a')
        sqlfinal = u"%s AND %s"%(sql_exp1,sql_exp2)

        arcpy.SelectLayerByAttribute_management(parameters[0].valueAsText,"NEW_SELECTION",where_clause= sqlfinal)
        if parameters[0].value and parameters[1].value and parameters[2].value and parameters[3].altered :

            def valuetable():
               if not parameters[5].altered :
                   with arcpy.da.SearchCursor(parameters[2].valueAsText,["Number","pointUniqueCode","pointRow"],where_clause = sqlfinal) as curtable:
                        vtab = []

                        for rowt in curtable:

                           vtab.append([rowt[0],rowt[1],rowt[2]])
                           parameters[5].value = vtab

            with arcpy.da.SearchCursor(parameters[0].valueAsText,"Number",where_clause = sql_exp1) as curpoint :
                l2 = [valuetable() for row in curpoint if row[0] == parameters[3].value]




            return

    def updateMessages(self, parameters):
        """Modify the messages created by internal validation for each tool
        parameter.  This method is called after internal validation."""
        return

    def execute(self, parameters, messages):
        """The source code of the tool."""

        if  parameters[5].altered :

            fields = [f for f in parameters[5].value]
            UniqueCode = [f[0] for f in parameters[5].value]
            rankslist = zip(*fields)[-1]
            i = 0
            with arcpy.da.UpdateCursor(parameters[6].valueAsText,["pointUniqueCode","pointRow"]) as cur:
                for row in cur:

                        row[1] = rankslist[i]
                        cur.updateRow(row)
                        i+=1



        return
  • 1
    I have a feeling that this behaviour is outside your control and is being called internally by the SelectLayerByAttribute tools. No idea this will work so give it a go, try setting the environment setting addOutputsToMap to False? The logic is if you are not adding to Map then no need to refresh? – Hornbydd Nov 16 '16 at 17:51
  • Your question seems to have changed since it was first asked. Now, while it has no answers is the ideal time to heavily revise it to try and make what you are now asking clear. – PolyGeo Jan 25 '17 at 8:04
1

Once the user has altered a parameter, the "altered" property will always be true, but the "hasBeenValidated" parameter is only false until the first run through the updateParameters routine after they edit the value. You might want to check for that instead.

if not parameters[3].hasBeenValidated:

  arcpy.SelectLayerByAttribute_management(parameters[0].valueAsText,"NEW_SELECTION",where_clause= sqlfinal)

The attribute in question is described on this help page: http://pro.arcgis.com/en/pro-app/arcpy/geoprocessing_and_python/customizing-tool-behavior-in-a-python-toolbox.htm

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.