Removing a layer from multiple mxds

957
3
Jump to solution
03-14-2013 04:11 PM
KenLucas
Occasional Contributor
I attempted to modify a sample code to remove just one layer from one of the two data frames, "Primary", I have in multiple mxds, all stored in the same folder.  This code runs, but does not actually remove the layer, "Dams", from the two text mxds, stored in the folder, RemoveLayers1.  I've specified upper, considering Dams starts with a cap D, but maybe it requires a diff command when caps are mixed with lower case.
I'm hoping someone can see what I'm missing. I would expect the code to provide an error message; not just fail to remove the layer.

import arcpy import os import glob mxds_path = r'C:\\Temp\\removelayers1\\' layer_name = r'Dams' data_frame = r'Primary' layers = [] mxds = []   for infile in glob.glob(os.path.join( mxds_path, "*.mxd" )):   mxd = arcpy.mapping.MapDocument(infile)   print "removing Dams layer from "  + infile   for df in arcpy.mapping.ListDataFrames(mxd, data_frame):     for lyr in arcpy.mapping.ListLayers(mxd, "", df):       #print lyr       if lyr.name.upper() == layer_name:         print 'Remove layer ' + layer_name         arcpy.mapping.RemoveLayer(df, lyr)         #for mxd_name in mxds:   #mxd = arcpy.mapping.MapDocument(mxds_path + mxd_name)   #print 'removing layer for ' + mxd_name    #  mxd.save()


Ken
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
T__WayneWhitley
Frequent Contributor
Hello Ken,
I think the main problem here is the expectation of what you'd get with the functions upper/lower.  So I'll demonstrate with IDLE:
>>> someText = 'IamAlayer' >>> print someText.upper() IAMALAYER >>> print someText.lower() iamalayer >>> 


As you can see, the function 'lower' returns all lower case; the function 'upper' returns all upper case.  It is that cut and dried.
So the only way your 'if' statement to be true as you need it to be to execute the 'removeLayer' part of the code, you at least need to feed in the proper conditional variables...

So you could go with 'lower' as you had the code originally - which for the layer in question would return 'dams' (if there is such a layer in the map's data frame), so you'd need to set the 'layer_name' variable to the following (not with the 1st letter capitalized):

layer_name = r'dams'


extra clarification:
As further explanation by example, it doesn't matter whether you use 'upper' or 'lower', you cannot use mixed case on the variable 'layer_name'....you should define it as either 'dams' (lower) or 'DAMS' (upper) as shown:
>>> if layer_name.lower() == 'dams':  print 'yes, we have a match - go ahead with the rest code block.'    yes, we have a match - go ahead with the rest code block. >>> if layer_name.upper() == 'DAMS':  print 'yes, we have a match - again, proceed...'    yes, we have a match - again, proceed... >>> if layer_name.lower() == 'Dams':  print 'go go go proceed with the code block...' else:  print 'no way....we do not agree - halt this block!'    no way....we do not agree - halt this block! >>>  >>> if layer_name.upper() == 'Dams':  print 'go go go proceed with the code block...' else:  print 'no way....we do not agree - halt this block!'    no way....we do not agree - halt this block! >>> 


At any rate, on your 'if' statement, the condition lyr.name.upper() == r'DAMS' [or lyr.name.lower() == r'dams'] must be met for 'arcpy.mapping.RemoveLayer(df, lyr)' to execute...

If you have any questions about that, let me know.  Also, you will need to save the mxd (whether you use 'mxd.save()' or 'mxd.saveACopy(...)', it doesn't matter, you must save the mxd for any changes to persist.


Enjoy,
Wayne

View solution in original post

0 Kudos
3 Replies
T__WayneWhitley
Frequent Contributor
Hello Ken,
I think the main problem here is the expectation of what you'd get with the functions upper/lower.  So I'll demonstrate with IDLE:
>>> someText = 'IamAlayer' >>> print someText.upper() IAMALAYER >>> print someText.lower() iamalayer >>> 


As you can see, the function 'lower' returns all lower case; the function 'upper' returns all upper case.  It is that cut and dried.
So the only way your 'if' statement to be true as you need it to be to execute the 'removeLayer' part of the code, you at least need to feed in the proper conditional variables...

So you could go with 'lower' as you had the code originally - which for the layer in question would return 'dams' (if there is such a layer in the map's data frame), so you'd need to set the 'layer_name' variable to the following (not with the 1st letter capitalized):

layer_name = r'dams'


extra clarification:
As further explanation by example, it doesn't matter whether you use 'upper' or 'lower', you cannot use mixed case on the variable 'layer_name'....you should define it as either 'dams' (lower) or 'DAMS' (upper) as shown:
>>> if layer_name.lower() == 'dams':  print 'yes, we have a match - go ahead with the rest code block.'    yes, we have a match - go ahead with the rest code block. >>> if layer_name.upper() == 'DAMS':  print 'yes, we have a match - again, proceed...'    yes, we have a match - again, proceed... >>> if layer_name.lower() == 'Dams':  print 'go go go proceed with the code block...' else:  print 'no way....we do not agree - halt this block!'    no way....we do not agree - halt this block! >>>  >>> if layer_name.upper() == 'Dams':  print 'go go go proceed with the code block...' else:  print 'no way....we do not agree - halt this block!'    no way....we do not agree - halt this block! >>> 


At any rate, on your 'if' statement, the condition lyr.name.upper() == r'DAMS' [or lyr.name.lower() == r'dams'] must be met for 'arcpy.mapping.RemoveLayer(df, lyr)' to execute...

If you have any questions about that, let me know.  Also, you will need to save the mxd (whether you use 'mxd.save()' or 'mxd.saveACopy(...)', it doesn't matter, you must save the mxd for any changes to persist.


Enjoy,
Wayne
0 Kudos
T__WayneWhitley
Frequent Contributor
import arcpy, os, glob
mxds_path = r'C:\Temp\removelayers1'
layer_name = 'DAMS'

for infile in glob.glob(os.path.join( mxds_path, "*.mxd")):
  mxd = arcpy.mapping.MapDocument(infile)
  for df in arcpy.mapping.ListDataFrames(mxd, ""):
    for lyr in arcpy.mapping.ListLayers(mxd, "", df):
      if lyr.name.upper() == layer_name:
        arcpy.mapping.RemoveLayer(df, lyr)
mxd.save()


...simple as that, I would think works -- check it and see (I have not tested it).
0 Kudos
KenLucas
Occasional Contributor
Wayne,
  Incredible. I followed your advice to make the case all the same and determined that a one letter change in the code, replacing the cap D, in the Dams variable of line 5 of my original script, solved the problem. Not only was the Dams layer removed, but it removed the layer, as spelled "Dams" in the mxds. In other words I didn't have to change to all one case for the 100 mxds that have the Dams layer. It was not necessary to run my original script in the same folder as the multiple mxds. So, that original script will remove any layer, specified in the line 5, as long as the name in the code is all lower case. Incredible how quick you spotted that problem in our code!  Thanks so much.
Ken
0 Kudos