I want to batch replace paths in a series of .mxd
files using Python. Many of the layers have moved and in some cases the name has changed or its dataset is different.
I've written this code which takes an Excel file with two columns (one column for the old path and one column for the new path) and converts to a dictionary. Then I iterate through the layers in my .mxd
files, and iterate through the dictionary, using replaceDataSource
to change the data sources.
The trouble is this won't work with annotation feature classes. I've added in a try/except with findAndReplaceWorkspacePath
to see if that may work (I don't believe the annotation layers/names have changed), but the code still doesn't address those layers.
One thing to note is that the annotation feature classes are stored in a personal geodatabase, but I don't know if this could be causing any issues.
I am hoping someone has ideas on code that will work to change the path of the annotation feature classses!
Here is my code:
import xlrd, arcpy, os
mxd_path = r'C:\temp\Chapters'
d = {}
wb = xlrd.open_workbook('U:\GIS\Chevron_Lokern\Projects\Figures_Update_2014\Lokern_Source_Paths_KL.xls')
sh = wb.sheet_by_index(0)
for i in range(293):
cell_value_class = sh.cell(i,0).value
cell_value_id = sh.cell(i,1).value
d[cell_value_class] = cell_value_id
for dirpath, dirnames, filenames in os.walk(mxd_path):
for filename in filenames:
fullPath = os.path.join(dirpath, filename)
if filename[-4:] == ".mxd":
mxd = arcpy.mapping.MapDocument(fullPath)
print filename
for lyr in arcpy.mapping.ListLayers(mxd):
if lyr.supports("DATASOURCE"):
#print lyr.datasetName
for k,v in d.iteritems():
#print k,v
k_path, k_name = os.path.split(k)
v_path, v_name = os.path.split(v)
if lyr.dataSource == k and k != v:
#print 'KEY:',k,'VAL:',v, 'NAME:',v_name
try:
print 'trying to change data source for',lyr.dataSource
lyr.replaceDataSource(v_path,'FILEGDB_WORKSPACE',v_name,True)
except Exception as e:
print 'can\'t replace',lyr.dataSource, e
try:
print 'trying to change data source for',lyr.dataSource
lyr.replaceDataSource(v_path,'RASTER_WORKSPACE',v_name,True)
except Exception as e:
print 'still can\'t replace',lyr.dataSource, e
try:
print 'trying to change data source for',lyr.dataSource
lyr.replaceDataSource(v_path,'SHAPEFILE_WORKSPACE',v_name,True)
except Exception as e:
print 'still can\'t replace',lyr.dataSource, e
try:
print 'trying to change data source for',lyr.dataSource
lyr.findAndReplaceWorkspacePath(k_path,v_path)
except Exception as e:
print 'can\'t replace workspace path for',lyr.datasetName, e
mxd.relativePaths = 'True'
mxd.save()
del mxd