Update Cursor script that allows selectable field to be updated?

440
5
Jump to solution
06-06-2013 12:23 PM
RachelAlbritton
Occasional Contributor III
I've written a code that selects attributes one by one. As each attribute is selected a select by location is performed to identify how many records in the select by location file intersect with the selected record from the select by attributes query. The number of records that intersect the selected attribute are recorded to the attribute table. The script works if the field to be updated is hardcodded into the script. I want to be able to pick what field gets to be updated each time the script is run. Is this possible?

import arcpy, os  arcpy.env.workspace = "C:/Temp" #arcpy.GetParameterAsText(0) arcpy.env.overwriteOutput = True outputWorkspace = "C:/Temp/Scratch" #arcpy.GetParameterAsText(1)  def outName(input,post="_Output"):     """Returns output name."""     outName=os.path.basename(input).split(".")[0]+post     return outName      Attribute = "Parcel_Test.shp" #arcpy.GetParameterAsText(2) Location = "Test_Wetlands.shp" #arcpy.GetParameterAsText(3)       #Get Count of the number of records for the file needing to be updated. #This count will be automatically plugged into a range value needed to write results from the analysis to the output shapefile. RangeCount = int(arcpy.GetCount_management(Attribute).getOutput(0)) print "There are", RangeCount, "records that need to be updated" arcpy.AddMessage("There are "+str(RangeCount)+" that need to be updated\n")  #Create Features Layers from Feature Classes AttributeFL=outName(Attribute,"_Layer") LocationFL=outName(Location,"_Layer") arcpy.MakeFeatureLayer_management(Attribute,AttributeFL) arcpy.MakeFeatureLayer_management(Location, LocationFL)  #Begin Update print "\nUpdating file with the number of records that intersect with each attribute" arcpy.AddMessage("Updating file with the number of records that intersect with each attribute\n")  for attribute in range(0,RangeCount):     FID = "FID=%s" % (attribute)     arcpy.SelectLayerByAttribute_management(AttributeFL,"NEW_SELECTION",FID)     arcpy.SelectLayerByLocation_management(LocationFL,"INTERSECT",AttributeFL)     LocationCount = int(arcpy.GetCount_management(LocationFL).getOutput(0))     arcpy.AddMessage(str(FID)+" has "+str(LocationCount)+" records that intersect with it.")     print str(FID), "has", LocationCount, "records that intersect with it."          #Update the three_mi field      uc=arcpy.UpdateCursor(AttributeFL)     for line in uc:         line.count = LocationCount         uc.updateRow(line) #Actually changes the table values to buffer count     del line     del uc      arcpy.SelectLayerByAttribute_management(AttributeFL,"CLEAR_SELECTION")      arcpy.AddMessage(Attribute+" has been updated\n") print Attribute, "has been updated\n"
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
ChrisSnyder
Regular Contributor III
If your field name is a variable, you need to use the .setValue() method. For example:

myFieldName = "CRAZY_FIELD" line.setValue(myFieldName, LocationCount)

View solution in original post

0 Kudos
5 Replies
ChrisPedrezuela
Occasional Contributor III
Hi,

You could just probably add a new input parameter:

inputFields = arcpy.GetParameterAsText(4)

Then from the script properties, in the parameters tab, set it to type "field", multiple input and indicate the source layer to get the fields from. You'll get a list of field names with checkboxes and any fieldname you check will be your input.

Cheers


I've written a code that selects attributes one by one. As each attribute is selected a select by location is performed to identify how many records in the select by location file intersect with the selected record from the select by attributes query. The number of records that intersect the selected attribute are recorded to the attribute table. The script works if the field to be updated is hardcodded into the script. I want to be able to pick what field gets to be updated each time the script is run. Is this possible?
import arcpy, os

arcpy.env.workspace = "C:/Temp" #arcpy.GetParameterAsText(0)
arcpy.env.overwriteOutput = True
outputWorkspace = "C:/Temp/Scratch" #arcpy.GetParameterAsText(1)

def outName(input,post="_Output"):
    """Returns output name."""
    outName=os.path.basename(input).split(".")[0]+post
    return outName
    
Attribute = "Parcel_Test.shp" #arcpy.GetParameterAsText(2)
Location = "Test_Wetlands.shp" #arcpy.GetParameterAsText(3)
     
#Get Count of the number of records for the file needing to be updated.
#This count will be automatically plugged into a range value needed to write results from the analysis to the output shapefile.
RangeCount = int(arcpy.GetCount_management(Attribute).getOutput(0))
print "There are", RangeCount, "records that need to be updated"
arcpy.AddMessage("There are "+str(RangeCount)+" that need to be updated\n")

#Create Features Layers from Feature Classes
AttributeFL=outName(Attribute,"_Layer")
LocationFL=outName(Location,"_Layer")
arcpy.MakeFeatureLayer_management(Attribute,AttributeFL)
arcpy.MakeFeatureLayer_management(Location, LocationFL)

