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.
Solved! Go to Solution.
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
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
@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.
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.
Would split() go inside the first if loop of the script?
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.
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']
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.
Thanks for sharing but screen shots are not very helpful - you can't steal from them!
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?