String values in GetParameterAsText()

3604
11
Jump to solution
01-03-2017 02:24 PM
JaredPilbeam1
Occasional Contributor

Hi,

I have a working ArcMap script tool called Update Map Elements that updates text and numbers in ArcMap documents.

It has four parameters; Workspace, Output, oldText and newText. Workspace is where the input folder goes. Output is the save-to folder. OldText is the text string to be replaced by the newText text string (Red Branch changes to Blue Branch).

My problem is: how can I have multiple string values? So, in the above parameters I specify the Red Branch string value to be replaced by Blue Branch. What if I wanted to have a bunch of string values--such as Red Branch, 600, Violet (oldText) and the corresponding newText values Blue Branch, 800, Green?

I have a feeling I add index positions to the values within the script, but I'm not sure how. I've had a look at this though I'm not sure it's the right approach: SetParameterAsText—Help | ArcGIS for Desktop  

Here's the script behind the Update Map Elements tool:

#set path to relevant folder
import arcpy
from arcpy import env
import os
arcpy.env.overwriteOutput = True

# set path to relvant folder
arcpy.env.workspace = Workspace = arcpy.GetParameterAsText(0)
Output = arcpy.GetParameterAsText(1)
oldText = arcpy.GetParameterAsText(2)
newText = arcpy.GetParameterAsText(3)
# list the mxds of the workspace folder
for mxdname in arcpy.ListFiles("*.mxd"):    
    print mxdname
# set the variable
    mxd = arcpy.mapping.MapDocument(Workspace + "\\" + mxdname)
# replace '2016' that occurs in the title of document
    for elm in arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT"):
        if oldText in elm.text:
            elm.text = elm.text.replace(oldText, newText)
            print '{} changed'.format(elm.text)
    
    for elm in arcpy.mapping.ListLayoutElements(mxd, ""):
        if oldText in mxd.title:
            mxd.title = elm.text.replace(oldText, newText)
# move the mxd.saveACopy outside of the if loop so a copy is saved even it does not meet the condition of the if loops
    mxd.saveACopy(os.path.join(Output + "\\" + mxdname))
# do not include this delete statement inside the above loop or it will delete the mxd object inside the loop. Make sure to dedent.
del mxd 

Thanks in advance.

0 Kudos
1 Solution

Accepted Solutions
DarrenWiens2
MVP Honored Contributor

If you can trust the user to follow the right format, you can use split, which returns a list of items split by the given delimeter:

>>> old_text = 'Red Branch, 600, Violet'
... print old_text.split(', ')
... print old_text.split(', ')[0]
... print old_text.split(', ')[1]
... print old_text.split(', ')[2]
... 
['Red Branch', '600', 'Violet']
Red Branch
600
Violet

View solution in original post

11 Replies
DarrenWiens2
MVP Honored Contributor

If you can trust the user to follow the right format, you can use split, which returns a list of items split by the given delimeter:

>>> old_text = 'Red Branch, 600, Violet'
... print old_text.split(', ')
... print old_text.split(', ')[0]
... print old_text.split(', ')[1]
... print old_text.split(', ')[2]
... 
['Red Branch', '600', 'Violet']
Red Branch
600
Violet
JaredPilbeam1
Occasional Contributor

@Darren

Thanks, but won't that limit the user to only that text as the input? I was looking for a war to keep the parameters completely general so the tool can be used for any sort of updates in a map document.

0 Kudos
DarrenWiens2
MVP Honored Contributor

I was just showing how you can break apart a given text string into parts based on a delimiter. You can still use GetParameterAsText() to collect the user input (e.g. "x,y,z"), break it apart using split() (['x','y','z']), and make your replacements using those individual pieces.

JaredPilbeam1
Occasional Contributor

Would split() go inside the first if loop of the script? 

0 Kudos
DarrenWiens2
MVP Honored Contributor

I don't exactly know what you're trying to do. You're the one who needs to understand the logic of your script. Split() splits a string by a delimiter, which I think is the basic step you're missing, but you need to play with it, understand what's happening, and then change the logic of your script to achieve the final goal. Come up with your new script and if it doesn't do what you think it should, either post and ask for more help, or do some debugging to figure it out.

curtvprice
MVP Esteemed Contributor

You may want to look at multi value parameters. GetParameterAsText pulls these in as ";" delimited, so if the user entered three strings a b c these come in as the string 'a;b;c' which you can then make into a list by splitting it:

strings = arcpy.GetParameterAsText(1).split(";")‍‍

This will give you a list of strings - here's a test at a Python prompt:

>>> 'a;b;c'.split()
['a', 'b', 'c']‍‍‍‍
JaredPilbeam1
Occasional Contributor

I was able to finish the Tool based on split() and some extra help from an ESRI tech. Additionally, there was a 'counter' variable that was used to match the oldText with the newText. There's no limit on the amount of text, but the words from both oldText and newText have to correspond with each other in the right order. If not, the wrong element will be replaced. 

Thanks all for the help.

curtvprice
MVP Esteemed Contributor

Thanks for sharing but screen shots are not very helpful - you can't steal from them!

https://community.esri.com/people/curtvprice/blog/2014/09/25/posting-code-blocks-in-the-new-geonet?s...

JaredPilbeam1
Occasional Contributor

Curtis,

I would have but More > Syntax highlighter isn't available on the toolbar if it's not the original post? I came across this problem before. The toolbar in the subsequent replies offers only half the tools originally available. Am I missing something?

0 Kudos