Select to view content in your preferred language

Python toolbox: Setting default values in Value Table

1460
4
Jump to solution
10-26-2022 12:01 PM
ChrisRingo
Regular Contributor

Hello all,

I was wondering if anyone can point me in the right direction here.  I'm running ArcGIS Pro 2.9.5 and am creating a tool for a Python Toolbox that will take a bunch of raster layers, and run some statistics on each, among other things. 

So it will take the input rasters and statistic types (SUM, MEAN, etc.) as a Value Table (i.e., datatype='GPValueTable'). My question is how to set a default for a column in this scenario, specifically the Statistic type. In the code snippet below, setting inRasterList.values = [['', '', 'NONE']] sets the default statistic type to NONE for the first raster, but when subsequent rasters are added, the default is not set (which is obvious from the statement syntax).

# -*- coding: utf-8 -*-

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 = "ForSys Tools (Test)"
        self.alias = "ForSys Tools"

        # 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 = "Sample Rasters"
        self.description = "Sample rasters at point locations"
        self.canRunInBackground = False
    def getParameterInfo(self):
        """Define parameter definitions"""
        inRasterList = arcpy.Parameter(
            displayName="Raster List (Stands are created from first raster)",
            name="strRasters",
            datatype="GPValueTable",
            parameterType="Optional",
            direction="Input"
        inRasterList.parameterDependencies = [inRasterList.name]
        inRasterList.columns = [["GPRasterLayer", "Raster Layer"], ["GPString", "Output Field Name"], ["GPString", "Statistic Type"]]
        inRasterList.filters[2].type = "ValueList"
        inRasterList.filters[2].list = ['NONE', 'MIN', 'MAX', 'MEAN', 'SUM']
        inRasterList.values = [['', '', 'NONE']]
     
        parameters = [inRasterList]
        
        return parameters

So is there some code that can be added to the updateParameters function that will accomplish this? Thanks for any help!

0 Kudos
1 Solution

Accepted Solutions
ChrisRingo
Regular Contributor

Thank you for your replies.  It does seem that Value Tables have some rather annoying behaviors, at least in 2.x. Among these annoyances is the inability to apply defaults past the first row, and equally defeating is that Arc throws an error if not all columns are entered - once you add a row, all columns are required. So you can't apply a default and you can't leave it blank.

Really, all I wanted was the ability to leave the statistics field blank, but Arc throws the error and you can't execute the tool in that case.

So the workaround I'm settling on is this: I found that if you add code to the validation script (specifically updateMessages) to throw a warning when the first raster is entered in the value table, the warning message prevents Arc from throwing the error and preventing the script from executing.  I just made the Warning message informational, as shown in the attached pic.  Pretty kludgy, but the best I could come up with, short of diving into the Pro SDK.  

I'll go ahead and mark it solved.

View solution in original post

0 Kudos
4 Replies
AlfredBaldenweck
MVP Regular Contributor

For some reason, I’ve found that loops make Value Tables not work.

My workaround on a past project is to get the value table parameter as text, then convert it to a value table each loop.

0 Kudos
by Anonymous User
Not applicable

It looks like the 'Add Another' doesn't duplicate the parameter default values.  I think to get what you are after, you'll need to use the Pro SDK and override the 'Add Another' functionality.  

0 Kudos
ChrisRingo
Regular Contributor

Thank you for your replies.  It does seem that Value Tables have some rather annoying behaviors, at least in 2.x. Among these annoyances is the inability to apply defaults past the first row, and equally defeating is that Arc throws an error if not all columns are entered - once you add a row, all columns are required. So you can't apply a default and you can't leave it blank.

Really, all I wanted was the ability to leave the statistics field blank, but Arc throws the error and you can't execute the tool in that case.

So the workaround I'm settling on is this: I found that if you add code to the validation script (specifically updateMessages) to throw a warning when the first raster is entered in the value table, the warning message prevents Arc from throwing the error and preventing the script from executing.  I just made the Warning message informational, as shown in the attached pic.  Pretty kludgy, but the best I could come up with, short of diving into the Pro SDK.  

I'll go ahead and mark it solved.

0 Kudos
AlfredBaldenweck
MVP Regular Contributor

Why not make another option, "BLANK", and set that to the default?

I was able to come up with this. It's kinda weird, but it works well enough.

Basically, you make a dummy copy of your value table. Then you go through each row in the list ( In my case, I only have two columns, but you should be able to expand it easily) and check its values. 

If the value of the column you want to be blank is not in the list of appropriate values, it will be replaced with the "BLANK" value. A None value cannot be in the list of appropriate values, and therefore will be changed to "BLANK". Any value, e.g. "SUM" that you change it to will stick.

Of course, you'll probably have to add a line of code somewhere in your execution telling the tool what to do if the value is "BLANK", but you were probably doing that anyway.

''' Parameter Defintion'''
param22 = arcpy.Parameter(
            displayName="Test",
            name="Testin",
            datatype="GPValueTable",
            parameterType="Optional",
            direction="Input")
param22.columns = [['GPString', 'Hello'], ['GPString', 'Goodbye']]
param22.filters[0].type = 'ValueList'
param22.filters[0].list =["Hello","Bonjour",
                          "Hola", "Anyeong", "Buongiorno"]
param22.filters[1].type = 'ValueList'
param22.filters[1].list =["Goodbye","Au revoir",
                          "Adios", "Anyeong", "Ciao", "BLANK"]
param22.values = [['Hello', "BLANK"]]

'''UpdateParameters'''
newTest= parameters[22].values
for pair in newTest:
    if pair[1] not in parameters[22].filters[1].list:
        pair[1] = "BLANK"
testing.values= newTest

 

(If you want it to look prettier, you can use a value of " " (one space) to get the empty look, although that might make it confusing to read)

Hope this helps!

0 Kudos