import arcpy, os path = r"H:\Plans\GIS Plans\2003" f = open('BrokenMXD2003.csv', 'w') f.write("Type, File Path, Layer, Broken Path" + "\n") for root, dirs, files in os.walk(path): for fileName in files: basename, extension = os.path.splitext(fileName) if extension == ".mxd": fullPath = os.path.join(root, fileName) mxd = arcpy.mapping.MapDocument(fullPath) brknMXD = arcpy.mapping.ListBrokenDataSources(mxd) for brknItem in brknMXD: lyrList = arcpy.mapping.ListLayers(mxd) f.write("MXD, " + fullPath + ", " + brknItem.name) if brknItem.supports("dataSource"): f.write(", " + brknItem.dataSource + "\n") else: f.write("\n") f.close() print "Script Completed"
import arcpy, os path = r"C:\Test" for root, dirs, files in os.walk(path): for fileName in files: basename, extension = os.path.splitext(fileName) if extension == ".mxd": fullPath = os.path.join(root, fileName) mxd = arcpy.mapping.MapDocument(fullPath) brknMXD = arcpy.mapping.ListBrokenDataSources(mxd) for brknItem in brknMXD: print "MXD: " +fileName if brknItem.supports("workspacePath"): source = brknItem.workspacePath print str(brknItem) + ": " + source else: print "Layer does not support source" print "Completed"
File "X:\Documents\Working Files\Broken Data Sources\ListBrokenMXD.py", line 11, in <module>
brknMXD = arcpy.mapping.ListBrokenDataSources(mxd)
File "D:\Program Files (x86)\ArcGIS\Desktop10.2\arcpy\arcpy\utils.py", line 181, in fn_
return fn(*args, **kw)
File "D:\Program Files (x86)\ArcGIS\Desktop10.2\arcpy\arcpy\mapping.py", line 1465, in ListBrokenDataSources
result = mixins.MapDocumentMixin(map_document_or_layer).listBrokenDataSources()
File "D:\Program Files (x86)\ArcGIS\Desktop10.2\arcpy\arcpy\arcobjects\mixins.py", line 832, in listBrokenDataSources
broken_sources = [l for l in self.layers if not l._arc_object.valid]
File "D:\Program Files (x86)\ArcGIS\Desktop10.2\arcpy\arcpy\arcobjects\mixins.py", line 683, in layers
for frame in reversed(self.dataFrames):
File "D:\Program Files (x86)\ArcGIS\Desktop10.2\arcpy\arcpy\arcobjects\mixins.py", line 695, in dataFrames
return map(convertArcObjectToPythonObject, self.pageLayout.dataFrames)
AttributeError: 'NoneType' object has no attribute 'dataFrames'
import arcpy, os path = r"H:\Plans\GIS Plans\2003" f = open('BrokenMXD2003.csv', 'w') f.write("Type, File Path, Layer, Broken Path" + "\n") for root, dirs, files in os.walk(path): for fileName in files: basename, extension = os.path.splitext(fileName) if extension == ".mxd": fullPath = os.path.join(root, fileName) mxd = arcpy.mapping.MapDocument(fullPath) arcpy.AddMessage(mxd) brknMXD = arcpy.mapping.ListBrokenDataSources(mxd) for brknItem in brknMXD: lyrList = arcpy.mapping.ListLayers(mxd) f.write("MXD, " + fullPath + ", " + brknItem.name) if brknItem.supports("dataSource"): f.write(", " + brknItem.dataSource + "\n") else: f.write("\n") f.close() print "Script Completed"
Hi Stacy, I added this one line but it seems to have had no effect. I'm not familiar with addMessage; should there have been a popup or something? You mentioned printing the mxd path but I don't see where the results of addMessage should be added to my csv file or printed in IDLE?
I've checked the .mxd's that aren't getting looped through; they open fine and seem to be "valid" so far as I can tell.
import arcpy, os path = r"H:\Plans\GIS Plans\2003" for root, dirs, files in os.walk(path): for fileName in files: basename, extension = os.path.splitext(fileName) if extension == ".mxd": fullPath = os.path.join(root, fileName) mxd = arcpy.mapping.MapDocument(fullPath) print mxd brknMXD = arcpy.mapping.ListBrokenDataSources(mxd) print "Script Completed"
import arcpy, os path = r"H:\Plans\GIS Plans\2003" for root, dirs, files in os.walk(path): for fileName in files: basename, extension = os.path.splitext(fileName) if extension == ".mxd": fullPath = os.path.join(root, fileName) mxd = arcpy.mapping.MapDocument(fullPath) print mxd brknMXD = arcpy.mapping.ListBrokenDataSources(mxd) for brknItem in brknMXD: print brknItem.name print "Script Completed"
Hi Lauren, thanks for your answer. I'm actually successful at creating and populating the csv file, it just hangs up near the end of cycling through all the mxd's and doesn't finish the job. It puts out a csv file just fine, with the majority of the broken links listed, it just doesn't make it through every mxd in the folder and I'm not sure what the error I'm being given means.
I notice you used "workspacePath" rather than "dataSource". I tested out your code in IDLE and it seems to be providing the same information as dataSource. I changed dataSource to workspacePath in my code and tested that out. Both using your code as a straight copy and paste into IDLE, and changing dataSource to workspacePath in my own code, I'm getting the exact same error as I have been. Oddly, it does NOT stop at the same .mxd in both scenarios.
Any clues out there???
Hello i have been struggling through the same problem as you i have an H: that has been moved around so much that i need to find all mxd's with broken data. i will then look to how efficiently it is to resource the data or if the map is to old and i cant find the sourcing to do something else.
can you or do you mind sharing your final working code?
Hi lela, I haven't looked at this in a long time but I do think it was working. I never made it to actually replacing the broken data sources as other things took priority but this should at least list which items have broken sources. I have two different scripts depending on data source type and never got to combining them but here they are. Should be pretty simple to add the table views one in if it's needed. I think it was hanging up before I put the test in to see if the data type is able to return a dataSource value, after I did that it worked fine.
List Broken .mxd and .lyr sources:
import arcpy, os #Update the following path with the folder you want to inspect path = r"H:\Plans\GIS Plans\2004\G2004-045" #Update the .csv file name below f = open('2004_Test.csv', 'w') f.write("Type, File Path, Layer, Broken Path" + "\n") for root, dirs, files in os.walk(path): for fileName in files: basename, extension = os.path.splitext(fileName) #Write the information for all .mxd's with broken data sources if extension == ".mxd": fullPath = os.path.join(root, fileName) mxd = arcpy.mapping.MapDocument(fullPath) brknMXD = arcpy.mapping.ListBrokenDataSources(mxd) for brknItem in brknMXD: f.write("MXD, " + fullPath + ", " + brknItem.name) #Test to see if the data type is able to return a dataSource value if brknItem.supports("dataSource"): f.write(", " + brknItem.dataSource + "\n") else: f.write("\n") #Write the information for all .lyr's with broken data sources elif extension == ".lyr": fullPath = os.path.join(root, fileName) lyr = arcpy.mapping.Layer(fullPath) brknLYR = arcpy.mapping.ListBrokenDataSources(lyr) for brknItem in brknLYR: f.write("LYR, " + fullPath + ", " + brknItem.name) #Test to see if the data type is able to return a dataSource value if brknItem.supports("dataSource"): f.write(", " + brknItem.dataSource + "\n") else: f.write("\n") f.close() print "Script Completed"
List broken table views:
import arcpy, os #Update the following path with the folder you want to inspect path = r"H:\Plans\GIS Plans\2004\G2004-045" #Update the .csv file name below f = open('2004_TestTableView.csv', 'w') f.write("Type, File Path, Layer, Broken Path" + "\n") for root, dirs, files in os.walk(path): for fileName in files: basename, extension = os.path.splitext(fileName) #Write the information for all .mxd's with broken data sources if extension == ".mxd": fullPath = os.path.join(root, fileName) mxd = arcpy.mapping.MapDocument(fullPath) brknMXD = arcpy.mapping.ListBrokenDataSources(mxd) for brknItem in brknMXD: if extension ==".dbf": f.write("MXD, " + fullPath + ", " + brknItem.name + ", " + brknItem.dataSource + "\n") f.close() print "Script Completed"