Improve my script so it toggle on/off layers after updating them

04-14-2016 01:40 PM
New Contributor III


The following script works perfectly to update all mxds contained in one folder using a unique .lyr file as a reference to all layers (in groups and subgroups). All mxds have the same TOC composition, but the visibility of each layer depend of the mxd. My problem is that when I run the "update script", the .lyr file apply his parameter to the layers so it turns them OFF. The .lyr file contains only OFF layers because, as I said, the visibility of every layer is different in each map project. 

So I would love to find a way to integrate a few more lines of code in the script so it would list the layers visibility parameter (for every layers in the mxd), then do the update, finally toggle back ON the layers that were ON initially using the list.

I found something, but I can't find a way to integrate it in the "update script" (​).

Here the "update script":

import arcpy
import os

MxdFolderPath = arcpy.GetParameterAsText(0)
if MxdFolderPath == '#' or not MxdFolderPath:
    MxdFolderPath = "//"
MxdCount = 0

sourcelypath = arcpy.GetParameterAsText(1)
if sourcelypath == '#' or not sourcelypath:
    sourcelypath = "// .lyr/Autres formats/Couches.lyr"  # reference .lyr file
sourcely = arcpy.mapping.Layer(sourcelypath)

arcpy.env.workspace = MxdFolderPath
arcpy.AddMessage("   MXD PROCESSING")
mxdList = arcpy.ListFiles("*.mxd")
Mxdlen = len(mxdList)
if Mxdlen == 0:
    arcpy.AddMessage("   There are no mxd in: " + str(MxdFolderPath))
    arcpy.AddMessage("   There are " + str(Mxdlen) + " mxd in: " + str(MxdFolderPath))

    for mxd in mxdList:
        MxdCount = (MxdCount + 1)
        MxdPPath = os.path.join(MxdFolderPath, mxd)
        processingmxd = arcpy.mapping.MapDocument(MxdPPath)
        arcpy.AddMessage(" Mxd: " + str(MxdCount) + " :" + str(mxd))
        dflist = arcpy.mapping.ListDataFrames(processingmxd, "Couches_DF")  # Dataframe
        for df in dflist:
            arcpy.AddMessage(" df: " + str(
            layers = arcpy.mapping.ListLayers(processingmxd, "Couches", df)  # layers called Couches
            for layer in layers:
                arcpy.AddMessage("      Layer: " + str(layer))
                arcpy.mapping.UpdateLayer(df, layer, sourcely, False)
                arcpy.AddMessage("      Layer Updated")
        arcpy.AddMessage(" ")
arcpy.AddMessage(" End")

Can anyone help? Thanks in advance!

0 Kudos
9 Replies
MVP Honored Contributor

I think you should be able to do something like the following inside your loop:

orig_vis = layer.visible # either True or False
arcpy.mapping.UpdateLayer(df, layer, sourcely, False) # update layer
layer.visible = orig_vis # set visibility
New Contributor III

Gave it a try, but it didn't work... The good side: there's is no error message.

0 Kudos
MVP Esteemed Contributor

hmmm maybe the mxd needs a refresh Refreshing Data Driven Pages—Help | ArcGIS for Desktop

thinkin example 2 here MapDocument—Help | ArcGIS for Desktop


0 Kudos
New Contributor III

Do you have to refresh if the mxd's aren't open?

0 Kudos
MVP Esteemed Contributor

Darren is correct since layer.visible is a read and write property Layer—Help | ArcGIS for Desktop

As a matter of reference... bookmark this link for the whole of arcpy What is ArcPy?—Help | ArcGIS for Desktop

Esteemed Contributor

What version of ArcGIS for Desktop are you working with?  Just a theory that this might have something to do with the layer.visible property not working as expected.

0 Kudos
New Contributor III

It is 10.3.1 (basic license)

0 Kudos
Esteemed Contributor

How about having 2 different lyr files, 1 with the layer visible and the other with the layer not visible.  Then when you check the current visibility of the layer in the mxd this determines which lyr file to use.  This could alleviate the current problem you are having if the map cannot be refreshed.

0 Kudos
New Contributor III

I don't think the current problem is to refresh, the script loops through a folder to apply it to every mxd. But your idea isn't bad, I would have to create a .lyr for each mxd then add some lines to the script to use this new .lyr only to set visibility... Now I have to find how to do it!

0 Kudos