1

My goal with this script is to create 9 PDFs and 9 sheets within an Excel workbook. The script utilizes select by location, attributes, and searchcursors to read data to Excel and iterate through user defined areas.

When I run the script with no user defined functions, I do not encounter this error (ERROR 000732: Layer Name or Table View: Dataset targetAreas does not exist or is not supported Failed to execute (SelectLayerByAttribute)). However, when I attempt to consolidate my script into neat functions, the script errors out.

The output should have 9 PDFs in the pdf directory and an Excel sheet with 9 worksheets. I get the desired output when I don't consolidate. However, when I'm iterating the areas in cursor3 (see code snippet below), the first iteration is successful, but the second iteration fails. So my resulting pdf directory only contains one PDF.

# Looping through feature classes
arcpy.MakeFeatureLayer_management(highRiskAreas, 'HRM')
arcpy.MakeFeatureLayer_management(targetAreas, 'targetAreas')
with arcpy.da.SearchCursor('targetAreas', ['Name', 'SHAPE@']) as cursor3:
    for area in cursor3:
        n = 0
        ws = wb.add_sheet('Area {}'.format(area[0]))
        arcpy.SelectLayerByAttribute_management('targetAreas', 
                        where_clause="\"Name\" = '{}'".format(area[0]))
        for fc, fields in fieldDict.items():
            n = featureSelector(fc, fields) + 1
        mapMaker(area[1], area[0])
        wb.save('{}.xls'.format(os.path.splitext(
                os.path.basename(studyArea))[0]))

I've read through other questions with the same error, but can't find anything that specifies my issue.

The full consolidated code is below...

import arcpy, os, shutil, xlwt, time
arcpy.env.overwriteOutput = True

# User Defined Functions
def featureSelector(feature, fields):
    '''
    determines amount of fields in searchcursor
    '''
    global n
    fcShort = os.path.splitext(os.path.basename(feature))[0]
    ws.write(n, 0, fcShort, header)
    arcpy.MakeFeatureLayer_management(feature, fcShort)
    arcpy.SelectLayerByLocation_management(fcShort, 'INTERSECT', 'targetAreas')
    arcpy.SelectLayerByLocation_management(fcShort, 'INTERSECT', 'HRM', 
                                    selection_type='SUBSET_SELECTION')
    with arcpy.da.SearchCursor(fcShort, fields) as cursor1:
        for i, row in enumerate(cursor1, n):
            ws.write(i + 1, 0, row[0], hraFont)
            try:
                ws.write(i + 1, 1, row[1], hraFont)
            except IndexError:
                pass
            n += 1
    arcpy.SelectLayerByLocation_management(fcShort, 'INTERSECT', 'targetAreas')
    arcpy.SelectLayerByLocation_management(fcShort, 'INTERSECT', 'HRM', 
                                    selection_type='REMOVE_FROM_SELECTION')
    with arcpy.da.SearchCursor(fcShort, fields) as cursor2:
        for i, row in enumerate(cursor2, n):
            ws.write(i + 1, 0, row[0], NonHRAFont)
            try:
                ws.write(i + 1, 1, row[1], NonHRAFont)
            except IndexError:
                pass
            n += 1
    return n

def fieldCalc(path = arcpy.env.workspace):
    '''
    Calculates field values for each feature class
    '''
    fcs = arcpy.ListFeatureClasses()
    fieldDict = {}
    for fc in fcs:
        if 'ATM' in fc:
            fieldDict[fc] = ['PRIMARY_AD']
        elif 'Laund' in fc:
            fieldDict[fc] = ['PRIMARY_AD', 'COMPANY_NA']
        elif 'LI_Immin' in fc:
            fieldDict[fc] = ['address']
        elif 'Pawn' in fc:
            fieldDict[fc] = ['IN_SingleL', 'USER_Store']
        elif 'Grocery' in fc:
            fieldDict[fc] = ['PRIMARY_AD', 'COMPANY_NA']
        elif 'Restau' in fc:
            fieldDict[fc] = ['IN_SingleL']
    return fieldDict

def mapMaker(shape, name):
    global pdfDirectory
    # Condition determining landscape or portrait map layout
    if ((shape.extent.XMax - shape.extent.XMin) > 
        (shape.extent.YMax - shape.extent.YMin)):
        mxd = arcpy.mapping.MapDocument(landscapemxd)
        df = arcpy.mapping.ListDataFrames(mxd)[0]
        #arcpy.MakeFeatureLayer_management(targetAreas, 'targetAreas')
        layer = arcpy.mapping.Layer('targetAreas')

        # In order to zoom to the selected targetted area, we need to create a 
        # feature layer
        # However, we don't want it visible on the hard copy map
        # The template mxd has a set symbology and we want to see that
        layer.visible = False
        arcpy.mapping.AddLayer(df, layer)
        arcpy.SelectLayerByAttribute_management(layer, 
                                where_clause="\"Name\" = '{}'".format(name))
        df.extent = layer.getSelectedExtent()
        arcpy.mapping.ExportToPDF(mxd, 
                    os.path.join(pdfDirectory, 'Area_{}'.format(name)))
        arcpy.RefreshActiveView()
    else:
        mxd = arcpy.mapping.MapDocument(portraitmxd)
        df = arcpy.mapping.ListDataFrames(mxd)[0]
        #arcpy.MakeFeatureLayer_management(targetAreas, 'targetAreas')
        layer = arcpy.mapping.Layer('targetAreas')
        layer.visible = False
        arcpy.mapping.AddLayer(df, layer)
        arcpy.SelectLayerByAttribute_management(layer, 
                    where_clause="\"Name\" = '{}'".format(name))
        df.extent = layer.getSelectedExtent()
        arcpy.mapping.ExportToPDF(mxd, os.path.join(pdfDirectory, 
                                    'Area_{}'.format(name)))
        arcpy.RefreshActiveView()

