Importing domains from Excel

14445
13
Jump to solution
07-10-2017 08:04 AM
MagnusPersson
New Contributor

Hi,

I am building a geodatabase which is supposed to contain A LOT of domains to be used in ArcGIS online and Collector.

Soo, i want to import all domains, 30-40 of them, to ArcMap instead of typing them in which would take forever.

Do you guys have an indea of how to do that?

13 Replies
HannahHutchins1
New Contributor II

Hey Randy,

Thank you for getting back to me!

Your descriptions help but unfortunately due to my lack in Python skills, I can't seem to produce anything. All I did to your first script was change the geoDB and excelWB environments to my working documents. 

When I run your first script, I get this error (see graphic below) and all it produces is one table in my geodatabase called "Domain1", which isn't correct.

I know I'm missing something - I'm guessing I have to change something more in your script but I can't figure out where.

I have my Excel document with domains attached.

Any insight would be helpful!

Thanks

0 Kudos
RandyBurton
MVP Alum

You would need to change the dbTable name to one of your tab names: 

# line 76 and 84 from above -- change from
    dbTable = "Domain1"
# to
    dbTable = "AccessSts" # a tab name in your workbook that you want to become a table‍‍‍‍

The section of the code above after line 72 sets up the values used in the new_table function.  In the example code, it creates 2 tables using 2 tabs in an Excel file.

Another way to read lots of tabs into domains without creating tables:

import xlrd
import arcpy
from arcpy import env

# name of geodatabase
geoDB = r"C:\Users\Randy\Documents\ArcGIS\PythonScripts\domains\domain_test.gdb"

# name of excel workbook
excelWB = r"C:\Users\Randy\Documents\ArcGIS\PythonScripts\domains\Parks_Domains.xlsx"

# lots of sheets in excel workbook, let's loop through them
xls = xlrd.open_workbook(excelWB, on_demand=True)
tabs = xls.sheet_names() # <- remeber: xlrd sheet_names is a function, not a property

isNum = ['ZipCode'] # list of tabs whose domain code is a number (not a number as text)

for tab in tabs:
    print "Processing tab: {}".format(tab)
    if tab in isNum: # if tab name is in number list, set type to long integer (or "SHORT")
        fldType = "LONG"
    else: # otherwise, set it to text
        fldType = "TEXT"

    print "\tCreating domain"
    arcpy.CreateDomain_management(in_workspace= geoDB, # geodatabase
                              domain_name= tab, # tab name will be the domain name
                              domain_description= tab, # tab name will be the description
                              field_type= fldType, # set field type
                              domain_type= "CODED", # this is a coded value domain
                              split_policy= "DEFAULT",
                              merge_policy= "DEFAULT")

    print "\tAdding codes and descriptions:"
    sheet = xls.sheet_by_name(tab)
    num_rows = sheet.nrows - 1
    
    curr_row = 0
    while curr_row < num_rows:
        curr_row += 1
        cd, desc = sheet.row_values(curr_row)
        if fldType == "LONG": # if field type is long integer
            cd = int(cd) # convert code to integer
        print "\t\t{}\t{}".format(cd, desc)
        arcpy.AddCodedValueToDomain_management(in_workspace= geoDB,
                                       domain_name= tab, # tab name is the domain name
                                       code= cd,
                                       code_description= desc)

print "Done."

This uses a couple of other arcpy functions: Create Domain and Add Coded Value To Domain.  The basic flow of the program is to add a domain for every tab in the workbook.  It assumes a setup similar to the one in your Excel file.

Hope this helps.

AndresCastillo
MVP Regular Contributor

"The worksheets for domains should have at least two columns (CODE and DESCRIPTION), but other related columns could be added. If the domain is being used to track employee activities, the domain code can link to the employee table and provide access to related information. "

Hi Randy, I don't understand why someone would add more than just code and description fields to the excel, when the other columns are not used in the code, such as:

arcpy.CreateTable_management
arcpy.AddField_management

arcpy.TableToDomain_management
arcpy.SortCodedValueDomain_management
arcpy.CreateDomain_management
arcpy.AddCodedValueToDomain_management

How can the domain code link to the employees table and provide access to related information?

A join?

By the way, beautiful code.

RandyBurton
MVP Alum

The basic idea is that a join could be made on the employee domain code in a feature layer to the employee code in an employee table.  For example, a study to evaluate access to tobacco products by underage youth could use something similar to an employee table.  The feature point layer would have known tobacco vendors and contain a domain for an underage youth and a yes-no domain for a successful tobacco purchase.  The table for the youth would also contain age, gender and other relevant information.  An analysis could be done to answer a question like where are underage girls more likely to access tobacco products and if the attempts were sufficiently gender neutral.  For this, you would need somewhere to store the information about the youth; a table in the database is an option. Then a domain can be created from this table.  But the project could also be organized in many other ways.  This is just one of them.