Can I set up a field parameter without checking it is in the feature class?

391
5
02-18-2013 04:31 PM
AllanMills
New Contributor III
I've got a script which does some calculations and stores them into fields. I've designed it so that if the fields don't exist they will be created but if they do exist they will be overwritten. When I set up the tool in Arc I tell it that the field parameters are of type field and are derived from the feature class being input.

The problem is, when I run the tool if I enter new field names it stops me with an error because the fields do not exist. I do still want the combo provided from the field type since there are cases where the field will exist though.

I'm thinking it might be a matter of adjusting the validation logic but I've no experience doing that.

Any ideas? Thanks in advance.
Tags (2)
0 Kudos
5 Replies
MikeMacRae
Occasional Contributor III
Allan,

Can you post your script and the error messages you get?
0 Kudos
AllanMills
New Contributor III
It's not the script that is throwing errors. It's when I try to set it up as a geoprocessing tool in Arc. One of the parameters is a feature class and three others are fields for that feature class - two of which might not exist yet.
0 Kudos
curtvprice
MVP Esteemed Contributor
when I run the tool if I enter new field names it stops me with an error because the fields do not exist. I do still want the combo provided from the field type since there are cases where the field will exist though.

I'm thinking it might be a matter of adjusting the validation logic but I've no experience doing that.

Any ideas? Thanks in advance.


The easy way to do this is to provide the field name as a string parameter (you can give it a default name and make it optional to save user typing).  Then your script can see if the field is there and act accordingly. It's best practice to name the string parameter a "field name" instead of a "field" so it's obvious that it's a string. (Like the Add Field tool.)

You can't have a pick list without writing python validation code to populate the list of picks with the existing field names (using arcpy.Describe().Fields). You'd want to add a user entered field name (if they did that) to your list. This could get complicated and I'm not sure it is worth the effort. However, if you really want to dive into that, the help is here:
Customizing script tool behavior
0 Kudos
AllanMills
New Contributor III
Thanks. I'll see how I go.
0 Kudos
curtvprice
MVP Esteemed Contributor
I've wanted to do so myself, so I implemented some validation code to do this. In the documentation you would specify that the field must be FLOAT or DOUBLE.

  def updateParameters(self):
    """Modify the values and properties of parameters before internal
    validation is performed.  This method is called whenever a parmater
    has been changed."""
    if self.params[0].value:
      fldName = self.params[1].value
      if not fldName:
        # set default value
        fldName = "XFIELD"
      else:
        # validate field name
        wk = arcpy.Describe(self.params[0].value).catalogPath        
        fldName = arcpy.ValidateFieldName(fldName,wk).upper()
      self.params[1].value = fldName
      # populate filter (picklist) with the current field name
      # plus existing field names
      flds = arcpy.Describe(self.params[0].value).Fields
      fldNames = [f.name.upper() for f in flds if f.type not in ["OID","Geometry"]]
      self.params[1].filter.list = [fldName] + fldNames
    return

  def updateMessages(self):
    """Modify the messages created by internal validation for each tool
    parameter.  This method is called after internal validation."""
    # If field exists, make sure it's a numeric field
    fldName = self.params[1].value
    if fldName:
      flds = arcpy.Describe(self.params[0].value).Fields
      fldNames = [f.name.upper() for f in flds]
      try:
        fType = flds[fldNames.index(fldName)].type
        # no error means field found - make sure it's a number
        if fType not in ["Double","Single"]: 
          self.params[1].setIDMessage("Error",889) # invalid field type
      except:
        pass

    return
0 Kudos