def Start():
    '''
    Calls other functions
    Settings for excel document
    '''
    # Excel Document and settings
    global ws, wb, hraFont, header, NonHRAFont, n, pdfDirectory, area
    wb = xlwt.Workbook()
    hraFont = xlwt.easyxf('font: name Times New Roman, color-index red, bold on')
    header = xlwt.easyxf('font: name Times New Roman, color-index black, bold on')
    NonHRAFont = xlwt.easyxf('font: name Times New Roman, color-index black')
    #areaFont = xlwt.easyxf('font: name Times New Roman, color-index black, height 28')

    # Creating dictionary for environmental features and 
    # their required attributes
    fieldDict = fieldCalc()

    # Creating PDF directory
    pdfDirectory = os.path.join(os.getcwd(), 'pdfs')
    if os.path.exists(pdfDirectory):
        shutil.rmtree(pdfDirectory)
        time.sleep(1)
        os.mkdir(pdfDirectory)
    else:
        os.mkdir(pdfDirectory)

    # Looping through feature classes
    arcpy.MakeFeatureLayer_management(highRiskAreas, 'HRM')
    arcpy.MakeFeatureLayer_management(targetAreas, 'targetAreas')
    with arcpy.da.SearchCursor('targetAreas', ['Name', 'SHAPE@']) as cursor3:
        for area in cursor3:
            n = 0
            ws = wb.add_sheet('Area {}'.format(area[0]))
            arcpy.SelectLayerByAttribute_management('targetAreas', 
                            where_clause="\"Name\" = '{}'".format(area[0]))
            for fc, fields in fieldDict.items():
                n = featureSelector(fc, fields) + 1
            mapMaker(area[1], area[0])
            wb.save('{}.xls'.format(os.path.splitext(
                    os.path.basename(studyArea))[0]))


# Setting Variables
arcpy.env.workspace = r"xxx"
portraitmxd = r"xxx"
landscapemxd = r"xxx"
studyArea = r"xxxx"
targetAreas = r"xxx"
highRiskAreas = r"xxxx"

# Initializing Script
Start()

Full unconsolidated script...

import arcpy, os, shutil, xlwt, time
# Setting Variables
arcpy.env.workspace = r"C:\Users\tuk36101\Desktop\canvasScript\environmentalFeatures"
portraitmxd = r"C:\Users\tuk36101\Desktop\canvasScript\portrait.mxd"
landscapemxd = r"C:\Users\tuk36101\Desktop\canvasScript\landscape.mxd"
studyArea = r"C:\Users\tuk36101\Desktop\canvasScript\NicetownTioga_CanvassingArea.shp"
targetAreas = r"C:\Users\tuk36101\Desktop\canvasScript\targetAreas.shp"
highRiskAreas = r"C:\Users\tuk36101\Desktop\canvasScript\highRiskArea.shp"
# Initialize time
start = time.time()

arcpy.env.overwriteOutput = True

# User Defined Functions
def featureSelector(feature, fields):
    '''
    determines amount of fields in searchcursor
    '''
    fcShort = os.path.splitext(os.path.basename(feature))[0]
    global n
    ws.write(n, 0, fcShort, header)
    arcpy.MakeFeatureLayer_management(feature, fcShort)
    arcpy.SelectLayerByLocation_management(fcShort, 'INTERSECT', 'targetAreas')
    arcpy.SelectLayerByLocation_management(fcShort, 'INTERSECT', 'HRM', selection_type='SUBSET_SELECTION')
    with arcpy.da.SearchCursor(fcShort, fields) as cursor:
        for i, row in enumerate(cursor, n):
            ws.write(i + 1, 0, row[0], hraFont)
            try:
                ws.write(i + 1, 1, row[1], hraFont)
            except IndexError:
                pass
            n += 1
    arcpy.SelectLayerByLocation_management(fcShort, 'INTERSECT', 'targetAreas')
    arcpy.SelectLayerByLocation_management(fcShort, 'INTERSECT', 'HRM', selection_type='REMOVE_FROM_SELECTION')
    with arcpy.da.SearchCursor(fcShort, fields) as featCur:
        for i, row in enumerate(featCur, n):
            ws.write(i + 1, 0, row[0], NonHRAFont)
            try:
                ws.write(i + 1, 1, row[1], NonHRAFont)
            except IndexError:
                pass
            n += 1

    return n

