1

I am creating my first tool in a Python Toolbox (*.pyt) to export a list of fieldnames to Excel. I have the following bits of code:

import arcpy


class Toolbox(object):
    def __init__(self):

        self.label = "Toolbox"
        self.alias = "Field to Table"
        self.tools = [Tool]

class Tool(object):
    def __init__(self):

        self.label = "Tool"
        self.description = "Export Fields to Table"
        self.canRunInBackground = False

    def getParameterInfo(self):
        param0 = arcpy.Parameter(
        displayName="Shapefile",
        name="shapefile",
        datatype="DEShapefile",
        parameterType="Required",
        direction="Input")

        param1 = arcpy.Parameter(
        displayName="Field Table",
        name="datafile",
        datatype="DETable",
        parameterType="Required",
        direction="Output")

        params = [param0, param1]
        return params

    def isLicensed(self):
        return True

    def updateParameters(self, parameters):
        return

    def updateMessages(self, parameters):
        return

    def execute(self, parameters, messages):
        shapefile = params[0].valueAsText 
        fields = arcpy.ListFields(shapefile) 
        datafile = params[1].valueAsText 
        spreds = open (datafile, 'w')
        for f in fields:
            spreds.write(f.name + "\n")

        spreds.close()
        return

Firstly, the actual execution part of the code works fine as I have tested it. I'm not sure what's wrong when I convert to a .pyt file.

Once I have got this working, is there anyway to create a parameter within the tool to create a new excel/dbf file, and run the script with that information, rather than having to create one first, before running the script. I hope that makes sense.

3
  • 1
    Sure. Change the direction of param1 to output. In python, using the "w" parameter on open() creates the file if it doesn't exist.
    – Paul
    Aug 18, 2015 at 17:09
  • If I create another parameter to let the user specify the workspace folder/area, will the excel file be created in that folder?
    – MacroZED
    Aug 19, 2015 at 7:57
  • @Zahir No, your param1 will have the full path, no need to add another parameter.
    – user2856
    Aug 19, 2015 at 11:56

2 Answers 2

3

The answer by @jbosq addresses the issue accessing the parameters and your indentation errors.

However, the code as is will open the path to excelfile as a text file, not an Excel spreadsheet and just write the field names separated by a newline to this text file. You need to use xlwt (for .xls Excel 2003 binary spreadsheets) or openpyxl (for .xlsx Excel 2007+ OOXML spreadsheets) or arcpy.management.CreateTable/arcpy.da.InsertCursor instead of the builtin python open() function.

Additionally (per @Paul's comment), change direction="Input" to direction="Output") for param1.

Finally, if you write the data to the spreadsheet using xlwt or openpyxl instead of arcpy.management.CreateTable/arcpy.da.InsertCursor you need change param1 datatype from DETable to DEFile and add a filter i.e. param1.filter.list = ['xls'] (if using xlwt) or param1.filter.list = ['xlsx'] (if using openpyxl).

1
  • Eventually, the list of fields to be exported to a table of sorts to be used within another model (already created), this doesn't have to be in excel. Would it be better for me to use DBF or another table? If so, how can I create a parameter for the user to identify a workspace, and then for the new table to be created, with the field list, within that workspace?
    – MacroZED
    Aug 19, 2015 at 14:25
2

I believe your main problem is in how the parameters are passed to the execute. Defining object parameters works like a function where declarations are not global. Give this a try:

def execute(self, params, messages): #params is your parameter list from getParameterInfo
    shapefile = params[0].valueAsText #first parameter from your list
    fields = arcpy.ListFields(shapefile) #capitalization maters
    excelfile = params[1].valueAsText #second parameter from your list
    spreds = open (excelfile, 'w')
    for f in fields:
       spreds.write(f.name + "\n")

    spreds.close()
    return

For more info: Accessing parameters within a Python toolbox

Also: Indent object def, add class Toolbox(object) as shown in this example and change GPShapefile to DEShapefile or GPLayer according to data types

5
  • Instead of creating and writing to an excel file, can I use a DBF file instead?
    – MacroZED
    Aug 19, 2015 at 10:40
  • @Zahir Yes you can output to a DBF instead. You would have to use a dbf module or the arcpy.management.CreateTable/arcpy.da.InsertCursor functions as you can't use the python open() function to write dbf's.
    – user2856
    Aug 19, 2015 at 12:00
  • I have amended the code (as suggested above) and the tool now has a user interface and allows me to specify parameters. It allows me to input a shapefile, and automatically suggests a filename for the DBF file (note, not an excel file) But get an error: line 47 global name 'params' is not defined. I have also updated my original questions code block to show what I have now.
    – MacroZED
    Aug 19, 2015 at 14:45
  • I have found the error and have corrected it. Another question...how to I get FIELDS as my column heading in the DBF file?
    – MacroZED
    Aug 19, 2015 at 14:59
  • When I plug in the shapefile, it automatically creates a name for the table. Is there a way to edit this within the parameter window?
    – MacroZED
    Aug 19, 2015 at 15:12

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.