Can I export a subset of data driven pages in a scheduled process using a def query?

3244
6
Jump to solution
07-18-2012 06:22 AM
TimDine
Occasional Contributor II
I am attempting to export a set of map books using a common index layer which has an attribute telling me which map books each feature in the index belongs to.  Interactively I can open ArcMap, change the definition query on the featureclass and refresh the data driven pages before exporting each map book.  I am attempting to do this in python so I can schedule it to update the books at a regular interval.  I could do this with a search cursor to loop through checking the attributes and append each page, although it appears the code below should work conceptually at doing what I'm attempting.  It runs (with the exception of the mxd.dataDrivenPages.refresh() line), but exports all of the features in the original unmodified definition query.  Any thoughts on if this can't work, why, or is the loop with a cursor my only option?

import arcpy mxd = arcpy.mapping.MapDocument("c:/temp/MapTemplate32KOneLine.mxd")  for myLayer in arcpy.mapping.ListLayers(mxd,'OneLineBoundaryTileEdit - 32K Index'):  myLayer.definitionQuery = "SUBTYPECD = 3 AND DEPOT LIKE '%BAR%'"  mxd.dataDrivenPages.refresh() mxd.dataDrivenPages.exportToPDF("C:/temp/BAR.pdf","ALL","","PDF_SINGLE_FILE","100","FASTEST")


Note:
The error I get from the mxd.dataDrivenPages.refresh() line is below.
Traceback (most recent call last):   File "testExportDataDrivenPages.py", line 13, in <module>     mxd.dataDrivenPages.refresh()   File "C:\Program Files (x86)\ArcGIS\Desktop10.0\arcpy\arcpy\_mapping.py", line 266, in refresh     return convertArcObjectToPythonObject(self._arc_object.refresh(*gp_fixargs((args), True))) ValueError: PageLayoutObject: Error in refreshing RefreshDataDrivenPages
0 Kudos
1 Solution

Accepted Solutions
TimDine
Occasional Contributor II
Apparently you have to stop editing, then everything is fine...

I can leave the code up if it's useful for reference or delete the post.

View solution in original post

0 Kudos
6 Replies
TimDine
Occasional Contributor II
Apparently you have to stop editing, then everything is fine...

I can leave the code up if it's useful for reference or delete the post.
0 Kudos
JeffBarrette
Esri Regular Contributor
Another option to consider is to simply run a query on your index layer (e.g, SelectLayerByAttribute) and export using the selected index features.

ddp.exportToPDF(outpdf, page_range_type="SELECTED") 


Jeff
0 Kudos
AndrewDuff
New Contributor
I am having the same error in one of my scripts and this is the only post I can find where DataDrivenPages.refresh() gives the value error.  Are there know issues beside editing that would cause this to be thrown from python but not from the gui itself as the OP had?

error on line: line 139
error in file name: C:\data\ArcGISServer\Reporting\OccProdReport.py
with error message: ValueError: PageLayoutObject: Error in refreshing RefreshDataDrivenPages
0 Kudos
JeffBarrette
Esri Regular Contributor
Are you doing anything else to the index layer dynamically while the script is running?  I once tried building the index layer on the fly (based on the area of interest) while it was being referenced within the same MXD the script/DDP was working against.  The solution was to work build the index using one MXD and the map pages using another MXD (but all with a single script).

Please provide more detail.

Jeff
0 Kudos
AndrewDuff
New Contributor
Are you doing anything else to the index layer dynamically while the script is running?  I once tried building the index layer on the fly (based on the area of interest) while it was being referenced within the same MXD the script/DDP was working against.  The solution was to work build the index using one MXD and the map pages using another MXD (but all with a single script).

Please provide more detail.

Jeff


I am doing exactly as you say.  I update the index layer dynamically while the script is running and then try to refresh data driven pages at which point I get the error I posted above (This works at 10, not 10.1).  After the code fails I can open my mxd, see that it is now pointing at the updated index layer and run the refresh manually on toolbar and it works with no errors.  It is not happy when you try to do this with python though.

