1 votos

TabletoExcel_conversión resultados en los encabezados solamente (también Exportar Informe falla, probablemente relacionado)

Así que aquí está el código de mi herramienta de script en su totalidad:

import arcpy
import datetime
import os
import sys
import itertools
import traceback

#Set Environment Variables
arcpy.env.overwriteOutput = True
arcpy.env.workspace = arcpy.GetParameterAsText(1)

#Collect user info from ArcGIS
PTE_layer = arcpy.GetParameterAsText(0)
rlf = arcpy.GetParameterAsText(2)
output_folder = arcpy.GetParameterAsText(3)
pdf = arcpy.GetParameter(4)
excel = arcpy.GetParameter(5)

#Set usefuls for later
today = datetime.datetime.today()
mxd = arcpy.mapping.MapDocument("CURRENT")  
df  = arcpy.mapping.ListDataFrames(mxd)[0]

class ProjectPTE:

    def __init__(self, CIP_ID = None, answer = None):
        self.CIP_ID = CIP_ID
        self.Yes = 0
        self.No = 0
        self.OwnerChange = 0
        self.Other = 0
        self.add(answer)

    def add(self,answer):
        if answer == "Y":
            self.Yes += 1
        elif answer == "N":
            self.No += 1
        elif answer == "New Ownership - Need PTE":
            self.OwnerChange += 1
        else:
            self.Other += 1

    def compare(self,other):
        try:    
            if self.CIP_ID == other.CIP_ID:
                return True
            else:
                return False               
        except AttributeError:
            return False

#Create cursor to move through PTE layer
fields = ["CIP_ID","PTE_Rcvd"]

#Main loop
#Using the ProjectPTE class above to define the rules for comparison,
# initialization, and updating, the loop goes through each row in the PTE
# layer and adds it's information to the project list.  This is accomplished
# by creating a ProjectPTE out of the current row and comparing that ProjectPTE
# with the existing ProjectPTEs in the project list.
project_list = []
pte_count = 0
with arcpy.da.SearchCursor(PTE_layer,fields) as PTE_cursor:
    for row in PTE_cursor:
        pte_count += 1
        CIP_ID = row[0]
        PTE_Rcvd = row[1]
        #Use current row CIP_ID to initialize new ProjectPTE
        current = ProjectPTE(CIP_ID,PTE_Rcvd)

        #Search through project list
        for project in project_list:

            #Compare CIP_IDs of list project and current layer project
            if current.compare(project):          
                #If a match is found, add PTE_Rcvd status to the project's
                # respective variable
                project.add(PTE_Rcvd)
                break           #Stop searching the project_list

        #If break was never reached, no matching CIP_ID was found.  Add current
        # project to project list and update that project's respective attribute
        else:
            project_list.append(current)

arcpy.AddMessage(str(pte_count) + " total PTEs counted for " + str(len(project_list)) + " projects")

del PTE_cursor

#Create a new table and populate it with the information collected in the
# project_list

stat_table = "PTE_Status_" + today.strftime("%Y%m%d")
arcpy.CreateTable_management(arcpy.env.workspace, stat_table)
fields = ["CIP_ID","Yes","No","Change_Owner","Other","Total"]
types = ["TEXT","SHORT","SHORT","SHORT","SHORT","SHORT"]
lengths = 12
for field_name,field_type in itertools.izip(fields,types):
    arcpy.AddMessage("Inserting " + field_name + " : " + field_type)
    arcpy.AddField_management(in_table=stat_table, field_name=field_name,
                              field_type=field_type, field_length=12)

#Create an insert cursor to populate the table
stat_cursor = arcpy.da.InsertCursor(stat_table, fields)

for project in project_list:
   total = project.Yes + project.No + project.OwnerChange + project.Other
    row = [
           project.CIP_ID,
           project.Yes,
           project.No,
           project.OwnerChange,
           project.Other,
           total
          ]
    stat_cursor.insertRow(row)

#Export Reports
export_string = "\\PTE_Status_" + today.strftime("%Y%m%d")
report_table = arcpy.mapping.TableView(stat_table)
#Insert the table into the current map
arcpy.mapping.AddTableView(df, report_table)
arcpy.RefreshTOC()

if report_table == arcpy.mapping.ListTableViews(mxd)[0]:
    arcpy.AddMessage("They are the same!")
else:
    arcpy.AddMessage("They are different!")

try:
    output_location = output_folder + export_string
    os.mkdir(output_location)
except WindowsError:
    pass
except:
    arcpy.AddWarning("Cannot create new folder. Generating files in "
                     "given folder instead.")
    output_location = output_folder

export_stub = output_location + export_string

