Copy attribute table fields from one shapefile to another

17484
13
Jump to solution
09-09-2015 01:04 PM
KeithAddison1
Occasional Contributor III

I have about 20 shapefiles that all need to have the same attribute table fields.  I have the attribute table fields all setup the way I want for one of the shapefiles.  I want to copy this attribute table setup over to the other shapefiles.  The entries of the tables are all empty for now, I just want to use the same columns/fields for all the shapefiles.  How can I copy the attribute table into the remaining shapefiles?  Using ArcInfo 10.0

0 Kudos
1 Solution

Accepted Solutions
IanMurray
Frequent Contributor

If you are comfortable with python, you could make a list of all the fields of the one (template) shapefile you have set-up, then loop through each other shapefile and add a field for each field that exists in the template shapefile.

If this is the way you want to go about it and you need help with this, I can get you some code to use to manage this process.

View solution in original post

13 Replies
WesMiller
Regular Contributor III

Do you have a common field that you can use to to join the two feature classes or are you going to need to do a spatial join to link the data?

0 Kudos
KeithAddison1
Occasional Contributor III

The only field they all have in common is SHAPE (all polygons), can I use that for a join?

0 Kudos
WesMiller
Regular Contributor III

If you use a spatial join the fields from both feature classes would be present in a new feature class, but i don't think that will do what you are after. i miss read your question sorry. I would suggest using model builder set it up for each of  the fields you want to add on one feature class and let it run then change the feature class to another and run it again until you get all 20

0 Kudos
IanMurray
Frequent Contributor

If you are comfortable with python, you could make a list of all the fields of the one (template) shapefile you have set-up, then loop through each other shapefile and add a field for each field that exists in the template shapefile.

If this is the way you want to go about it and you need help with this, I can get you some code to use to manage this process.

KeithAddison1
Occasional Contributor III

I figured out a workaround by merging all the shapefiles together then setting up the attribute table & breaking each feature back out into its individual shapefile.  Not ideal but takes less time than entering each field for all 20 shapefiles.  Can't believe I didn't think of that sooner, I guess that's because I assumed there would be an easy way to copy/paste attribute table templates.

I am learning Python so I would be interested in seeing code to do this for some arbitrary field names, say: A, B & C.  It could also come in handy if I run into this situation again for a great many shapefiles and I can't come up with a workaround.

0 Kudos
IanMurray
Frequent Contributor

This is far from an ideal solution, since I am uncomfortable with dictionaries, I make a list of lists that contain the attributes for existings fields using the arcpy module.  In the below example, your "template" shapefile needs to be in a seperate directory from the rest, since this script does not check to see if a field already exists.  If your other shapefiles were in multiple directories or subdirectories, we would need to use the os module walk function, or arcpy.da.Walk to create the list of shapes.

I do not have data to test on at the moment, so this is untested and I can't show the output.

#importing Modules
import arcpy
#Creating variable for template file path
template_shp = "FilePathtoShp"
#Making a list of Field Objects
fields = arcpy.ListFields(template_shp)
#Creating empty list to append field attribute list to
allfields = []
#Looping through field objects
for field in fields:
    #Creating empty list to append field attributes to
    field_attributes = []
    #Appending all relevant field object elements as strings to list
    field_attributes.append(field.name , field.type , field.precision , field.scale, field.length, field.aliasName , field.isNullable , field.required)
    #Appending list of field elements to new field list
    allfields.append(field_attributes)
#Setting workspace
arcpy.env.workspace = "directoryofshapefiles"
#Creating List of FeatureClasses in workspace
shapes = arcpy.ListFeatureClasses()
#Looping through each shape
for shape in shapes:
    #Looping through each field 
    for field in allfields:
        #Adding field based on field attributes of original field
        arcpy.AddField_management(shape , field[0] , field[1] , field[2], field[3], field[4] , field[5], field[6] , field[7])

I'm sure someone more proficient with python could show a better way.

0 Kudos
DarrenWiens2
MVP Honored Contributor

For what it's worth, running the built-in feature class level tools (Copy, then Append) seems to work about twice as fast as adding fields individually. See below where Test A uses feature class level tools and Test B uses field level tools (I believe these are comparing apples to apples, but I could be wrong). For small feature classes, the differences are pretty small, but for large datasets, the time difference could be considerable. I'd say the code is somewhat simpler, as well.

import arcpy, time

# Set up shared conditions
arcpy.env.workspace = r'C:\junk\new_fields'
arcpy.env.overwriteOutput = True
template = 'template.shp' # the template FC
fcs = arcpy.ListFeatureClasses('*Copy*') # the "other" FCs

#############################################

# Test A
starttime1 = time.time()

outCounter = 1
for fc in fcs:
    newCopy = "output_" + str(outCounter) + '.shp'
    arcpy.Copy_management(template, newCopy)
    arcpy.Append_management(fc, newCopy, 'NO_TEST')
    outCounter += 1

endtime1 = time.time() - starttime1
print 'Total time: ' + str(endtime1) +'s' # about 3.5 seconds

############################################

# Test B
starttime2 = time.time()

fields = arcpy.ListFields(template)
allfields = []
for field in fields:
    if field.name != 'FID' and field.name != 'Shape':
        allfields.append([field.name , field.type , field.precision , field.scale, field.length, field.aliasName , field.isNullable , field.required])
for shape in fcs:
    for field in allfields:
        arcpy.AddField_management(shape , field[0] , field[1] , field[2], field[3], field[4] , field[5], field[6] , field[7])

endtime2 = time.time() - starttime2
print 'Total time: ' + str(endtime2) +'s' # about 7 seconds
0 Kudos
KeithAddison1
Occasional Contributor III

What exactly does the Test A code output to?  I put in the template shapefile and workspace path I want to use in place of template.shp, and add print newCopy to the end and it tells me newCopy is not defined, there's no new shapefile in the workspace, or anywhere else on the C drive.  The rest of the code runs fine, I just can figure out where its sending the results.

0 Kudos
DarrenWiens2
MVP Honored Contributor

For me, it output new files to:

C:\junk\new_fields\output_1.shp

C:\junk\new_fields\output_2.shp

C:\junk\new_fields\output_3.shp

C:\junk\new_fields\output_4.shp

C:\junk\new_fields\output_5.shp

0 Kudos