I'm trying to create a drop down menu in a Python script in ArcMap where one input is a CSV and the other input is a drop down of the headers in that CSV. Is this possible at all?
In the image above, "Candidate List" is the supplied CSV and "Candidate Field" is the field header that the user selects for the column that the data is located in. Would I have to put something in the script its self or in the update parameters?
with open(Candidate List, "rb") as f:
reader = csv.reader()
i = reader.next()
Wherein I want I to be the fields for that drop down.
2 Answers 2
It is definitely possible. You would need to use script tool validation class.
- Read the .csv headers (can be done with
csv
orpandas
, for instance).
With csv
:
import csv
csv.DictReader(open(r"C:\GIS\grafiti.csv","r")).fieldnames
['FID', 'OBJECTID', 'CID', 'SqFtAprox', 'POINT_X', 'POINT_Y']
With pandas
:
import pandas as pd
pd.read_csv(r"C:\GIS\grafiti.csv").columns.tolist()
['FID', 'OBJECTID', 'CID', 'SqFtAprox', 'POINT_X', 'POINT_Y']
- Use
updateParameters
to set values of the needed parameter to the list of columns.
Code:
self.params[2].filter.list = headers
Please look up the help page for more examples. Another helpful answer is here.
-
The only issue is that the CSV being input will always be different for different users, can this still be implemented?AGH_TORN– AGH_TORN2017年07月27日 20:43:09 +00:00Commented Jul 27, 2017 at 20:43
-
Of course. You will be updating your .csv headers parameter list values every time a user browses to her .csv file. The list values will not be stored within the tool itself; it will be read dynamically upon every tool execution after users specifies the input .csv file.Alex Tereshenkov– Alex Tereshenkov2017年07月28日 03:55:08 +00:00Commented Jul 28, 2017 at 3:55
Found the solution, see below:
def updateParameters(self):
if self.params[4].value and \
(self.params[4].value.value.endswith("xls") or self.params[4].value.value.endswith("xlsx")):
import xlrd
book = xlrd.open_workbook(self.params[4].value.value)
sheet = book.sheet_by_index(0)
headers = [str(cell.value) for cell in sheet.row(0)]
self.params[5].filter.list = headers
-
Hm, isn't it what I have told you to do? ;) in the question, you talk about .csv, now you are reading .xls. But glad you got something working anyways :)Alex Tereshenkov– Alex Tereshenkov2017年07月28日 03:53:59 +00:00Commented Jul 28, 2017 at 3:53
-
It is, yes. I have it configured for both xls and csv depending on user input. I wasn't quite sure how to implement the
self.params[4]
and I wasn't aware that I had to useself.params[4].value.value
in order to actually open the file.AGH_TORN– AGH_TORN2017年07月28日 14:46:24 +00:00Commented Jul 28, 2017 at 14:46
Explore related questions
See similar questions with these tags.