if pdf:

    arcpy.AddMessage("Writing PDF from " + str(report_table) + " to " + export_stub + ".pdf")
    try:
        export_file = export_stub + ".pdf"
        arcpy.mapping.ExportReport(report_table, rlf, export_file)
    except:
        arcpy.AddWarning("No PDF Written")
        tb = sys.exc_info()[2]
        tbinfo = traceback.format_tb(tb)[0]
        pymsg = "PYTHON ERRORS:\nTraceback info:\n" + tbinfo + "\nError Info:\n" + sys.exc_info()[1].args[0]
        msgs = "ArcPy ERRORS:\n" + arcpy.GetMessages(2) + "\n"
        arcpy.AddWarning(pymsg)
        arcpy.AddWarning(msgs)    

if excel:

    arcpy.AddMessage("Writing spreadsheet from " + report_table.name + " to " + export_stub + ".xls")
    try:
        export_file = export_stub + ".xls"
        arcpy.TableToExcel_conversion(report_table.name, export_file)
    except:
        arcpy.AddWarning("No Excel Spreadsheet written")
        tb = sys.exc_info()[2]
        tbinfo = traceback.format_tb(tb)[0]
        pymsg = "PYTHON ERRORS:\nTraceback info:\n" + tbinfo + "\nError Info:\n" + sys.exc_info()[1].args[0]
        msgs = "ArcPy ERRORS:\n" + arcpy.GetMessages(2) + "\n"
        arcpy.AddWarning(pymsg)
        arcpy.AddWarning(msgs)

El error generado desde Export Report es un IOError: No se pudo escribir el archivo de salida del informe. Esto me indica que el informe se ejecuta correctamente (los campos de mi tabla generada coinciden con los campos de mi rlf) pero no se puede escribir.

No se genera ningún error de TabletoExcel_conversion. La salida, sin embargo, es un .xls válido con las cabeceras de tabla correctas y sin valores de atributo.

La tabla se ha creado correctamente y se ha añadido a mi mapa. Entonces puedo ejecutar manualmente la herramienta de geoprocesamiento TabletoExcel y exportar el informe a PDF desde ArcMap sin ningún problema. No hay ninguna razón por la que estas herramientas no se pueden ejecutar dentro de una herramienta de script ArcTool.

He hecho todas las pruebas que se me han ocurrido. Algunas todavía están en mi código (como la comprobación para ver si mi variable objeto TableView es la misma que la TableView en mi mapa). No veo ninguna razón por la que estas herramientas no estén funcionando correctamente. Sin embargo, creo que el error generado por ExportReport está directamente relacionado con la falta de datos escritos por TabletoExcel_conversion. No sé por qué ambas herramientas pueden ver mi tabla y los nombres de los campos pero no pueden leer los atributos.

Nota interesante: http://pro.arcgis.com/en/pro-app/tool-reference/conversion/table-to-excel.htm indica que la herramienta acepta un objeto TableView. Cuando paso "report_table" como objeto TableView, obtengo el siguiente error de ejecución:

Traceback (most recent call last):
  File "c:\program files\arcgis\desktop10.3\ArcToolbox\Scripts\TableToExcel.py", line 222, in <module>
    arcpy.GetParameter(3))
  File "c:\program files\arcgis\desktop10.3\ArcToolbox\Scripts\TableToExcel.py", line 190, in table_to_excel
    with arcpy.da.SearchCursor(in_table, field_names) as cursor:
RuntimeError: cannot open 'GPT0'

Cuando lo ejecuto como está actualmente (atributo TableView.name), crea las cabeceras sólo .xls. Estoy asumiendo que el nombre de cadena proporcionada genera una búsqueda de la tabla utilizando el espacio de trabajo por lo que encontrar con éxito la tabla. Sin embargo, la ayuda de la herramienta indica específicamente que un objeto TableView se debe pasar, no un nombre de cadena de la tabla.

Sí, la tabla existe, existe en mi mapa, se puede imprimir fila por fila en la ventana de mensajes, etc.

He utilizado con éxito herramientas similares para otros fines, algunos mucho más complicados. Esta me tiene perplejo. He incluido todo mi código porque en este punto el problema podría estar en cualquier parte. Esta debería ser la parte fácil.

1voto

BJ Clark Puntos 1648

De acuerdo. Responderé a mi propia pregunta.

Recuerda siempre borrar tus cursores cuando hayas terminado con ellos. Yo no borré mi cursor de inserción, por lo que cada acceso posterior a la tabla fue golpeado con el bloqueo que el cursor de inserción colocó en ella. Ese bloqueo permitía la creación de nuevos cursores, pero no el acceso a los datos.

Tras añadir del stat_cursor a mi código después del bucle que utiliza el cursor, ahora todo funciona

headpalm

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X