I enabled multiple value input for some parameter in an ArcMap 10.8 Python Toolbox.
In my script, I can easily split the input received from the UI by applying .split(";") since the input values are separated by ";".
However, when the user selects a layer from the drop-down that is located within a group, each such value consists of the group name and the layer name, separated by "\". The problem: "\" is an escape character in Python. I cannot separate the layer name from the group name. I need the layer name, though, because I want to search the .mdx document for that name in order to get the full path to the layer on disc.
Is there some way to solve this?
I tried:
combined_name.split("\\")
combined_name.split(r"\\")
r"{0}".format(combined_name).split("\\")
where combined_name is the respective name extracted from the input variable. All these attempts were without success.
Edit: I tried the arcpy.GetParameter(0) suggestion with no success. This is the Toolbox I used to test it:
import arcpy as ap
# Toolbox
class Toolbox(object):
def __init__(self):
self.label = "Tool"
self.alias = "Tool"
# List of tool classes associated with this toolbox
self.tools = [Tool]
class Tool(object):
def __init__(self):
self.label = "Tool"
self.description = "Test GetParameter(0)."
self.canRunInBackground = False
def getParameterInfo(self):
"""Define parameter definitions"""
in_raster = ap.Parameter(
displayName = "Input Raster",
name = "Raster",
datatype = ["GPRasterLayer", "DERasterDataset"],
parameterType = "Required",
direction = "Input",
multiValue = True)
params = [in_raster]
return params
def isLicensed(self):
"""Set whether tool is licensed to execute."""
return True
def updateParameters(self, params):
return
def updateMessages(self, params):
return
def execute(self, params, messages):
rasters = ap.GetParameter(0)
if rasters is None:
ap.AddMessage("Parameter is of type None.")
else:
ap.AddMessage("Parameter is something other then None.")
return
When I open the Tool dialogue and add some rasters to the list, I get the "Parameter is oy type None" message after running the tool.
Solved! Go to Solution.
I found some solution (here, I added a condition to check whether the input is some file path that I don't want to mess up. The tool accepts selecting loaded layers from a drop-down as well as browsing files):
def replace_grouped(in_var):
if not os.path.isfile(in_var):
out = repr(in_var).strip("'").split("\\")[-1]
else:
out = in_var
return out
or, in practice: Since somehow the ending \'" was introduced to some input variables but not others, I had to do the following
def replace_grouped(in_var):
if not os.path.isfile(in_var):
out = repr(in_var).strip("'").strip('"').strip("'").strip('"') \
.split("\\")[-1]
else:
out = in_var
return out
(very ugly, but I haven't found a better way to get rid of the trailing garbage yet.)
Instead of grabbing the input as text, you could grab the item itself using:
arcpy.GetParameter()
Then use a for loop to access the layer properties
e.g.:
layernames = arcpy.GetParameter(0)
for l in layernames:
arcpy.AddMessage(l.name)
Unfortunately, arcpy.GetParameter(0) returns "None" for my ArcMap MultiValue input parameter... I guess this only works in ArcGIS Pro.
This should work in ArcMap also. What Data Type do you have your multivalue input as? I've tried it with the option set to Layer and it works
I have some ["GPRasterLayer", "DERasterDataset"] datatype
So it would work with raster layers, but not with a raster dataset, as that can't have a "Layer Name" property anyway. It only has layer properties once it is inside of an MXD or your have cast it as a feature layer, but if that hasn't happened/isn't the case then you wouldn't have the issue with it being part of a group layer anyway, so perhaps you could code around that e.g. an if statement based on feature type then a for loop to access layer name for those inputs that support it.
split() returns a list so you have to use an index to grab the item that you want. Maybe you are doing this, but its not in your code example?
fc = combined_name.split("\\")[-1]
fc = combined_name.split(r"\")[-1]
fc = r"{0}".format(combined_name.split("\\")[-1])
True, it returns a list. However, it returns a list of a single element which is still the combined name...
maybe try:
fc = str(combined_name).split("\\")[-1]
fc = str(combined_name).split(r"\")[-1]
fc = r"{0}".format(str(combined_name).split("\\")[-1])
I found some solution (here, I added a condition to check whether the input is some file path that I don't want to mess up. The tool accepts selecting loaded layers from a drop-down as well as browsing files):
def replace_grouped(in_var):
if not os.path.isfile(in_var):
out = repr(in_var).strip("'").split("\\")[-1]
else:
out = in_var
return out
or, in practice: Since somehow the ending \'" was introduced to some input variables but not others, I had to do the following
def replace_grouped(in_var):
if not os.path.isfile(in_var):
out = repr(in_var).strip("'").strip('"').strip("'").strip('"') \
.split("\\")[-1]
else:
out = in_var
return out
(very ugly, but I haven't found a better way to get rid of the trailing garbage yet.)