0

I am trying to remove layers from the TOC using Python Toolbox. It works provided that the layer names have no spaces in their names. Tho whole script looks like:

class LayerprocessingRemoveUntickedLayers(object):
    def __init__(self):
        """Define the tool (tool name is the name of the class)."""
        self.label = "Remove unticked layers"
        self.description = "Removes unticked layers."
        self.canRunInBackground = False

    def getParameterInfo(self):
        """Define parameter definitions"""
        param0 = parameter("toclayers", "Unticked layers", "GPString", "Optional", multiValue=True)

        params = [param0]
        return params

    def updateParameters(self, parameters):
        unticked_set = set()
        mxd = arcpy.mapping.MapDocument("CURRENT")
        df = arcpy.mapping.ListDataFrames(mxd)[0]
        for lyr in arcpy.mapping.ListLayers(mxd, "", df):
            if not lyr.visible:
                unticked_set.add(lyr.longName)
            del lyr

        parameters[0].filter.list = sorted(list(unticked_set))
        return

    def execute(self, parameters, messages):
        toclayers = parameters[0].valueAsText.split(";")  # ??? Here is my problem

        arcpy.AddMessage("\nTicked layers:")
        for t in toclayers:
            arcpy.AddMessage("... " + t)

        arcpy.AddMessage("\nRemoving chosen layers... ")
        mxd = arcpy.mapping.MapDocument("CURRENT")
        df = arcpy.mapping.ListDataFrames(mxd)[0]
        for lyr in arcpy.mapping.ListLayers(mxd, "", df):
            if not lyr.visible and lyr.longName in toclayers:
                arcpy.AddMessage("... " + lyr.longName)
                arcpy.mapping.RemoveLayer(df, lyr)
        return

Step 1: updateParameters function reads layers and gives me layers´ names.

tool dialog

Step 2: I tick layers I want to remove (it does no matter whether they are broken or not). There is no group layer.

Step 3: the script removes only those chosen layers that have no spaces in their names (in this case PP_N_eroze_SUp and PP_N_eroze_SUt). Obviously because layers with spaces in their names get quotes to their values.

tool messaging

Mr. Che commented that layers with spaces in their names get quotes when passed from tool dialog to script executing. And now I remember that I asked a question with the same problem some time ago as Multivalue input from chosen field giving patchy input strings from ArcPy?

The problem was in arcpy.GetParameterAsText(0), the solution was changing it to arcpy.GetParameter(0) and splitting its strings with ";" as Hornbydd suggested a long time ago.

It worked when the tool was within an ordinary toolbox. Now I have this tool in the Python toolbox but changing parameters[0].valueAsText.split(";") to str(parameters[0].value).split(";") is not working. How to get values (this is to say split values from parameters[0]) correctly?

  • 1
    Check your layer names and list of layers by printing them. Update your answer so we could see these printed values. – Mr. Che Jul 17 '18 at 12:56
  • 1
    longName returns the full grouplayer path structure, are some of your layers group layers or sit within a group layer, this would explain why they are not removed when you search in your toclayers list. – Hornbydd Jul 17 '18 at 14:05
  • I updated the question and added tool´s messages. None of the layers are a group layer. – jonlew Jul 18 '18 at 8:58
0

After trying and checking errors I know now that ticked values are stored in a ValueTable object. So I created a list with values from this ValueTable and all of these values are now strings.

def execute(self, parameters, messages):
    toclayers = parameters[0].value  # gives a ValueTable

    # Loop through the ValueTable and fill the list of values
    toclayers_list = []
    for i in xrange(0, toclayers.rowCount):
        toclayers_list.append(toclayers.getValue(i, 0))

    arcpy.AddMessage("\nTicked layers:")
    for t in toclayers_list:
        arcpy.AddMessage("... " + t)

    arcpy.AddMessage("\nRemoving chosen layers... ")
    mxd = arcpy.mapping.MapDocument("CURRENT")
    df = arcpy.mapping.ListDataFrames(mxd)[0]
    for lyr in arcpy.mapping.ListLayers(mxd, "", df):
        if not lyr.visible and lyr.longName in toclayers_list:
            arcpy.AddMessage("... " + lyr.longName)
            arcpy.mapping.RemoveLayer(df, lyr)

Tool messages:

enter image description here

Now it works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.