Dynamic Text Based on Variable?

1973
9
05-14-2012 02:35 PM
JoelMadero
New Contributor
I guess this question is two fold:

1. Is there a way to make dynamic text that is based on a variable?

2. If so how do I do it and set the variable # using python.

My situation is I have a map ID # in the top right of my map. As of now I manually change the ID # for every map that I make, I want this to be automated. I have a list of the ID's so I can make a loop if I can figure out how to set the text to be based on a variable and then learn how to set that variable using ESRI's python. Thanks in advance
Tags (2)
0 Kudos
9 Replies
MathewCoyle
Frequent Contributor
Here's what I do.

var_text = "Some title/number etc"
element_name = "ID"
for elm in arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", element_name):
    if elm.name == element_name:
        elm.text = (var_text)
0 Kudos
JoelMadero
New Contributor
Here's what I do.

var_text = "Some title/number etc"
element_name = "ID"
for elm in arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", element_name):
    if elm.name == element_name:
        elm.text = (var_text)


Thanks for the reply. How do I actually set the dynamic text to be the element named "ID". I think otherwise I get it, thanks again appreciate all the help.
0 Kudos
JeffBarrette
Esri Regular Contributor
Right click on the text element and select properties.  Go to the Size and Position tab.  Set the Element Name there.  Be sure all elements that you want to find have a unique name.

Jeff
0 Kudos
JoelMadero
New Contributor
Right click on the text element and select properties.  Go to the Size and Position tab.  Set the Element Name there.  Be sure all elements that you want to find have a unique name.

Jeff


Nevermind, need to read directions more thoroughly. going to try now
0 Kudos
JoelMadero
New Contributor
so it works the first time but fails to change the text when you run the same code a second time:

var_text = "1200"
>>> element_name = "map_ID"
>>> for elm in arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", element_name):
...  if elm.name == element_name:
...   elm.Text = (var_text)


first time no problem at all, second time I just change var_text to some other thing "1201" for instance and it doesn't update the text. Any ideas?

Edit: More info, if I double click on text and then exit properties, then run the script again with a different # for var_text it works. This defeats the purpose of the script though (automate the maps) so hoping to find a way around it
0 Kudos
BenjaminGale
New Contributor III
Not sure if this is the sort of thing you were looking for but I might have something that will work for you.
However, it requires a look up table containing map names and the text you want displayed.

To use the code, the maps you want to run the code on should ALL contain the same text
for the element you want to change. For example, when I was testing the code I had the
text '<TextVariable>' on each map and it was set to be the text replaced by what was
stored in the look up table for that map document.
So in my test, the text that said '<TextVariable>' became 'Map 001' in Map1.mxd, it became
'Map 002' in Map2.mxd and so on.

This solution would require you to change the text after the map is completed. Also, the code can't be run
on a map that is currently open.

#============================================
# Change Text Based Using Look Up Table
#============================================

import arcpy
import os

mxds = [r"C:\My_Stuff\GIS\Text\Map1.mxd","C:\My_Stuff\GIS\Text\Map2.mxd"] #List of mxds
table = [r"C:\My_Stuff\GIS\Text\DynamicText.gdb\LookupText"] # Lookup table

for mxd in mxds:
    rows = arcpy.SearchCursor(table)
    mapp = arcpy.mapping.MapDocument(mxd)
    for row in rows:
        val = row.getValue("MapName") #Fieldname containing map names
        if val + ".mxd" == os.path.basename(mxd):
            txt = row.getValue("Text") #Fieldname containing text string
            txt_elms = arcpy.mapping.ListLayoutElements(mapp,"TEXT_ELEMENT")
            for elm in txt_elms:
                if elm.text == "<TextVariable>": #Text in all maps to be replaced
                elm.text = txt
                mapp.save()
                del rows, row


You could also set the code to look for element names rather than text

Also, while I didn't have any trouble with the code, if you use the code you may want to test it on copies
of you maps first given that it saves the changes made.
0 Kudos
MathewCoyle
Frequent Contributor
so it works the first time but fails to change the text when you run the same code a second time:

var_text = "1200"
>>> element_name = "map_ID"
>>> for elm in arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", element_name):
...  if elm.name == element_name:
...   elm.Text = (var_text)


first time no problem at all, second time I just change var_text to some other thing "1201" for instance and it doesn't update the text. Any ideas?

Edit: More info, if I double click on text and then exit properties, then run the script again with a different # for var_text it works. This defeats the purpose of the script though (automate the maps) so hoping to find a way around it


Try this. The line elm.Text won't work. Capitalization is important, as is indenting. Though in this case, the indentation you used was fine.
for elm in arcpy.mapping.ListLayoutElements(mxd,"TEXT_ELEMENT",element_name):
    elm.text = var_text
0 Kudos
JoelMadero
New Contributor
Try this. The line elm.Text won't work. Capitalization is important, as is indenting. Though in this case, the indentation you used was fine.
for elm in arcpy.mapping.ListLayoutElements(mxd,"TEXT_ELEMENT",element_name):
    elm.text = var_text


That did the trick. I've never used a language that has two different actions dependent on capitalization. If anything it just fails if it's not capitalized right but in this case it worked the first time, failed the second. Very strange, but problem solved 🙂 Thanks for the reply
0 Kudos
JoelMadero
New Contributor
Try this. The line elm.Text won't work. Capitalization is important, as is indenting. Though in this case, the indentation you used was fine.
for elm in arcpy.mapping.ListLayoutElements(mxd,"TEXT_ELEMENT",element_name):
    elm.text = var_text


Edit: Oh you mean an actual selection. I really am trying to avoid selecting as it's so much slower than what I'm doing now (definition query, zoom to layer). Not sure why the speed difference but it's at least 50% faster avoiding selection and with 250+ maps being printed from a mid range computer, 50% is a lot of time saved
0 Kudos