def fieldCalc(path = arcpy.env.workspace):
    '''
    Calculates field values for each feature class
    '''
    fcs = arcpy.ListFeatureClasses()
    fieldDict = {}
    for fc in fcs:
        if 'ATM' in fc:
            fieldDict[fc] = ['PRIMARY_AD']
        elif 'Laund' in fc:
            fieldDict[fc] = ['PRIMARY_AD', 'COMPANY_NA']
        elif 'LI_Immin' in fc:
            fieldDict[fc] = ['address']
        elif 'Pawn' in fc:
            fieldDict[fc] = ['IN_SingleL', 'USER_Store']
        elif 'Grocery' in fc:
            fieldDict[fc] = ['PRIMARY_AD', 'COMPANY_NA']
        elif 'Restau' in fc:
            fieldDict[fc] = ['IN_SingleL']
    return fieldDict

# --------------------------------------------------------------------------------------------------#

# Excel Formatting
hraFont = xlwt.easyxf('font: name Times New Roman, color-index red, bold on')
header = xlwt.easyxf('font: name Times New Roman, color-index black, bold on')
NonHRAFont = xlwt.easyxf('font: name Times New Roman, color-index black')
#areaFont = xlwt.easyxf('font: name Times New Roman, color-index black, height 28')

# Excel Document
wb = xlwt.Workbook()

# Global Layer
arcpy.MakeFeatureLayer_management(highRiskAreas, 'HRM')
arcpy.MakeFeatureLayer_management(targetAreas, 'targetAreas')

# Returning necessary fields for each feature class   
fieldDict = fieldCalc()

# Looping through feature classes
with arcpy.da.SearchCursor('targetAreas', ['Name']) as areaCursor:
    for area in areaCursor:
        n = 0
        ws = wb.add_sheet('Area {}'.format(area[0]))
        arcpy.SelectLayerByAttribute_management('targetAreas', where_clause="\"Name\" = '{}'".format(area[0]))
        for fc, fields in fieldDict.items():
            n = featureSelector(fc, fields) + 1
wb.save('Nicetown.xls')

# Map of Areas
# Final Process

# Housing the map pdfs
pdfDirectory = os.path.join(os.getcwd(), 'pdfs')
if os.path.exists(pdfDirectory):
    shutil.rmtree(pdfDirectory)
    time.sleep(1)
    os.mkdir(pdfDirectory)
else:
    os.mkdir(pdfDirectory)
arcpy.RefreshActiveView()
arcpy.MakeFeatureLayer_management(targetAreas, 'targetAreas')
with arcpy.da.SearchCursor('targetAreas', ['Name', 'SHAPE@']) as cursor:
    for row in cursor:

        # Condition determining landscape or portrait map layout
        if (row[1].extent.XMax - row[1].extent.XMin) > (row[1].extent.YMax - row[1].extent.YMin):
            mxd = arcpy.mapping.MapDocument(landscapemxd)
            df = arcpy.mapping.ListDataFrames(mxd)[0]
            arcpy.MakeFeatureLayer_management(targetAreas, 'targetAreas')
            layer = arcpy.mapping.Layer('targetAreas')

            # In order to zoom to the selected targetted area, we need to create a feature layer
            # However, we don't want it visible on the hard copy map
            # The template mxd has a set symbology and we want to see that
            layer.visible = False
            arcpy.mapping.AddLayer(df, layer)
            arcpy.SelectLayerByAttribute_management(layer, where_clause="\"Name\" = '{}'".format(row[0]))
            df.extent = layer.getSelectedExtent()
            arcpy.mapping.ExportToPDF(mxd, os.path.join(pdfDirectory, 'Area{}'.format(row[0])))
            arcpy.RefreshActiveView()
        else:
            mxd = arcpy.mapping.MapDocument(portraitmxd)
            df = arcpy.mapping.ListDataFrames(mxd)[0]
            arcpy.MakeFeatureLayer_management(targetAreas, 'targetAreas')
            layer = arcpy.mapping.Layer('targetAreas')
            layer.visible = False
            arcpy.mapping.AddLayer(df, layer)
            arcpy.SelectLayerByAttribute_management(layer, where_clause="\"Name\" = '{}'".format(row[0]))
            df.extent = layer.getSelectedExtent()
            arcpy.mapping.ExportToPDF(mxd, r'pdfs\Area{}'.format(row[0]))
            arcpy.RefreshActiveView()

# End time
end = time.time()
total = ('{:.2f} minutes'.format((end-start)/60))
print total
2
  • Try creating targetAreas as a Layer object rather than just a string and passing it in to any function as a parameter that needs it. i.e. target_areas_lyr = arcpy.MakeFeatureLayer_management(targetAreas, 'targetAreas').getOutput(0)
    – user2856
    Commented Mar 3, 2020 at 2:35
  • I applied this method to all instances of 'targetAreas', but it didn't solve the issue. Commented Mar 5, 2020 at 19:43

1 Answer 1

0

I was able to solve this by bringing...

arcpy.MakeFeatureLayer_management(targetAreas, 'targetAreas')

into the for loop directly below it. My speculation is that the feature layer disappears when applied to the mapMaker function so a new feature layer needs to be created for each iteration.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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