0

My Python Script tool (ArcGIS Desktop 10.2) has two getParameterAsText inputs.

The first parameter is populated by the initializeParameters(self) module in the validation script which selects all CSVs in a particular folder. Obviously set to 'Input' and 'Multivalue = yes' It works fine.

The second parameter is populated by the updateParameters(self) module in the validation script by:

1) taking one CSV at a time (from parameter 1), and according to the information in its name...

2) pulling the proper path + file name from a "settings" (dbf) table with which to populate the second parameter, which is 'Output' and obviously set to "Multivalue = yes'.

The Problem:

If I select multiple CSVs from Parameter 1 the "Target_FCs" list only has the first corresponding path + file name appended to it (again, via the "settings" (dbf) table as described in step 2, above).

There are no problems with the values from my "settingsTable" (e.g. "mypath").

Quite sure the issue is that the for row in cursor line is only working the first time, just don't know why and how to make it work each time through the for csv in CSVs.split(';') loop.

BTW - I can confirm that the for csv in CSVs.split(';') loop is working correctly. If I choose 3 CSVs from Parameter 1, this loop is traveled 3 times, but the for row in cursor is only traveled once.

Validation Code Snippet:

import arcpy
import os

  def updateParameters(self):
    settingsTable = os.path.join(os.path.split(os.path.realpath(__file__))[0],"Settings_CSV_to_ASMAD_FC.dbf")
    cursor = arcpy.SearchCursor(settingsTable)
    Target_FCs = []

    CSVs = str(self.params[0].value)
    x = 0
    if self.params[0].altered:
      for csv in CSVs.split(';'):       
        if csv.upper().find("SMALLSITES") != -1:
          datatype = "SmallSites"
        elif csv.find("BIGSITES") != -1:
          datatype = "BigSites"
        if csv.upper().find("INACTIVE") != -1:
          activity = "Inactive"
        elif csv.upper().find("ACTIVE") != -1:
          activity = "Active"

        for row in cursor:
          myname = row.getValue("Name")
          mypath = row.getValue("Location")
          if myname == datatype + "_" + activity: 
            Target_FCs.append(mypath)

        self.params[1].value = Target FCs

    return

CSV contents are not relevant to this question, only their names. Some names could be: "BIGSITES_ACTIVE.csv", "SMALLSITES_INACTIVE.csv", etc...

Settings Table looks like this:

Name                    Location
BIGSITES_ACTIVE         Q:\Data\Sites.gdb\BigSites_Active
BIGSITES_INACTIVE       Q:\Data\Sites.gdb\BigSites_Inactive
SMALLSITES_ACTIVE       Q:\Data\Sites.gdb\SmallSites_Active
SMALLSITES_INACTIVE     Q:\Data\Sites.gdb\SmallSites_Inactive

It's really just a lookup table to determine where the new FC (that is to be created from the CSV) is to be stored.

  • 3
    This is may not solve your problem, but it is better to replace cursor = arcpy.SearchCursor(settingsTable) with with arcpy.da.SearchCursor(settingsTable) as cursor: – ahmadhanb Jun 13 '18 at 1:41
  • 1
    @ahmadhanb Thanks. I believe you are correct, that is a better way to script a cursor. Problem is now I'm getting errors on my validation script. All I did was copy your line of code over my original cursor line and indented the rest of my script (very careful in doing so). But I realize this is a secondary problem and will have to be for another question. For now, I'm still hoping for an answer to this one. But thanks again all the same. – Waterman Jun 13 '18 at 2:01
  • If you do switch to the arcpy.da version, it should be with arcpy.da.SearchCursor(settingsTable, ['Name', 'Location']) as cursor: . Ie, it requires a second parameter specifying which fields to include in each row (and the order of those fields) - use '*' to specify all fields (including geometry). You can then access those values as row[0] and row[1], repectively. – Son of a Beach Jun 13 '18 at 3:58
  • I would suggest adding some debugging code to write to a file. This may confirm if it is in fact running through each row as expected, and for each CSV as expected. Eg, at the beginning of the function, something like file = open("/path/to/debug-file.txt","w") and then under the for row... and just before the if myname, add something like file.write("{}, {}, {}, ".format(csv, myname, mypath)). (Of course it's better to use with with open and if you don't you should also close near the end of the function). Then see what you get in your debug file. – Son of a Beach Jun 13 '18 at 4:13
  • Apologies @SonofaBeach - I can understand your confusion. I've added the samples from my CSV and dbf ("Settings") table you requested to the end of my question. As you can see "Location" points to a "mypath" value which is in fact a "path+file name". – Waterman Jun 15 '18 at 0:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.