Having trouble replaceDataSource loop

1169
9
05-18-2017 01:43 PM
RaleighMyers
New Contributor II

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, 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)

0 Kudos
9 Replies
JoshuaBixby
MVP Esteemed Contributor

You are looping over your shape files, assuming there are shape files to loop over, but you are not doing anything each shape file as you loop over them.  Looking at your replaceDataSource syntax, you are passing an empty string as the dataset_name.

0 Kudos
JimCousins
MVP Regular Contributor

A couple of things:

1) ListFeatureClasses requires some arguments ListFeatureClasses(wild_card, feature_type, feature_dataset), and you are not passing anything, so your shapefile list is empty.

2) As Joshua indicated, you are passing an empty string as the name. You need to alter to:

 for shape in shapelist:                      
...     lyr.replaceDataSource(r"\\path\Set1Test", "SHAPEFILE_WORKSPACE", shape)

Best Regards,

Jim

0 Kudos
IanMurray
Frequent Contributor

Technically all the arguments are optional so this would return something even with no arguments(see the example code in the help), as long as the workspace environment was valid and contained feature classes.

0 Kudos
JimCousins
MVP Regular Contributor

Point taken.

0 Kudos
DanPatterson_Retired
MVP Emeritus

ListFeatureClasses requires no parameters, in which case everything is returned... check the code example in the link

0 Kudos
RaleighMyers
New Contributor II

Yes, the ListFeatureClasses() returns a list. I have 11 of the shapefiles in a test directory. Here's what print shapelist returns after running the code:

[u'Set1_Plan1.shp', u'Set1_Plan10.shp', u'Set1_Plan11.shp', u'Set1_Plan2.shp', u'Set1_Plan3.shp', u'Set1_Plan4.shp', u'Set1_Plan5.shp', u'Set1_Plan6.shp', u'Set1_Plan7.shp', u'Set1_Plan8.shp', u'Set1_Plan9.shp']

0 Kudos
IanMurray
Frequent Contributor

That means when you use the placeholder variable shape in the loop, it should be the name of each of those shapefile in turn.

This is what you have:

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

This is what it should be(As Jim previously noted):

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

Also wouldn't hurt to refresh the active view after changing the source each time with arcpy.RefreshActiveView()

0 Kudos
RaleighMyers
New Contributor II
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, but I haven't been able to figure how to do that.
Per your suggestion, I added RefreshActiveView() after replaceDataSource and ran the code. It refreshed 10 times, but it's not replacing the data source with the next one. It keeps the first one each time and only prints out one pdf. (Or maybe two pdfs. It created one with an 11:05 timestamp, then the timestamp was 11:06)
0 Kudos
IanMurray
Frequent Contributor

Any more information on the error you are getting?  Are you sure you are creating the layer object for the correct layer in your map document?

Without more information its hard to know why exactly the script is failing.

Also see this thread and make sure relative paths are not on when replacing data sources

https://gis.stackexchange.com/questions/40549/replacing-layer-data-sources-using-replacedatasource-o...

0 Kudos