mudo

Refresh default values in GPValue table parameter in Python toolbox

Discussion created by mudo on Jun 5, 2014
Latest reply on Jul 1, 2014 by mudo
I am working in ArcGIS 10.1 SP 1 on Windows Server 2008 R2 Enterprise.

I created a python toolbox that is opened from a python addin and displays records from a feature class in a value table. It allows users to change values (by reordering the records)  or delete records in that feature class.  I would like the tool to open and display the records that are currently in the feature class.  It does this the first time it is opened and completes the edits,  however, when I launch the tool again, the value table does not refresh to reflect the changes to the feature class.  Instead, the records(and their values) that were in the feature class prior to any changes and tool execution are shown in the value table.

I have tried calling the getParameterInfo() method from various places in the code with no luck. 

The only way I can get it to update is to manually refresh the python toolbox in ArcCatalog.  Any help is appreciated. 

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 = [ReorderPages]


class ReorderPages(object):
    # TODO How to refresh parameter list
    def __init__(self):
        """Define the tool (tool name is the name of the class)."""
        self.label = "Reorder Pages"
        self.description = ""
        self.canRunInBackground = False

    def getParameterInfo(self):
        """Define parameter definitions"""
        params = []
        mxd = arcpy.mapping.MapDocument("CURRENT")
        param0 = arcpy.Parameter(
            displayName = 'Pages',
            name = 'pages',
            datatype = 'GPValueTable',
            parameterType = 'Optional',
            direction = 'Input'
            )
        param0.columns = [['String', 'Map Page']]
        gridFc = os.path.dirname(mxd.filePath) + r"\SourceData.gdb\Grid_Index"
        param0.values = sorted([[r[0] + " pg. " + str(r[1])] for r in arcpy.da.SearchCursor(gridFc, ["MXD_NAME", "PAGE_NUM"])])
        params = [param0]
        return params
    

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

    def updateParameters(self, parameters):
        """Modify the values and properties of parameters before internal
        validation is performed.  This method is called whenever a parameter
        has been changed."""
        pass

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

    def getNewIndex(self, map_name, pos_list):
        # Get a single map name and the updated position list from the user
        # to create a dictionary holding the map names (e.g. "Timber Sales Map pg. 1")
        # and the user specified position relative to other maps of the same name.
        # The format will be {"Timber Sales Map pg. 1: 3, "Timber Sales Map pg. 2: 2, ...}
        list_by_map = [mp.strip("'") for mp in pos_list if mp and re.match(map_name, mp)]
        dict_by_map = {m: list_by_map.index(m) + 1 for m in list_by_map}
        return dict_by_map

    def getMapNames(self, index_feature):
        search_nms = arcpy.da.SearchCursor(index_feature, ["MXD_NAME"])
        names = []
        for record in search_nms:
            names.append(record[0])
            map_list = list(set(names))
        del record, search_nms, names
        return map_list

    def updateIndex(self, index_feature, pos_list):
        map_set = self.getMapNames(index_feature)
        for mp in map_set:
            expr = "MXD_NAME = '" + mp + "'"
            new_pos = self.getNewIndex(mp, pos_list)
            update_indx = arcpy.da.UpdateCursor(index_feature, ["MXD_NAME", "PAGE_NUM"], expr)
            for ind_rec in update_indx:
                map_page = ind_rec[0] + " pg. " + str(ind_rec[1])
                if map_page in pos_list:
                    ind_rec[1] = new_pos[map_page]
                    update_indx.updateRow(ind_rec)
                else:
                    update_indx.deleteRow()
            del ind_rec, update_indx
        del map_set

    def execute(self, parameters, messages):
        """The source code of the tool."""
        new_list = parameters[0].valueAsText
        pg_list = new_list.split(";")
        pg_clean = [m.strip("'") for m in pg_list]
        mxd = arcpy.mapping.MapDocument("CURRENT")
        path = os.path.dirname(mxd.filePath)
        grid_fc = path + r"\SourceData.gdb\Grid_Index"
        self.updateIndex(grid_fc, pg_clean)
        del mxd, new_list, pg_list, pg_clean, grid_fc, path

Outcomes