Copy selected features to geodatabase feature class

5713
34
Jump to solution
06-11-2015 08:23 AM
CCWeedcontrol
Occasional Contributor III

I am working on creating a addon button to update some address points and copy that updated feature. The first part of the code does what it is suppose to do (only update the selected feature) but the second part of the code doesn't do what it is suppose to do and that is copy "only" the selected feature to the file geodatbase feature class. The code runs fine i don't get any errors but the second part of the codes doesn't copy the selected feature.

I would also like to an an "if" statement. if there is no feature selected i want it to do nothing or tell me there is nothing selected. if there is something selected i want it to only updates the selected feature and only copy the selected feature. Any ideas?

import arcpy, time
import pythonaddins
import os

#populate selected feature 
APT = "TEST"
arcpy.env.overwriteOutput = True
mxd = arcpy.mapping.MapDocument("CURRENT")
if int(arcpy.GetCount_management(APT).getOutput(0)) > 0:
    rows = arcpy.UpdateCursor(APT)
    for row in rows:
        row.FacltyType = ("Single Family Home")
        row.StructType = ("Primary, Private")
        row.Verified = ("Yes, GRM, TA")
        row.Status = ("Active")
        row.StructCat = ("Residential")
        row.APA_CODE = ("1110")
        rows.updateRow(row)
    del row, rows

#Copies address point to backup address points in filegeodatabase

fc1 = "CCAP"

#Database
workspace = r"C:\GIS\CCAP\CCAP.mdb"
arcpy.env.overwriteOutput = True
# Start an edit session. Must provide the worksapce.
edit = arcpy.da.Editor(workspace)

# Edit session is started without an undo/redo stack for versioned data
#  (for second argument, use False for unversioned data)
edit.startEditing(True)

# Start an edit operation
edit.startOperation()

if int(arcpy.GetCount_management(APT).getOutput(0)) > 0:
    arcpy.Append_management(APT, fc1, "NO_TEST")

# Stop the edit operation.
edit.stopOperation()

# Stop the edit session and save the changes
edit.stopEditing(True)

arcpy.RefreshActiveView()
Tags (1)
0 Kudos
1 Solution

Accepted Solutions
RichardFairhurst
MVP Honored Contributor

Yes, lists are the key to what you want to do.  that is why the arcpy.ListFields function returns a list of field objects (not just field names).  With two of these lists from different databases you can create a looping structure that is nearly identical to the code I provided to relate the two lists and perform updates.  The list of field objects can easily be converted to the list of field names used by the cursors.

So here is some code that should work for relating two field lists for two different data sources using the ListFields function.  Since the field lists for both the update cursor and insert cursor match you can use the same row object for the updateRow and InsertRow methods:

import arcpy     
from datetime import datetime as d     
startTime = d.now()     
     
#set to folder where features are located     
arcpy.env.workspace = r"C:\Users\OWNER\Desktop\Test" #on windows use \ instead of /     
arcpy.env.overwriteOutput = True     
#---------------------------     
#define variables for cursor     
#---------------------------     
FC = "test"     
incidentsFC = "CCAP"


FCfields = arcpy.ListFields(FC)  
incidentsFCfields = arcpy.ListFields(incidentsFC)  
# Create a field list of fields you want to manipulate and not just copy  
# All of these fields must be in the incidentsFC  
manualFields =  ["FacltyType", "StructType", "Verified", "Status", "StructCat", "APA_CODE", "ACCOUNT", 'SiteStreet', 'SHAPE@X', 'SHAPE@Y']  
matchedFields = []  
for manualField in manualFields:  
    matchedFields.append(manualField.upper())  
for FCfield in FCfields:  
    for incidentFCfield in incidentsFCfields:  
        # if FCfield.name.upper() == incidentFCfield.name.upper() and \  
        # FCfield.type == incidentFCfield.type and \  
        # incidentFCfield.editable() and \  
        # not FCfield.name.upper() in matchedFields:  
        if FCfield.name.upper() == incidentFCfield.name.upper() and FCfield.type == incidentFCfield.type and incidentFCfield.editable == True and not (FCfield.name.upper() in matchedFields):  
            matchedFields.append(FCfield.name)  
            break  
  
parcelsCount = int(arcpy.GetCount_management(FC).getOutput(0))   
  
dsc = arcpy.Describe(FC)       
  
rowInserter = arcpy.da.InsertCursor(incidentsFC, matchedFields)      
     
selection_set = dsc.FIDSet       
if len(selection_set) == 0:     
    print "There are no features selected"
           
elif parcelsCount >= 1:         
    with arcpy.da.UpdateCursor(FC, matchedFields) as rows:     
        for row in rows:     
            row[0] = ("Single Family Home")         
            row[1] = ("Primary, Private")         
            row[2] = ("Yes, GRM, TA")         
            row[3] = ("Active")         
            row[4] = ("Residential")         
            row[5] = ("1110")     
            rows.updateRow(row)     
       
            rowInserter.insertRow(row)   
    del row     
    del rows     
    del rowInserter
   
