2

How do you output a list of multiple featurelayers from an mxd while controlling the output names of the shapefiles and overwriting the contents of the shapefile outputs if the the file already exists? Currently I'm using both the FeatureClasstoFeatureClass_conversion() and CopyFeatures_management() functions. I can get one featurelayer to output and overwrite a shapefile in a different location. But how to do this for a list of shapefiles?

import arcpy 
Mxd = arcpy.mapping.MapDocument("CURRENT")  
arcpy.mapping.ListLayers(Mxd)
arcpy.env.overwriteOutput = True  

sampleinputList = ["input_a", "input_b", "input_c"] #list of feature layers
sampleout_path = "T:/path" #output path 
samplenames = ["input_a_name", "input_b_name", "input_c_name"]
sampleOutputnamesList = ["T:/path/input_a_name", "T:/path/input_b_name", "T:/path/input_c_name"] # each input corresponds to a respective output name
for featureclasses in sampleinputList:
    arcpy.CopyFeatures_management(sampleinputList,sampleOutputnamesList)
    #neither of these list structures worked :/    
for featureclasses in sampleinputList:
    arcpy.FeatureClasstoFeatureClass_conversion(sampleinputList,sampleout_path,samplenames)

both instances give me a Runtime error Traceback (most recent call last): File "<string>", line 2, in <module> File "c:\program files (x86)\arcgis\desktop10.2\arcpy\arcpy\management.py", line 2281, in CopyFeatures raise e RuntimeError: Object: Error in executing tool

Here's the part of the code I think should be amended:

#Filename mapping Dictionary
fileNames = {
'unique layer namea' : 'unique_shapefile_renamedA',
'unique layer nameb' : 'unique_shapefile_renamedB',
'unique layer nameC' : 'unique_shapefile_renamedC',
}

outPath = "T:\\path" #path to folder where new shapefiles will be output

for featureclass in listLayers: #this loops through the arcpy function seen on last line
    if featureclass.name.lower() in fileNames:
        outputName = '{}.shp'.format(fileNames[featureclass.name.lower()]) 
        outputPath = os.path.join(outPath, outputName)
        arcpy.CopyFeatures_management(featureclass, outputPath)

if the original syntax of the Copy Features management function is CopyFeatures_management (in_features, out_feature_class,) then shouldn't featureclass in last line of the block be defined in the way outputPath is defined?

  • Please confirm your indentation after the if featureclass.name.lower() line, as currently it's incorrect – Midavalo Aug 17 '16 at 19:19
  • Changed @Midavalo – SteeleJohnson Aug 17 '16 at 20:42
  • 'shouldn't featureclass in last line of the block be defined in the way outputPath is defined?' - no, it is defined by for featureclass in listLayers:. featureclass here is your in_features that you're copying to your outputPath. – Midavalo Aug 17 '16 at 22:27
  • @Midavalo well in that case it didn't do anything. There were no errors but none of the shapefiles seemed to be updated/exported based on the dates I see. – SteeleJohnson Aug 18 '16 at 16:02
1

You need to get a list of your layers, and then loop through them, outputting them to your desired location. You currently are getting your layer list, but not storing that list in a parameter.

Below I've modified your script to loop through the layers and output them to a folder, giving each layer a new (or slightly modified) name. I've used both methods you've tried - you need to choose which on you prefer and remove the other.

import arcpy, os

arcpy.env.overwriteOutput = True  

mxd = arcpy.mapping.MapDocument("CURRENT") 
layerList = arcpy.mapping.ListLayers(mxd) # list of layers in MXD
outPath = r"D:\temp\SE\OutputFolder" #output path 

# Try this
for featureclass in layerList: # Using Copy Features
    outputName = '{}_cf_output.shp'.format(featureclass.name) # Creates a new output name
    outputPath = os.path.join(outPath, outputName)
    arcpy.CopyFeatures_management(featureclass, outputPath)

# Or try this
for featureclass in layerList: # Using Feature Class to Feature Class
    outputName = '{}_fc2fc_output.shp'.format(featureclass.name) # Creates a new output name
    arcpy.FeatureClassToFeatureClass_conversion(featureclass, outPath, outputName)

If you are wanting to completely rename each feature class name when you copy it (as per your comment), you will need to have a dictionary of old and new file names defined, rather than just outputting each layer it finds in the MXD. Doing it this way will miss any layers that you haven't defined in the dictionary.

import arcpy, os

arcpy.env.overwriteOutput = True  

mxd = arcpy.mapping.MapDocument("CURRENT") 
layerList = arcpy.mapping.ListLayers(mxd) # list of layers in MXD

# Dictionary of filename mapping
# {Old Filename: New Filename}
fileNames = {
             'input_a': 'input_a_name',
             'input_b': 'input_b_name',
             'input_c': 'input_c_name'
            }

outPath = r"D:\temp\SE\OutputFolder" #output path 

for featureclass in layerList: # Using Copy Features
    if featureclass.name.lower() in fileNames:
        outputName = '{}.shp'.format(fileNames[featureclass.name]) # Creates a new output name
        outputPath = os.path.join(outPath, outputName)
        arcpy.CopyFeatures_management(featureclass, outputPath)

The dictionary is set up with the old name (the layer name in your MXD), and the name you want it called once output to shapefile. Arcpy will loop through the layers in your MXD, and if they're listed in the dictionary it will copy the layer out to a shapefile using the new name in the dictionary.

Put your older filename/layer name in the dictionary in lowercase so that python can do a match by comparing the lowercase layer name (featureclass.name.lower()) - remember that Python is very case specific!

  • Hey @Midavalo, Thanks for this. How exactly does the outputName allow me to specify the name I'd like the output shapefiles to take on? I wouldn't want to try it without knowing how I can specify what each of the layers will be renamed to. Btw I chose to go with the CopyFeatures_managementoption because the FeatureClass_conversion doesn't duplicate all of the files that are made up within the shapefile. It outputs only 4 as opposed to 6 for some reason eg the .prj . shx etc – SteeleJohnson Aug 16 '16 at 18:00
  • @SteeleJohnson the line outputName = '{}_cf_output.shp'.format(featureclass.name) is what gives your output a new filename. If your input feature class is Abcde it will name your output Abcde_cf_output.shp. The {} is a placeholder in the string for the featureclass.name passed to it using the .format(), and the rest of the string _cf_output.shp is added to the end. – Midavalo Aug 16 '16 at 18:17
  • @SteeleJohnson you can of course change this to whatever you want the new output to be. The featureclass.name comes from the input feature class, and this helps ensure each output has a unique name. – Midavalo Aug 16 '16 at 18:19
  • I see. What if I already had set names for output files. For example a layer in a map named Verybigpark gets exported and renamed as something along the lines of vbPark and overwrites an existing shapefile called vbPark whereas a layer called TinyRiver gets called TnyRiv? Where each output name is different. Is that possible? – SteeleJohnson Aug 16 '16 at 18:34
  • @SteeleJohnson I have added extra code for if you want to pre-map your layers to new filenames. If you don't want to pre-map them, you can use the first code I gave, as that will output each layer with a different name based on the existing layer name plus any extra text you want to add. – Midavalo Aug 16 '16 at 23:17

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.