My code is below.

   relPath = os.path.dirname(__file__)   
        arcpy.env.overWriteOutput = True
        arcpy.env.workspace = relPath
        arcpy.env.scratchWorkspace = relPath
        arcpy.AddMessage("The relpath variable is " + relPath + "...")
        arcpy.AddMessage("The scratch folder is " + arcpy.env.scratchFolder + "...")
        arcpy.AddMessage("The scratch gdb is " + arcpy.env.scratchGDB + "...")

        ##We have two map documents, the first is the report page, the second is the map page
        mxdPath1 = "C:\data\ArcGISServer\Reporting\scratch\Template_Page1_GeoLib.mxd"
        mxdPath2 = "C:\data\ArcGISServer\Reporting\scratch\Template_Page2_GeoLib10.1.mxd"

        arcpy.AddMessage("Map document 1 is located at " + mxdPath1 + "...")
        arcpy.AddMessage("Map document 2 is located at " + mxdPath2 + "...")      

        mxd = arcpy.mapping.MapDocument(mxdPath1)
        mxd2 = arcpy.mapping.MapDocument(mxdPath2)

        ##Get the layers and the table
        lyr = arcpy.mapping.ListLayers(mxd, "WS_OCCURPOINT_SV")[0]
        tab = arcpy.mapping.ListTableViews(mxd, "WS_RAPTORSUM")[0]
        buf = arcpy.mapping.ListLayers(mxd2, "OccurPoint_SV_Buffer")[0]

        arcpy.AddMessage("Obtained the map layers from the map templates...")

        ##Loop through all of the layout elements in the first page and assign them to variables
        for elm in arcpy.mapping.ListLayoutElements(mxd):
            ##These are for the tabular component at the top of page 1
            if elm.name == "tabYear": tabYear = elm
            if elm.name == "tabNestNum": tabNestNum = elm
            if elm.name == "tabESO": tabESO = elm
            if elm.name == "tabLSO": tabLSO = elm
            if elm.name == "tabSummary": tabSummary = elm
            if elm.name == "tabObserver": tabObserver = elm
            ##These are for headings or for large group elements on page 1
            if elm.name == "txtLocationInfo": txtLocationInfo = elm
            if elm.name == "txtTerritory": txtTerritory = elm
            if elm.name == "txtSiteName": txtSiteName = elm
            if elm.name == "txtWarning": txtWarning = elm
            if elm.name == "txtWarning2": txtWarning2 = elm
            if elm.name == "MiddleGroup": middleGroup = elm
            if elm.name == "UseSpace": useSpace = elm

        ##Loop through all of the layout elements in the second page and assign them to variables
        for elm in arcpy.mapping.ListLayoutElements(mxd2):
            ##These are for the tabular component at the bottom of page 2
            if elm.name == "tabNestNumPage2": tabNestNumPage2 = elm
            if elm.name == "tabZappedPage2": tabZappedPage2 = elm
            if elm.name == "tabOccurNotesPage2": tabOccurNotesPage2 = elm
            if elm.name == "tabLastEffortDatePage2": tabLastEffortDatePage2 = elm
            if elm.name == "tabLatLongPage2": tabLatLongPage2 = elm
            ##These are for headings of page 2
            if elm.name == "txtTerritoryPage2": txtTerritoryPage2 = elm
            if elm.name == "txtSiteNamePage2": txtSiteNamePage2 = elm
            if elm.name == "txtQuadNamePage2": txtQuadNamePage2 = elm
            if elm.name == "txtQuadCodePage2": txtQuadCodePage2 = elm
            #if elm.name == "txtLegalDescPage2": txtLegalDescPage2 = elm
            if elm.name == "txtLocationInfoPage2": txtLocationInfoPage2 = elm
            if elm.name == "txtWarningPage2": txtWarningPage2 = elm

        arcpy.AddMessage("Obtained the text elements from the map templates...")

        ##Get the input parameters
        territoryList = arcpy.GetParameterAsText(0)
        territoryListNums = territoryList.split(';')
        speciesCode = arcpy.GetParameterAsText(1)
        occurType = arcpy.GetParameterAsText(2)
        mapScale = arcpy.GetParameterAsText(3)

        ##Set up the buffer output
        OccurPoint_SV_Buffer = arcpy.env.scratchGDB + "\\buffer"
        territoryListString = "(" + str(territoryList).replace(";",",") + ")"

        ##For file geodatabase "SPPCODE" = 'HALE' AND "HrtgOccurno" in (41, 88, 160, 655, 1126)
        if occurType == "ALL":
            whereClause = "\"SPPCODE\" = '" + speciesCode + "' AND \"HrtgOccurno\" in " + territoryListString
        else:
            whereClause = "\"SPPCODE\" = '" + speciesCode + "' AND \"HrtgOccurno\" in " + territoryListString + " AND \"OccurType_PT_Desc\" = '" + occurType + "'"

        ##Check to see if things exist and delete
        arcpy.AddMessage("Deleting the old 'Output_Layer' and 'OccurPoint_SV_Buffer' [outside of main loop]...")
        if arcpy.Exists(arcpy.env.scratchGDB + "\Output_Layer"):
            arcpy.Delete_management(arcpy.env.scratchGDB + "\Output_Layer")
        else:
            arcpy.AddMessage(arcpy.env.scratchGDB + "\Output_Layer" + " does not exist...")

        if arcpy.Exists(OccurPoint_SV_Buffer):
            arcpy.Delete_management(OccurPoint_SV_Buffer)
        else:
            arcpy.AddMessage(OccurPoint_SV_Buffer + " does not exist...")
        arcpy.AddMessage("Deleted the old 'Output_Layer' and 'OccurPoint_SV_Buffer' [outside of main loop]...")

        ##Select the territories to buffer
        arcpy.MakeFeatureLayer_management(lyr, arcpy.env.scratchGDB + "\Output_Layer", whereClause, "", "OBJECTID OBJECTID VISIBLE NONE;OccurPointID OccurPointID VISIBLE NONE;SPPCODE SPPCODE VISIBLE NONE;ComName ComName VISIBLE NONE;TaxoNameID TaxoNameID VISIBLE NONE;HrtgOccurno HrtgOccurno VISIBLE NONE;HrtgSeqno HrtgSeqno VISIBLE NONE;SiteName SiteName VISIBLE NONE;EffortDate EffortDate VISIBLE NONE;OccurNotes OccurNotes VISIBLE NONE;ObsAffil ObsAffil VISIBLE NONE;OccurType_PT_Desc OccurType_PT_Desc VISIBLE NONE;OccurClass_Desc OccurClass_Desc VISIBLE NONE;OccurOn_Desc OccurOn_Desc VISIBLE NONE;Zapped_Desc Zapped_Desc VISIBLE NONE;CountyName CountyName VISIBLE NONE;Legal_Desc_Nm Legal_Desc_Nm VISIBLE NONE;Township Township VISIBLE NONE;Range Range VISIBLE NONE;RangeDir RangeDir VISIBLE NONE;SubDivNo SubDivNo VISIBLE NONE;SubDivType SubDivType VISIBLE NONE;Lat_SPNAD83HARN Lat_SPNAD83HARN VISIBLE NONE;Long_SPNAD83HARN Long_SPNAD83HARN VISIBLE NONE;X_SPNAD83HARN X_SPNAD83HARN VISIBLE NONE;Y_SPNAD83HARN Y_SPNAD83HARN VISIBLE NONE;Accuracy_Desc Accuracy_Desc VISIBLE NONE;WDFWRegion WDFWRegion VISIBLE NONE;QuadCode100k QuadCode100k VISIBLE NONE;QuadCode24k QuadCode24k VISIBLE NONE;QuadName24k QuadName24k VISIBLE NONE;DelormePageNo DelormePageNo VISIBLE NONE;Shape Shape VISIBLE NONE")

        ##Do the buffer
        arcpy.Buffer_analysis(arcpy.env.scratchGDB + "\Output_Layer", OccurPoint_SV_Buffer, "500 Feet", "FULL", "ROUND", "LIST", "SPPCODE;ComName;TaxoNameID;HrtgOccurno;SiteName")

        #Set the current page to the first one
        mxd2.dataDrivenPages.currentPageID = 1
        #Refresh the data driven pages
        mxd2.dataDrivenPages.refresh()
        arcpy.AddMessage("Completed updating the map grid...")


