1

I have a CSV file which contains a list of clients and different project numbers and project names. This list is generated periodically. The list can contain multiple values for client name but unique values in the project number/name fields. For example, the CSV might look like this:

COMPANY NAME, PROJECT NUMBER, PROJECT NAME

ABC Corp, P123, Mapping Project 1
ABC Corp, P124, Mapping Project 2
Acme, P38, Some Kind of Project 1
BBB Corp, P188, Another Kind of Project
BBB Corp, P189, Another Kind of Project 2
BBB Corp, P190, Mapping Project 1

What I would like to do is create a python tool in ArcGIS 10.2.1 which has two parameters:

  1. Company Name
  2. Project

The Project parameter would be a concatenation of PROJECT NUMBER, PROJECT NAME in the format: PROJECT NUMBER - PROJECT NAME.

I'm trying to program a validation class such that the user is presented with a drop down list of UNIQUE values of the client name. Then, the second parameter would present only the project numbers associated with that client. These values would then populate values in a map layout.

So, for example, if the user selects ABC Corp from the first drop down, the second drop down would only have two choices:

P123 - Mapping Project 1
P124 - Mapping Project 2

Similarly, if the user selects BBB Corp from the first drop down, the second drop down would have three choices:

P188 - Another Kind of Project
P189 - Another Kind of Project 2
P190 - Mapping Project 1

I've successfully got the first drop down to create a unique list of companies. However, I'm having trouble getting the validator class to display properly. I can generate a list in IDLE correctly, I'm just not sure how I can get it to display in ArcGIS.

My validator code looks like this:

import arcpy, csv
class ToolValidator(object):
  """Class for validating a tool's parameter values and controlling
  the behavior of the tool's dialog."""

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

    csvpath = "S:\projects\P000000 Pre-Sales and Internal GIS Activities\ArcGIS Toolbox Development\Get XIC Information\CSV\ProjectData.csv"
    xicData = []
    with open(csvpath,'rb') as csvfile:
        reader = csv.reader(csvfile, delimiter = ',', quotechar='|')
        for row in reader:
            xicData.append(', '.join(row))

    xicData.pop(0)
    self.xicData = xicData
    pass

  def initializeParameters(self):
    """Refine the properties of a tool's parameters.  This method is
    called when the tool is opened."""

    companyset=set()
    for i in self.xicData:
        companyset.add(i.split(', ')[0])
    companylist=list(companyset)
    companylist.sort()

    self.params[0].filter.list = companylist
    return 

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

    if self.params[0].value:
        projectList = self.params[1].filter
        companyName = self.params[0]
        projectList = []
        xicSplit = []
        for i in self.xicData:
            xicSplit.append(i.split(', '))
        for i in xicSplit:
            if i[0] == companyName:
                projectList.append(i[1] + ' - ' + i[2])

        projectList.sort()


        self.params[1].filter.list = projectList
    return

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

The problem seems to be in the updateParameters function. I think my logic is sound, but I don't know where I'm going wrong.

2

Here is the corrected script. I changed just one lines and it is working.

import arcpy, csv
class ToolValidator(object):
    """Class for validating a tool's parameter values and controlling
    the behavior of the tool's dialog."""

    def __init__(self):
        """Setup arcpy and the list of tool parameters."""
        self.params = arcpy.GetParameterInfo()
        csvpath = "D:/Python/Toolbox/company_project.csv"
        xicData = []
        with open(csvpath,'rb') as csvfile:
            reader = csv.reader(csvfile, delimiter = ',', quotechar='|')
            for row in reader:
                xicData.append(', '.join(row))

        xicData.pop(0)

        self.xicData = xicData
        pass

    def initializeParameters(self):
        """Refine the properties of a tool's parameters.  This method is
        called when the tool is opened."""
        companyset=set()
        for i in self.xicData:
            companyset.add(i.split(', ')[0])
        companylist=list(companyset)
        companylist.sort()

        self.params[0].filter.list = companylist
        return

    def updateParameters(self):
        """Modify the values and properties of parameters before internal
        validation is performed.  This method is called whenever a parameter
        has been changed."""
        if self.params[0].value:
            projectList = self.params[1].filter
            # you are comparing the companyName with 
            # the xicSplit value below in script
            # so, to get value of params use self.params[0].value 
            # as used in below line
            companyName = self.params[0].value
            projectList = []
            xicSplit = []
            for i in self.xicData:
                xicSplit.append(i.split(', '))
            for i in xicSplit:
                if i[0] == companyName:
                    projectList.append(i[1] + ' - ' + i[2])
            projectList.sort()
            self.params[1].filter.list = projectList
        return

    def updateMessages(self):
        """Modify the messages created by internal validation for each tool
        parameter.  This method is called after internal validation."""
        return
  • Thanks. Turns out, all I needed to do was change the line in the updateParameters function. I just added .value and it worked. You're incorrect about .pop() creating a blank value in the zeroth index of the list. It just removes it and the first index becomes the zeroth index. I did that to remove headers. – Fezter May 8 '14 at 1:04
  • I intended to write "after using .pop()" but instead I wrote "by using .pop()". Sorry about that. And in my csv file I had a blank line, so I got that blank value at zeroth index. Thank you for correcting me – Surya May 8 '14 at 17:50

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.