The script below imports a spreadsheet into ArcMap and generates a shapefile. Currently, I can use the ArcMap tool that interfaces with the script to navigate to the spreadsheet I want to import. This tool will be used periodically to import from several spreadsheets, and I'd like to have the tool interface be just a dropdown, where each item links to a corresponding spreadsheet. Is this possible?
# Author: John K. Tran
# Contact: [email protected]
import arcpy
import os
from os import listdir
import csv
print "arcpy imported"
"""
Input CSV can look like:
Lat,Lon,First Name,Last Name
12.34,56.78,Joe,Smith
0.98,7.65,Jane,Doe
65.43,43.21,Bob,Sagat
Make sure 'Lat' and 'Lon' fields are the 1st and 2nd column in the CSV
respectively.
"""
incsv = arcpy.GetParameterAsText(0)
#Change this to the path of your CSV file.
outfc = r'N:\ReferenceMaterials\ArcGIS Python\Pavement Cores by County\A
Interim Shapefiles' + '\\' + arcpy.GetParameterAsText(1) + '.shp'
#Change this to the path of your output FC.
spatialref = arcpy.SpatialReference(4326)
#Create the spatial reference object as WGS84. Can modify if desired.
testData = r'N:\ReferenceMaterials\ArcGIS Python\Pavement Cores by County\A
Interim Shapefiles'
if len(os.listdir(testData)) == 0:
pass
else:
for t in listdir(testData):
if t.endswith('.shp'):
arcpy.Delete_management(os.path.join(testData, t))
arcpy.CreateFeatureclass_management(os.path.dirname(outfc),
os.path.basename(outfc), "POINT", None, None, None, spatialref)
csv.register_dialect("xls", delimiter=",", lineterminator="\n")
#Register the dialect for native CSV syntax in Microsoft Excel.
f = open(incsv, "r")
reader = csv.reader(f, dialect = "xls")
headers = reader.next() #Read the first line as the header names.
for header in headers[2:]:
#Add fields for remaining columns if needed. Default is TEXT field.
arcpy.AddField_management(outfc, header, "TEXT")
cursor = arcpy.da.InsertCursor(outfc, ['SHAPE@XY'] + headers[2:])
#Create InsertCursor.
count = 0
for row in reader:
if count % 1000 == 0:
print "processing row {0}".format(count)
Ycoord = row[0] # Make sure 'Lat' is in the 1st column.
Xcoord = row[1] # Make sure 'Lon' is in the 2nd column.
newrow = [(float(Xcoord), float(Ycoord))] + row[2:]
cursor.insertRow(newrow) # Insert point in FC for each row in CSV.
count += 1
del cursor
f.close()
1 Answer 1
Yes, you can do this using a script tool validator. You would also need to configure the parameter (in the tool's properties) to 'Value List' for its 'Filter' property.
See the documentation at: Customizing script tool behavior
As the doco says,
Validation is everything that happens before a tool's OK button is clicked.
This can include populating the list of items in a drop-down.
There are some examples of code on the linked page.
The only odd part of how all this works (in my opinion) is that the Python validator class is NOT part of your script tool's script itself, but instead it is a separate Python script that is stored within the script properties. In the script properties, click on the 'Validation' tab, and then the 'Edit' button to edit the script. NB: You should configure ArcMap to use your preferred Python IDE as the editor, otherwise you'll be stuck editing your script in Notepad, or some other plain text editor.
Below is an example of how it could look for your particular case. Note that this is simply the default Validator script with only two lines added - the excelDir global variable at the top, and the prameter filter list assignment in initializeParameters()
.
import arcpy, os
excelDir = "C:/path/to/ExcelFiles"
class ToolValidator(object):
"""Class for validating a tool's parameter values and controlling
the behavior of the tool's dialog."""
def __init__(self):
"""Setup arcpy and the list of tool parameters."""
self.params = arcpy.GetParameterInfo()
def initializeParameters(self):
"""Refine the properties of a tool's parameters. This method is
called when the tool is opened."""
self.params[0].filter.list = sorted([os.path.join(excelDir, filename) for filename in os.listdir(excelDir) if file.endswith(".xlsx") or file.endswith(".xls")])
return
def updateParameters(self):
"""Modify the values and properties of parameters before internal
validation is performed. This method is called whenever a parameter
has been changed."""
return
def updateMessages(self):
"""Modify the messages created by internal validation for each tool
parameter. This method is called after internal validation."""
return
Explore related questions
See similar questions with these tags.