Ill try what you say for the second mxd.
0 Kudos
AndrewDuff
New Contributor
I am doing exactly as you say.  I update the index layer dynamically while the script is running and then try to refresh data driven pages at which point I get the error I posted above (This works at 10, not 10.1).  After the code fails I can open my mxd, see that it is now pointing at the updated index layer and run the refresh manually on toolbar and it works with no errors.  It is not happy when you try to do this with python though.

My code is below.

   relPath = os.path.dirname(__file__)   
        arcpy.env.overWriteOutput = True
        arcpy.env.workspace = relPath
        arcpy.env.scratchWorkspace = relPath
        arcpy.AddMessage("The relpath variable is " + relPath + "...")
        arcpy.AddMessage("The scratch folder is " + arcpy.env.scratchFolder + "...")
        arcpy.AddMessage("The scratch gdb is " + arcpy.env.scratchGDB + "...")

        ##We have two map documents, the first is the report page, the second is the map page
        mxdPath1 = "C:\data\ArcGISServer\Reporting\scratch\Template_Page1_GeoLib.mxd"
        mxdPath2 = "C:\data\ArcGISServer\Reporting\scratch\Template_Page2_GeoLib10.1.mxd"

        arcpy.AddMessage("Map document 1 is located at " + mxdPath1 + "...")
        arcpy.AddMessage("Map document 2 is located at " + mxdPath2 + "...")      

        mxd = arcpy.mapping.MapDocument(mxdPath1)
        mxd2 = arcpy.mapping.MapDocument(mxdPath2)

        ##Get the layers and the table
        lyr = arcpy.mapping.ListLayers(mxd, "WS_OCCURPOINT_SV")[0]
        tab = arcpy.mapping.ListTableViews(mxd, "WS_RAPTORSUM")[0]
        buf = arcpy.mapping.ListLayers(mxd2, "OccurPoint_SV_Buffer")[0]

        arcpy.AddMessage("Obtained the map layers from the map templates...")

        ##Loop through all of the layout elements in the first page and assign them to variables
        for elm in arcpy.mapping.ListLayoutElements(mxd):
            ##These are for the tabular component at the top of page 1
            if elm.name == "tabYear": tabYear = elm
            if elm.name == "tabNestNum": tabNestNum = elm
            if elm.name == "tabESO": tabESO = elm
            if elm.name == "tabLSO": tabLSO = elm
            if elm.name == "tabSummary": tabSummary = elm
            if elm.name == "tabObserver": tabObserver = elm
            ##These are for headings or for large group elements on page 1
            if elm.name == "txtLocationInfo": txtLocationInfo = elm
            if elm.name == "txtTerritory": txtTerritory = elm
            if elm.name == "txtSiteName": txtSiteName = elm
            if elm.name == "txtWarning": txtWarning = elm
            if elm.name == "txtWarning2": txtWarning2 = elm
            if elm.name == "MiddleGroup": middleGroup = elm
            if elm.name == "UseSpace": useSpace = elm

        ##Loop through all of the layout elements in the second page and assign them to variables
        for elm in arcpy.mapping.ListLayoutElements(mxd2):
            ##These are for the tabular component at the bottom of page 2
            if elm.name == "tabNestNumPage2": tabNestNumPage2 = elm
            if elm.name == "tabZappedPage2": tabZappedPage2 = elm
            if elm.name == "tabOccurNotesPage2": tabOccurNotesPage2 = elm
            if elm.name == "tabLastEffortDatePage2": tabLastEffortDatePage2 = elm
            if elm.name == "tabLatLongPage2": tabLatLongPage2 = elm
            ##These are for headings of page 2
            if elm.name == "txtTerritoryPage2": txtTerritoryPage2 = elm
            if elm.name == "txtSiteNamePage2": txtSiteNamePage2 = elm
            if elm.name == "txtQuadNamePage2": txtQuadNamePage2 = elm
            if elm.name == "txtQuadCodePage2": txtQuadCodePage2 = elm
            #if elm.name == "txtLegalDescPage2": txtLegalDescPage2 = elm
            if elm.name == "txtLocationInfoPage2": txtLocationInfoPage2 = elm
            if elm.name == "txtWarningPage2": txtWarningPage2 = elm

        arcpy.AddMessage("Obtained the text elements from the map templates...")

        ##Get the input parameters
        territoryList = arcpy.GetParameterAsText(0)
        territoryListNums = territoryList.split(';')
        speciesCode = arcpy.GetParameterAsText(1)
        occurType = arcpy.GetParameterAsText(2)
        mapScale = arcpy.GetParameterAsText(3)

        ##Set up the buffer output
        OccurPoint_SV_Buffer = arcpy.env.scratchGDB + "\\buffer"
        territoryListString = "(" + str(territoryList).replace(";",",") + ")"

        ##For file geodatabase "SPPCODE" = 'HALE' AND "HrtgOccurno" in (41, 88, 160, 655, 1126)
        if occurType == "ALL":
            whereClause = "\"SPPCODE\" = '" + speciesCode + "' AND \"HrtgOccurno\" in " + territoryListString
        else:
            whereClause = "\"SPPCODE\" = '" + speciesCode + "' AND \"HrtgOccurno\" in " + territoryListString + " AND \"OccurType_PT_Desc\" = '" + occurType + "'"

        ##Check to see if things exist and delete
        arcpy.AddMessage("Deleting the old 'Output_Layer' and 'OccurPoint_SV_Buffer' [outside of main loop]...")
        if arcpy.Exists(arcpy.env.scratchGDB + "\Output_Layer"):
            arcpy.Delete_management(arcpy.env.scratchGDB + "\Output_Layer")
        else:
            arcpy.AddMessage(arcpy.env.scratchGDB + "\Output_Layer" + " does not exist...")

        if arcpy.Exists(OccurPoint_SV_Buffer):
            arcpy.Delete_management(OccurPoint_SV_Buffer)
        else:
            arcpy.AddMessage(OccurPoint_SV_Buffer + " does not exist...")
        arcpy.AddMessage("Deleted the old 'Output_Layer' and 'OccurPoint_SV_Buffer' [outside of main loop]...")

        ##Select the territories to buffer
        arcpy.MakeFeatureLayer_management(lyr, arcpy.env.scratchGDB + "\Output_Layer", whereClause, "", "OBJECTID OBJECTID VISIBLE NONE;OccurPointID OccurPointID VISIBLE NONE;SPPCODE SPPCODE VISIBLE NONE;ComName ComName VISIBLE NONE;TaxoNameID TaxoNameID VISIBLE NONE;HrtgOccurno HrtgOccurno VISIBLE NONE;HrtgSeqno HrtgSeqno VISIBLE NONE;SiteName SiteName VISIBLE NONE;EffortDate EffortDate VISIBLE NONE;OccurNotes OccurNotes VISIBLE NONE;ObsAffil ObsAffil VISIBLE NONE;OccurType_PT_Desc OccurType_PT_Desc VISIBLE NONE;OccurClass_Desc OccurClass_Desc VISIBLE NONE;OccurOn_Desc OccurOn_Desc VISIBLE NONE;Zapped_Desc Zapped_Desc VISIBLE NONE;CountyName CountyName VISIBLE NONE;Legal_Desc_Nm Legal_Desc_Nm VISIBLE NONE;Township Township VISIBLE NONE;Range Range VISIBLE NONE;RangeDir RangeDir VISIBLE NONE;SubDivNo SubDivNo VISIBLE NONE;SubDivType SubDivType VISIBLE NONE;Lat_SPNAD83HARN Lat_SPNAD83HARN VISIBLE NONE;Long_SPNAD83HARN Long_SPNAD83HARN VISIBLE NONE;X_SPNAD83HARN X_SPNAD83HARN VISIBLE NONE;Y_SPNAD83HARN Y_SPNAD83HARN VISIBLE NONE;Accuracy_Desc Accuracy_Desc VISIBLE NONE;WDFWRegion WDFWRegion VISIBLE NONE;QuadCode100k QuadCode100k VISIBLE NONE;QuadCode24k QuadCode24k VISIBLE NONE;QuadName24k QuadName24k VISIBLE NONE;DelormePageNo DelormePageNo VISIBLE NONE;Shape Shape VISIBLE NONE")

        ##Do the buffer
        arcpy.Buffer_analysis(arcpy.env.scratchGDB + "\Output_Layer", OccurPoint_SV_Buffer, "500 Feet", "FULL", "ROUND", "LIST", "SPPCODE;ComName;TaxoNameID;HrtgOccurno;SiteName")

        #Set the current page to the first one
        mxd2.dataDrivenPages.currentPageID = 1
        #Refresh the data driven pages
        mxd2.dataDrivenPages.refresh()
        arcpy.AddMessage("Completed updating the map grid...")


Ill try what you say for the second mxd.


I got around it by explicitly updating the datasource before calling refresh as below.

      
 ##Replace data source
        buf.replaceDataSource(arcpy.env.scratchGDB, "FILEGDB_WORKSPACE", "buffer")
0 Kudos