1

In ArcGIS (using 10.4) I have my layout set up, shapefile A symbolized and labeled. What I need to do is print this layout to pdf, then change the source of shapefile A to the next in a series of several hundred, have it look the same, change the title, and print the pdf. I'm trying to loop through each shapefile in a folder. The shapefiles are polygon. The legend stays the same because each shapefile has the same number of polygons, symbolized the same way. The labels should stay the same, but move as the polygons they label change shape and position. The extent is constant. This is easy to do interactively in ArcGIS: go into the Layer Properties, Source tab, Set Data Source... In trying to do this in Python, I'm having difficulty. My code maybe isn't looping. It prints one map. I think the replaceDataSource {dataset_name} needs to be a variable (the ""), but I can't figure how to do that.

>>> import arcpy  
... import os  
... mxd = arcpy.mapping.MapDocument("CURRENT")   
... df = arcpy.mapping.ListDataFrames(mxd, "*")[0]    
... lyr = arcpy.mapping.ListLayers(mxd, "*", df)[3]             
... output_dir = r"\\path\PDFs"   
... arcpy.env.workspace = r"\\path\Set1Test"
... shapelist = arcpy.ListFeatureClasses()       
... for shape in shapelist:                      
...     lyr.replaceDataSource(r"\\path\Set1Test", "SHAPEFILE_WORKSPACE", "")
...     TextElement = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "MapTitleText")[0]  
...     TextElement.text = lyr.datasetName                                     
...     arcpy.mapping.ExportToPDF(mxd, r"\\path\PDFs\Map " + lyr.datasetName)

I've also tried this, with the same result:

>>> import arcpy
... import os
... mxd = arcpy.mapping.MapDocument("CURRENT")
... df = arcpy.mapping.ListDataFrames(mxd, "*")[0]
... lyr = arcpy.mapping.ListLayers(mxd, "*", df)[3]
... output_dir = r"\\path\PDFs"
... for file in os.listdir(r"\\path\Set1\Set1Test"):
...     if file.startswith ("Set"):
...             lyr.replaceDataSource(r"\\path\Set1\Set1Test", "SHAPEFILE_WORKSPACE", "")
... TextElement = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "MapTitleText")[0]
... TextElement.text = lyr.datasetName 
... arcpy.mapping.ExportToPDF(mxd, r"\\path\PDFs\Map " + lyr.datasetName)
1

replaceDataSource (workspace_path, workspace_type, {dataset_name}, {validate})

The curly brackets indicate the parameter is optional.

If you are changing the workspace (different geodatabase for example) but the feature class name is not changed, you don't need to specify a dataset_name value.

lyr.replaceDataSource(r"\\path\Set1\Set1Test", "SHAPEFILE_WORKSPACE", "")

If you are updating to a feature class with a different name than the original, you need to specify the dataset name

lyr.replaceDataSource(r"\\path\Set1\Set1Test", "SHAPEFILE_WORKSPACE", "NameOfNewFeatureClass")

For more info see Updating and fixing data sources with arcpy.mapping and Layer - Methods.

dataset_name = A string that represents the name of the dataset the way it appears in the new workspace (not the name of the layer in the TOC). If dataset_name is not provided, the replaceDataSource method will attempt to replace the dataset by finding a table with a the same name as the layer's current dataset property.

Since you are wanting to replace one shapefile with another, you possibly just need to use the shape variable from your loop to update from one to the next, however I haven't had a chance to test this:

lyr.replaceDataSource(r"\\path\Set1\Set1Test", "SHAPEFILE_WORKSPACE", shape)

I have now tested, in response to your comment about the "Unexpected Error". The reason you get this error is because you have .shp extension on your shapefile names, and the lyr.replaceDataSource() wants just the shapefile name, not the extension. You can remove the extension before passing the filename to the function:

shapelist = arcpy.ListFeatureClasses()       
for shape in shapelist:
    shapename = os.path.splitext(shape)[0]
    lyr.replaceDataSource(r"\\path\Set1Test", "SHAPEFILE_WORKSPACE", shapename)
  • Yes! I have tried lyr.replaceDataSource(r"\\path\Set1\Set1Test", "SHAPEFILE_WORKSPACE", shape) . It produces an "Unexpected error." I think the dataset name needs to be a variable, maybe, but I haven't been able to figure how to do that. – R_exists May 19 '17 at 14:48
  • @R_exists I have updated my answer - you need to exclude .shp from the shapefile name variable when using with replaceDataSource(). See the update in my answer. – Midavalo May 19 '17 at 20:18
  • Excluding .shp from the shapefile name variable is indeed the answer. Thank you very much for the help! – R_exists May 22 '17 at 15:18

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.