Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am new to writing scripts, and I am trying to make a map series using ArcPy.mapping and data driven map pages. I would like to put some text on the map that updates for each map in the series depending on a new definition query for my dataset of sites. So, I set up my map series based on the district numbers the sites are in (districts 1 - 32). So, the pageNum should also equal the district, and I thought I could pass the pageNum into a SQL query and get a new count of sites for each district and then insert that as dynamic text using text.replace.

Here is my code - can anyone tell me where I'm going wrong with this? I would be so grateful!

EDIT I was able to get my code to work, so I am replacing the erroneous code with the functioning one, in case it is useful for someone else... or if someone can show me how to make it more elegant and efficient;-)

import arcpy, string, os

mxdPath = "CURRENT"
outPath = r"D:\Geoprocessing\CDMAPS\PDFs\MapPage\\"
SitesConDist = r"D:\Geoprocessing\CDMAPS\MXDs_and_Geodatabase\CDMaps.mdb\Sites\SitesCD"
outputMXD = "D:\Geoprocessing\CDMAPS\MXDs_and_Geodatabase\SeriesMXDs\\"

    mxd = arcpy.mapping.MapDocument(mxdPath)
    ddp = mxd.dataDrivenPages
    df = arcpy.mapping.ListDataFrames(mxd, "Cong*")[0]    
    for pageNum in range(1, mxd.dataDrivenPages.pageCount +1):

        mxd.dataDrivenPages.currentPageID = pageNum
        distNo = str(mxd.dataDrivenPages.currentPageID)
        arcpy.MakeFeatureLayer_management("SitesConDist","siteLyr","[congress_dist_no] = "+ distNo,"#","")

        defCorp = "[COnly] = 'X'"
        defCoop = "[COOP] = 'X' AND [COnly] IS NULL"
        defNSIP = "[NSIP_Full_or_Partial] = 'X'"
        defDisc = "[agency_use_cd] NOT IN ( 'A' , 'L' , 'M' )"

        arcpy.SelectLayerByAttribute_management("siteLyr","NEW_SELECTION",defCorp )
        corpscount = str(arcpy.GetCount_management("siteLyr"))
        arcpy.AddMessage(corpscount + " corps gages in district " + str(pageNum))
        print corpscount + " corps gages in district " + str(pageNum)

        arcpy.SelectLayerByAttribute_management("siteLyr", "NEW_SELECTION",defCoop)
        coopcount = str(arcpy.GetCount_management("siteLyr"))
        arcpy.AddMessage(coopcount + " coop gages in district " + str(pageNum))
        print coopcount + " coop gages in district " + str(pageNum)

        arcpy.SelectLayerByAttribute_management("siteLyr", "NEW_SELECTION",defNSIP)
        nsipcount = str(arcpy.GetCount_management("siteLyr"))
        arcpy.AddMessage(nsipcount + " nsip gages in district " + str(pageNum))
        print nsipcount + " nsip gages in district " + str(pageNum)

        arcpy.SelectLayerByAttribute_management("siteLyr", "NEW_SELECTION",defDisc)
        disccount = str(arcpy.GetCount_management("siteLyr"))
        arcpy.AddMessage(disccount + " discontinued gages in district " + str(pageNum))
        print disccount + " discontinued gages in district " + str(pageNum)

        for elm in arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT"):
                if == "CorpCount":
                    elm.text = "(" + corpscount + ")"
                    print "Corp line in legend has been replaced"
                if == "CoopCount":
                    elm.text = "(" + coopcount + ")"
                    print "Coop line in legend has been replaced"
                if == "NSIPCount":
                    elm.text = "(" + nsipcount + ")"
                    print "NSIP line in legend has been replaced"
                if == "DiscCount":
                    elm.text = "(" + disccount + ")"
                    print "Discontinued line in legend has been replaced"

        Pdf = outPath + "distNo" + str(pageNum) + ".pdf"
        arcpy.mapping.ExportToPDF(mxd, Pdf)
        #os.startfile(Pdf) -> this line can be used to preview each map as it is created
        arcpy.AddMessage("Created PDF {0} of {1}".format(str(mxd.dataDrivenPages.currentPageID), str(mxd.dataDrivenPages.pageCount)))
        print "Created PDF {0} of {1}".format(str(mxd.dataDrivenPages.currentPageID), str(mxd.dataDrivenPages.pageCount))
    del mxd, df

except Exception, e:
    import traceback
    map(arcpy.AddError, traceback.format_exc().split("\n"))
share|improve this question
What is the ouput? Is there an error or is it not returning what you want? An example would be useful. – Dan Patterson Mar 24 '11 at 22:17
Hi! Thanks for offering to look at my code - here is the error: – Christy-Ann Archuleta Mar 25 '11 at 15:35
File "D:\Working\SCRIPTS\", line 16, in <module> for lyr in arcpy.mapping.ListLayers(mxd, "", df)[0]: File "C:\ArcGIS\Desktop10.0\arcpy\arcpy\arcobjects\", line 229, in iter self.layers AttributeError: LayerObject: Get attribute layers does not exist LayerObject: Get attribute layers does not exist Completed script MapBookProduction... Failed to execute (MapBookProduction). – Christy-Ann Archuleta Mar 25 '11 at 15:35
Does my description of what I'm trying to do make sense? I want to count how many features are in a feature class and put the count on each map. Each map shows a district with a different number of sites located in it. Since the page number coincides with the district number, I thought I could use that number in a sql query to define the points by their district number attribute. Does that make sense? It's so hard to describe these things with words;-) – Christy-Ann Archuleta Mar 25 '11 at 15:49
Brutal...on a hunch, have you tried mxd = arcpy.mapping.MapDocument("CURRENT") and running it from within ArcMap rather than standalone? Edit Saw Kevin's suggestion below, which might also be the case, so try his first – Dan Patterson Mar 25 '11 at 19:28

On the following line:

for lyr in arcpy.mapping.ListLayers(mxd, "", df)[0]:

Try removing the [0] at the end. With this you're looking for lyr inside a single layer object. By taking out the [0] you should be able to loop over and search by name like you want

share|improve this answer
Hi Kevin and Dan - after reading your suggestions, I realized I don't really have to fiddle around with the data frame and layers. I went ahead and made .lyr files containing the basic definition query I'm using to display my sites in 4 categories. So, that got rid of a bunch of code. Also understanding how the [0] is a big help. I was trying to figure that out all day. I think I'm alot closer with this code, but sqlExp won't work. I think it has something to do with passing a number into the sql string query. Hmmm... – Christy-Ann Archuleta Mar 25 '11 at 21:33
First I get the field name from the sites feature class desc = arcpy.Describe(sites) fields = desc.fields for field in fields: if == "dist_no": district = – Christy-Ann Archuleta Mar 25 '11 at 22:12
Well - I can't figure out how to put my new code in here... not enough characters. – Christy-Ann Archuleta Mar 25 '11 at 22:17

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.