how to set script to handle error 000800: The value is not a member of <value>.

930
13
Jump to solution
10-08-2021 09:17 AM
RPGIS
by
Regular Contributor

 

Hi,

I am working on a custom script tool where the update parameters automatically adjust a list of selectable values. Every time the user selects a value, it is removed from the list of values and returns whichever values remain. This is set up so that either not too many values are selected or a repeat of values is selected. It works, but then this error message appears. Any help on this would be greatly appreciated.

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."""            

        # Update parameter 2 values from list generated from parameter 1 input
        feature_class = parameters[1].value
        TileNumber_field = [field.name for field in arcpy.ListFields(feature_class) if field.name == 'TILE_NUMBER']
        scur = arcpy.da.SearchCursor(feature_class, TileNumber_field)
        parameters[2].filter.list = [row[0] for row in scur]

        Export_values = ['Water', 'Sewer', 'Stormwater', 'Lidar']
        Sub_ListValues = []
        
        # Update parameter 3 value list
        Selected_value = parameters[3].valueAsText

        if Selected_value is None:
            parameters[3].filter.list = Export_values
        else:
            if ';' not in Selected_value:
                parameters[3].filter.list = [value for value in Export_values if value != Selected_value]
            elif ';' in Selected_value:
                converted_str2list = Selected_value.split(';')
                parameters[3].filter.list = [value for value in Export_values if value not in converted_str2list]

return

 

0 Kudos
1 Solution

Accepted Solutions
DonMorrison1
Occasional Contributor III

If I understand what you are trying to do, I usually accomplish it by a displaying set of checkboxes that dictate which input fields to display. The example below might seem like overkill but the code is pretty simple - you just have to set up the mapping of checkboxes to input parameters correctly. 

 

    def getParameterInfo(self):
        cb_0 = arcpy.Parameter(displayName="Checkbox 0", name="cb_0", datatype="GPBoolean", parameterType="Required", direction="Input")
        cb_1 = arcpy.Parameter(displayName="Checkbox 1", name="cb_1", datatype="GPBoolean", parameterType="Required", direction="Input")
        cb_2 = arcpy.Parameter(displayName="Checkbox 2", name="cb_2", datatype="GPBoolean", parameterType="Required", direction="Input")
        in_0 = arcpy.Parameter(displayName="Input 0", name="in_0", datatype="GPString", parameterType="Optional", direction="Input")
        in_1 = arcpy.Parameter(displayName="Input 1", name="in_1", datatype="GPString", parameterType="Optional", direction="Input")
        in_2 = arcpy.Parameter(displayName="Input 2", name="in_2", datatype="GPString", parameterType="Optional", direction="Input")
        in_3 = arcpy.Parameter(displayName="Input 3", name="in_3", datatype="GPString", parameterType="Optional", direction="Input")
        in_4 = arcpy.Parameter(displayName="Input 4", name="in_4", datatype="GPString", parameterType="Optional", direction="Input")
        return [cb_0, cb_1, cb_2, in_0, in_1, in_2, in_3, in_4]

    def updateParameters(self, parameters):
        # Parameter indexes
        CB_0 = 0
        CB_1 = 1
        CB_2 = 2
        IN_0 = 3
        IN_1 = 4
        IN_2 = 5
        IN_3 = 6
        IN_4 = 7
        # Map checkbox parameter to visible input parameters
        TBL = {CB_0: [IN_0],
               CB_1: [IN_1, IN_2],
               CB_2: [IN_2, IN_3, IN_4]}
        # Update parameter visibility
        for p_in in range (IN_0, IN_4 + 1):
            parameters[p_in].enabled = False
        for p_cb in [p for p in range (CB_0, CB_2+1) if parameters[p].value == True]:
            for p_in in TBL[p_cb]:
                parameters[p_in].enabled = True        
        return

  

View solution in original post

0 Kudos
13 Replies
JeffK
by MVP Regular Contributor
MVP Regular Contributor

Do you have anything in the in the default value or filter of the parameter of the tool?

0 Kudos
RPGIS
by
Regular Contributor

I don't have a default nor do I have any filter of the parameter. I haven't tried setting the filter but I guess I could give that a try. I will let you know if I end up with the same result.

Here is the actual error that I keep getting whenever a value is selected (i.e. Water).

ERROR 000800 The value is not a member of Sewer | Stormwater | Lidar.

0 Kudos
JeffK
by MVP Regular Contributor
MVP Regular Contributor

It looks like the validation is called again by some other trigger deep in the innerworkings of the script tool and since it is no longer part of that list that filter is validating against, it invalidates.

WPF comboboxes does the same type of behavior and will fire actions multiple times on a single click or value change and it takes some backend code to work with it.

You need to add a handler to break out of that cycle.  Maybe another class property that stores the previous value and when the method is called again, will check if the value has changed and if not, doesnt try to validate against the filter list again. This is untested, but is something similar to how I worked out the comboboxes firing multiple times on the same value.

def __init__(self):
        """Setup arcpy and the list of tool parameters."""
        self.params = arcpy.GetParameterInfo()
        self.previous_selection = None

# Update parameter 3 value list
        Selected_value = parameters[3].valueAsText
        # test if the value has changed from the previous selection and return if its the same
        if Selected_value != self.previous_selection:
            if Selected_value is None:
                parameters[3].filter.list = Export_values
        ...
        # set the previous selection value:
        self.previous_selection = Selected_value

 

0 Kudos
RPGIS
by
Regular Contributor

Hi @JeffK,

 

I tried your suggestion but the tool either raised an error or there were no values to select. There is another work around that I have thought about that I could give a try. That workaround involving multiple parameters with yes or no values. But I am hoping there is an option for ensuring that only remaining values remain when a value is selected from a list of values.

0 Kudos
DonMorrison1
Occasional Contributor III

So if the parameter value is 'Water', want to remove 'Water' from the parameter's filter list?  That won't work. The selected value always has to be a member of the filter list or else you get the ERROR 00800. Or maybe I'm not understanding it right...

0 Kudos
RPGIS
by
Regular Contributor

Hi @DonMorrison1,

When I select a single value, then the error would arise. However, if I were to select two values, the error wouldn't arise despite multiple selected values. I managed to set it and get the behavior to change so the error wouldn't persist but it was only occurring if multiple values were selected. 

0 Kudos
DonMorrison1
Occasional Contributor III

Ah - it's a multivalue parameter - you can read about my struggles here (not related to your problem).  When I run into something like this I try to reduce the code down to the absolute bare minimum to reproduce the problem, then start adding print statements so I can see what is going on.  For instance, if you remove parameters 1 and 2 can do you still get the error? Also, it would be useful to see the code in your getParametersInfo function.  

0 Kudos
RPGIS
by
Regular Contributor

Here is what I have thus far. I can easily configure everything else for when the script runs, but I am trying to setup some limitations so that the end user doesn't continuous select information and/or duplicate information. Figuring out how to set limitations based on available values is something that seems easier said than done. I thought, perhaps, to even use a table of values and set each value to only a unique selectable value.

 

 

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

import arcpy
import sys
import os


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 = "toolbox"

        # 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 = "Tool"
        self.description = ""
        self.canRunInBackground = False


    def getParameterInfo(self):
        """Define parameter definitions"""
        Select_Folder = arcpy.Parameter(
            displayName = "Select Output Folder",
            name = "Output_Folder",
            datatype = "DEType",
            parameterType = "Required",
            direction = "Input")
        
        Grid_Index = arcpy.Parameter(
            displayName = "Input Grids Feature",
            name = "TileIndex",
            datatype = "DEFeatureClass",
            parameterType = "Required",
            direction = "Input")

        Select_Grids = arcpy.Parameter(
            displayName = "Select Grids",
            name = "Select_Grids",
            datatype = "GPString",
            parameterType = "Required",
            direction = "Input",
            multiValue = True)

        Select_DataExport = arcpy.Parameter(
            displayName = "Select Data To Export",
            name = "Select_DataExport",
            datatype = "GPString",
            parameterType = "Required",
            direction = "Input",
            multiValue = True)

        Select_WaterSewerDatabases = arcpy.Parameter(
            displayName="Input Databases (Water & Sewer)",
            name = "Select_Databases",
            datatype = "DEType",
            parameterType = "Optional",
            direction = "Input",
            enabled = False)

        Select_StormwaterDatabases = arcpy.Parameter(
            displayName="Input Databases (Stormwater)",
            name = "Select_Databases",
            datatype = "DEType",
            parameterType = "Optional",
            direction = "Input",
            enabled = False)

        LidarGridsFolder = arcpy.Parameter(
            displayName = "Lidar Grids Folder",
            name = "LidarTilesFolder",
            datatype = "DEType",
            parameterType = "Optional",
            direction ="Input",
            enabled = False)

        LidarGrids = arcpy.Parameter(
            displayName = "Input Lidar Grids",
            name = "LidarTiles",
            datatype = "DEType",
            parameterType = "Optional",
            direction = "Input",
            enabled = False)
            
        parameters = [Select_Folder, Grid_Index,  Select_Grids, Select_DataExport, Select_WaterSewerDatabases, Select_StormwaterDatabases, LidarGridsFolder, LidarGrids]
        return parameters

    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."""            

        # Update parameter 2 values from list generated from parameter 1 input
        feature_class = parameters[1].value
        TileNumber_field = [field.name for field in arcpy.ListFields(feature_class) if field.name == 'TILE_NUMBER']
        scur = arcpy.da.SearchCursor(feature_class, TileNumber_field)
        parameters[2].filter.list = [row[0] for row in scur]

        Export_values = ['Water', 'Sewer', 'Stormwater', 'Lidar']
        parameters[3].filter.list = Export_values
            
        # Update either parameter 4, 5, 6, 7 depending on parameter 3 value

        if parameters[3].valueAsText is None:
            pass
        elif parameters[3].valueAsText in Export_values[:2]:
            parameters[4].enabled = True
                        
                
        if parameters[6].enabled:
            parameters[7].enabled = True
                
        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."""

##        # Input parameters for tool processing
##        folder_path = parameters[0].valueAsText
##        Grids = parameters[2].valueAsText
##        Water_Sewer_Databases = parameters[4].valueAsText
##        Stormwater_Databases = parameters[5].valueAsText
##        LidarFolder = parameters[6].valueAsText
##        
##        # Values for intermediate processing or outputs
##        new_folder = ''
##        Export_GDB = ''
##        
##        namefolder = os.path.join(folder_path, 'DataExportFolder')
##        Export_GDB_name = os.path.join(new_folder, 'Export')
##        
##        for root, directories, files in os.walk(folder_path):
##            if os.path.exists(namefolder) == True:
##                new_folder = namefolder
##            else:
##                new_folder = os.mkdir(namefolder)
##
##        for root, directory, file in os.walk(new_folder):
##            if Project in os.path.join(root, file):
##                pass
##            else:
##                Export_GDB = arcpy.management.CreateFileGDB(new_folder, Export_GDB_name)

        
        
        return

 

 

0 Kudos
DonMorrison1
Occasional Contributor III

If I understand what you are trying to do, I usually accomplish it by a displaying set of checkboxes that dictate which input fields to display. The example below might seem like overkill but the code is pretty simple - you just have to set up the mapping of checkboxes to input parameters correctly. 

 

    def getParameterInfo(self):
        cb_0 = arcpy.Parameter(displayName="Checkbox 0", name="cb_0", datatype="GPBoolean", parameterType="Required", direction="Input")
        cb_1 = arcpy.Parameter(displayName="Checkbox 1", name="cb_1", datatype="GPBoolean", parameterType="Required", direction="Input")
        cb_2 = arcpy.Parameter(displayName="Checkbox 2", name="cb_2", datatype="GPBoolean", parameterType="Required", direction="Input")
        in_0 = arcpy.Parameter(displayName="Input 0", name="in_0", datatype="GPString", parameterType="Optional", direction="Input")
        in_1 = arcpy.Parameter(displayName="Input 1", name="in_1", datatype="GPString", parameterType="Optional", direction="Input")
        in_2 = arcpy.Parameter(displayName="Input 2", name="in_2", datatype="GPString", parameterType="Optional", direction="Input")
        in_3 = arcpy.Parameter(displayName="Input 3", name="in_3", datatype="GPString", parameterType="Optional", direction="Input")
        in_4 = arcpy.Parameter(displayName="Input 4", name="in_4", datatype="GPString", parameterType="Optional", direction="Input")
        return [cb_0, cb_1, cb_2, in_0, in_1, in_2, in_3, in_4]

    def updateParameters(self, parameters):
        # Parameter indexes
        CB_0 = 0
        CB_1 = 1
        CB_2 = 2
        IN_0 = 3
        IN_1 = 4
        IN_2 = 5
        IN_3 = 6
        IN_4 = 7
        # Map checkbox parameter to visible input parameters
        TBL = {CB_0: [IN_0],
               CB_1: [IN_1, IN_2],
               CB_2: [IN_2, IN_3, IN_4]}
        # Update parameter visibility
        for p_in in range (IN_0, IN_4 + 1):
            parameters[p_in].enabled = False
        for p_cb in [p for p in range (CB_0, CB_2+1) if parameters[p].value == True]:
            for p_in in TBL[p_cb]:
                parameters[p_in].enabled = True        
        return

  

0 Kudos