arcpy.RefreshActiveView()                           
try:   
    print '(Elapsed time: ' + str(d.now() - startTime)[:-3] + ')'   
   
except Exception, e:   
    # If an error occurred, print line number and error message   
    import traceback, sys   
    tb = sys.exc_info()[2]   
    print "Line %i" % tb.tb_lineno   
    print e.message

View solution in original post

34 Replies
SepheFox
Frequent Contributor

Hey there, it's not necessary to be in an edit session to use the append tool. Try this:

import arcpy

#populate selected feature
APT = "TEST"
fc1 = "CCAP"
workspace = r"C:\GIS\CCAP\CCAP.mdb"
arcpy.env.overwriteOutput = True
mxd = arcpy.mapping.MapDocument("CURRENT")
if int(arcpy.GetCount_management(APT).getOutput(0)) > 0:
    rows = arcpy.UpdateCursor(APT)
    for row in rows:
        row.FacltyType = ("Single Family Home")
        row.StructType = ("Primary, Private")
        row.Verified = ("Yes, GRM, TA")
        row.Status = ("Active")
        row.StructCat = ("Residential")
        row.APA_CODE = ("1110")
        rows.updateRow(row)
        arcpy.Append_management(APT, fc1, "NO_TEST")
        del row, rows
    elif int(arcpy.GetCount_management(APT).getOutput(0)) == 0:
        print "There are no features selected"
    arcpy.RefreshActiveView()
0 Kudos
CCWeedcontrol
Occasional Contributor III

I am getting an error on elif int(arcpy.GetCount_management(APT).getOutput(0)) == 0

Parsing error SyntaxError: invalid syntax (line 21)

0 Kudos
SepheFox
Frequent Contributor

Oh yes, I see the mistake. It needs to be indented to the same level as if, and then print statement should be indented level with rows, and refresh view shouldn't be indented.

0 Kudos
CCWeedcontrol
Occasional Contributor III

after adjusting the indents and when nothing is select and run the code i get the following error on line 18

Runtime error

Traceback (most recent call last):

  File "<string>", line 18, in <module>

NameError: name 'rows' is not defined

import arcpy  
  
#populate selected feature  
APT = "TEST"  
fc1 = "CCAP"  
workspace = r"C:\GIS\CCAP\CCAP.mdb"  
arcpy.env.overwriteOutput = True  
mxd = arcpy.mapping.MapDocument("CURRENT")  
if int(arcpy.GetCount_management(APT).getOutput(0)) > 0:  
    rows = arcpy.UpdateCursor(APT)  
    for row in rows:  
        row.FacltyType = ("Single Family Home")  
        row.StructType = ("Primary, Private")  
        row.Verified = ("Yes, GRM, TA")  
        row.Status = ("Active")  
        row.StructCat = ("Residential")  
        row.APA_CODE = ("1110")  
        rows.updateRow(row)  
        arcpy.Append_management(APT, fc1, "NO_TEST")  
        del row, rows  
elif int(arcpy.GetCount_management(APT).getOutput(0)) == 0:  
    print "There are no features selected"  

With a point selected i don't get any error. The "TEST" point that is selected does the fields updated but nothing is copied to the "CCAP" feature class.

0 Kudos
DanPatterson_Retired
MVP Emeritus

your cursor needs to be outside the​ if statement (into line 8.5) because it is undefined if the count is 0 and goes to the 'else' portion of the if-else

CCWeedcontrol
Occasional Contributor III

interesting i am not sure i follow into line 8.5?

0 Kudos
DanPatterson_Retired
MVP Emeritus

​hmmmmm maybe between line 8 and 9

CCWeedcontrol
Occasional Contributor III

That is what i thought you meant but just making sure.

having nothing selected i still get the error

"Runtime error

Traceback (most recent call last):

  File "<string>", line 18, in <module>

NameError: name 'rows' is not defined"

import arcpy  
  
#populate selected feature  
APT = "TEST"  
fc1 = "CCAP"  
workspace = r"C:\GIS\CCAP\CCAP.mdb"  
arcpy.env.overwriteOutput = True  
mxd = arcpy.mapping.MapDocument("CURRENT")
rows = arcpy.UpdateCursor(APT)
for row in rows: 
    if int(arcpy.GetCount_management(APT).getOutput(0)) > 0:            
            row.FacltyType = ("Single Family Home")  
            row.StructType = ("Primary, Private")  
            row.Verified = ("Yes, GRM, TA")  
            row.Status = ("Active")  
            row.StructCat = ("Residential")  
            row.APA_CODE = ("1110")  
            rows.updateRow(row)  
            arcpy.Append_management(APT, fc1, "NO_TEST")  
            del row, rows  
     elif int(arcpy.GetCount_management(APT).getOutput(0)) == 0:  
         print "There are no features selected"  

Am i not doing something correct? Am i going about this the best way?

0 Kudos
DanPatterson_Retired
MVP Emeritus

​well line 20 is not right...rows gets deleted the first time throw the cursor... move that row completely outside of the for row in rows loop or comment it out for testing ie

# del row,rows

0 Kudos