Using a Search Cursor to Update Map Text - Not getting all info

2529
8
Jump to solution
01-20-2016 10:18 AM
RachelAlbritton
Occasional Contributor III

I've written a python script that reads data from a related table and writes those field values into a text box within ArcMap. The script runs OK when I tell it to print to the command window (all fields are printed), but in the map instead of entering to the new line of text, it appears to be writing over itself. How can I stop this a get it to write in all this info?

import arcpy, os, traceback

mxd = arcpy.mapping.MapDocument(r"\\ad.utah.edu\sys\FM\gis\ags_directories\DDC_Web\Template.mxd")
StopsTable = r"\\csi-files\\fm\\gis\\ags_10_3\\ags_content\\sde_connection_files\\fm-agsDataReader@fm-gisdbtest0.fm.utah.edu.sde\\UUSD.DBO.DDC\\UUSD.DBO.DDC_Stops"

for elm in arcpy.mapping.ListLayoutElements(mxd,"TEXT_ELEMENT"):
    
    sc = arcpy.SearchCursor(StopsTable)
    for row in sc:
        if elm.name == "Report":
            print "Stops "+str(row.Stop_Number)+": "+row.Stop_Status+"\n"
            elm.text = "Stops "+str(row.Stop_Number)+": "+row.Stop_Status+"\n"

Python Shell Print Screen (to show me the script is doing what I want it to)

Final MXD after Script runs:

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
JakeSkinner
Esri Esteemed Contributor

Hi Rachel,

Each time you iterate through the table you are overwriting the text element.  So the last row is always displayed.  You will need to append the element's text each time.  Ex:

for elm in arcpy.mapping.ListLayoutElements(mxd,"TEXT_ELEMENT"): 
        with arcpy.da.SearchCursor(StopsTable, ["Stop_Number", "Stop_Status"]) as cursor:
            for row in cursor:
                if elm.name == "Report": 
                    elm.text = elm.text + "Stops "+str(row[0])+": "+row[1] +"\n"

Note:  I used the arcpy.da.SearchCursor in the above example.

View solution in original post

8 Replies
DarrenWiens2
MVP Honored Contributor

Store the growing string in a variable, then write it to the element.

Untested:

my_string = ""
for row in sc:  
        if elm.name == "Report"
            print "Stops "+str(row.Stop_Number)+": "+row.Stop_Status+"\n"  
            my_string += "Stops "+str(row.Stop_Number)+": "+row.Stop_Status+"\n" 
elm.text = my_string
0 Kudos
RachelAlbritton
Occasional Contributor III

great Idea, but I got the same results.

I've figured out that I can make each stop its own text box and that works - tedious though:

for elm in arcpy.mapping.ListLayoutElements(mxd,"TEXT_ELEMENT"):

    sc = arcpy.SearchCursor(StopsTable)

    for row in sc:

        if elm.name == "Stop2" and row.Stop_Number == 2:

            elm.text = "Stop "+str(row.Stop_Number)+": "+row.Stop_Status          

        elif elm.name == "Stop3" and row.Stop_Number == 3:

            elm.text = "Stop "+str(row.Stop_Number)+": "+row.Stop_Statusy_string = "" for row in sc:          if elm.name == "Report":              print "Stops "+str(row.Stop_Number)+": "+row.Stop_Status+"\n"              my_string += "Stops "+str(row.Stop_Number)+": "+row.Stop_Status+"\n" elm.text = my_strin

0 Kudos
JimmyKroon
Occasional Contributor II

The problem is that line 12 overwrites elm.text during each cycle of the loop. You need to append the new text to the previous values without overwriting.

I would have thought changing = to += would work, but if not, try the append() string function.

mystring.append(new text to add)

0 Kudos
JakeSkinner
Esri Esteemed Contributor

Hi Rachel,

Each time you iterate through the table you are overwriting the text element.  So the last row is always displayed.  You will need to append the element's text each time.  Ex:

for elm in arcpy.mapping.ListLayoutElements(mxd,"TEXT_ELEMENT"): 
        with arcpy.da.SearchCursor(StopsTable, ["Stop_Number", "Stop_Status"]) as cursor:
            for row in cursor:
                if elm.name == "Report": 
                    elm.text = elm.text + "Stops "+str(row[0])+": "+row[1] +"\n"

Note:  I used the arcpy.da.SearchCursor in the above example.

RachelAlbritton
Occasional Contributor III

Thanks Jake - That's what I needed. So my only issue is now, this will always add to whatever existing text is already in the text box. Each time I run the script I need the existing info to be deleted and the new info written in. Any suggestions?

0 Kudos
JakeSkinner
Esri Esteemed Contributor

You could do something along the following:

firstTime = True

with arcpy.da.SearchCursor(StopsTable, ["Stop_Number", "Stop_Status"]) as cursor:
    for row in cursor:
        for elm in arcpy.mapping.ListLayoutElements(mxd,"TEXT_ELEMENT"):
            if elm.name == "Report":
                if firstTime:
                    elm.text = "Stops "+str(row[0])+": "+row[1] +"\n"
                    firstTime = False
                else:                                    
                    elm.text = elm.text + "Stops "+str(row[0])+": "+row[1] +"\n"

arcpy.RefreshActiveView()
0 Kudos
JimmyKroon
Occasional Contributor II

Find the text element first, set it's value to nothing, then search and append the report values.

for elm in arcpy.mapping.ListLayoutElements(mxd,"TEXT_ELEMENT"😞

     if elm.name == "Report"

          elm.text = ""

          with arcpy.da.SearchCursor(StopsTable, ["Stop_Number", "Stop_Status"]) as cursor: 

               for row in cursor: 

                    elm.text = elm.text + "Stops "+str(row[0])+": "+row[1] +"\n"

0 Kudos
RachelAlbritton
Occasional Contributor III

Yeah, I thought that would work as well, but unfortunately it doesn't...not sure why

I decided to clone the text box, and write the report to the clone. Then the clone can be deleted at the beginning of the script when it ran and a new clone will be created to write to.

0 Kudos