#Begin Update
print "\nUpdating file with the number of records that intersect with each attribute"
arcpy.AddMessage("Updating file with the number of records that intersect with each attribute\n")

for attribute in range(0,RangeCount):
    FID = "FID=%s" % (attribute)
    arcpy.SelectLayerByAttribute_management(AttributeFL,"NEW_SELECTION",FID)
    arcpy.SelectLayerByLocation_management(LocationFL,"INTERSECT",AttributeFL)
    LocationCount = int(arcpy.GetCount_management(LocationFL).getOutput(0))
    arcpy.AddMessage(str(FID)+" has "+str(LocationCount)+" records that intersect with it.")
    print str(FID), "has", LocationCount, "records that intersect with it."
    
    #Update the three_mi field 
    uc=arcpy.UpdateCursor(AttributeFL)
    for line in uc:
        line.count = LocationCount
        uc.updateRow(line) #Actually changes the table values to buffer count
    del line
    del uc

    arcpy.SelectLayerByAttribute_management(AttributeFL,"CLEAR_SELECTION")
    
arcpy.AddMessage(Attribute+" has been updated\n")
print Attribute, "has been updated\n"
0 Kudos
RachelAlbritton
Occasional Contributor III
Thanks for the reply. I have tried assigning a variable to a field, but I get a general 99999 error.

import arcpy, os

arcpy.env.workspace = "C:/Temp" #arcpy.GetParameterAsText(0)
arcpy.env.overwriteOutput = True
outputWorkspace = "C:/Temp/Scratch" #arcpy.GetParameterAsText(1)

def outName(input,post="_Output"):
    """Returns output name."""
    outName=os.path.basename(input).split(".")[0]+post
    return outName
    
Attribute = "Parcel_Test.shp" #arcpy.GetParameterAsText(2)
Location = "Test_Wetlands.shp" #arcpy.GetParameterAsText(3)
Field = arcpy.GetParameterAsText(0)
     
#Get Count of the number of records for the file needing to be updated.
#This count will be automatically plugged into a range value needed to write results from the analysis to the output shapefile.
RangeCount = int(arcpy.GetCount_management(Attribute).getOutput(0))
print "There are", RangeCount, "records that need to be updated"
arcpy.AddMessage("There are "+str(RangeCount)+" that need to be updated\n")

#Create Features Layers from Feature Classes
AttributeFL=outName(Attribute,"_Layer")
LocationFL=outName(Location,"_Layer")
arcpy.MakeFeatureLayer_management(Attribute,AttributeFL)
arcpy.MakeFeatureLayer_management(Location, LocationFL)

#Begin Update
print "\nUpdating file with the number of records that intersect with each attribute"
arcpy.AddMessage("Updating file with the number of records that intersect with each attribute\n")

for attribute in range(0,RangeCount):
    FID = "FID=%s" % (attribute)
    arcpy.SelectLayerByAttribute_management(AttributeFL,"NEW_SELECTION",FID)
    arcpy.SelectLayerByLocation_management(LocationFL,"INTERSECT",AttributeFL)
    LocationCount = int(arcpy.GetCount_management(LocationFL).getOutput(0))
    arcpy.AddMessage(str(FID)+" has "+str(LocationCount)+" records that intersect with it.")
    print str(FID), "has", LocationCount, "records that intersect with it."
    
    #Update the three_mi field 
    uc=arcpy.UpdateCursor(AttributeFL)
    for line in uc:
        line.Field = LocationCount
        uc.updateRow(line) #Actually changes the table values to buffer count
    del line
    del uc

    arcpy.SelectLayerByAttribute_management(AttributeFL,"CLEAR_SELECTION")
    
arcpy.AddMessage(Attribute+" has been updated\n")
print Attribute, "has been updated\n"


Error Message:

Traceback (most recent call last):
  File "C:\Python26\ArcGIS10.0\Lib\site-packages\pythonwin\pywin\framework\scriptutils.py", line 326, in RunScript
    exec codeObject in __main__.__dict__
  File "C:\ArcGIS\Tools\Select_Update.py", line 67, in <module>
    line.Field = LocationCount
  File "C:\Program Files (x86)\ArcGIS\Desktop10.0\arcpy\arcpy\arcobjects\_base.py", line 35, in __setattr__
    return setattr(self._arc_object, attr, ao)
RuntimeError: ERROR 999999: Error executing function.
0 Kudos
ChrisSnyder
Regular Contributor III
If your field name is a variable, you need to use the .setValue() method. For example:

myFieldName = "CRAZY_FIELD" line.setValue(myFieldName, LocationCount)
0 Kudos
RachelAlbritton
Occasional Contributor III
That worked - Thanks!
0 Kudos
ChrisPedrezuela
Occasional Contributor III
Yup you need to use setValue since using line.Field makes the program think there is an actual fieldname "Field"
0 Kudos