How to control display order of arcpy scripted coded value domain?

2192
12
Jump to solution
07-12-2017 10:33 AM
ChristopherRoss1
New Contributor II

I use a python script to create and populate coded text domain values for an SDE. The script adds the coded values in the order that I want them (using AddCodedValueToDomain_management), which is in order of usefulness, not alphabetical. My problem is that when I review the text domains in Catalog, they are in a scrambled order. Is there a way to control or change this order? 

I am aware of the SortCodedValueDomain_management, but that seems to only allow ascending and descending sorting.

0 Kudos
1 Solution

Accepted Solutions
RhettZufelt
MVP Frequent Contributor

I have a lookup table that I keep my domains in (first column is code, second is description).

If I use the TableToDomain tool with the "replace" option, the dropdown order matches what I have in the original table exactly.  If I ever have to add/remove/modify any of them, I just modify the table, then re-run the script and they are in the order desired.

I'm on 10.2.1, but this works for me:

arcpy.TableToDomain_management("C:/ArcGIS/Default.gdb/sorted","code","desc","C:/ArcGIS/testdomainadds.gdb","sorted","desc","REPLACE")

R_

View solution in original post

12 Replies
ChristopherRoss1
New Contributor II

In lieu of a direct solution, I have opted to change my domains to SHORT rather than TEXT. This is acceptable only because this is a blank database, however, it would be good to have a solution in the event that a database was populated with corresponding text codes.

RebeccaStrauch__GISP
MVP Emeritus

or if text, you can add a number in the front to have it sort by that, ie

1-My first choice

2-a second choice

3-etc.

Not ideal, but at least you can force the sort order.

ChristopherRoss1
New Contributor II

I agree, still not ideal but it is another alternative solution. Thanks for the suggestion.

0 Kudos
RandyBurton
MVP Alum

The Sort Coded Value Domain tool will sort by either code or description in ascending or descending order. As Rebecca Strauch, GISP mentioned you can force the sort order, either using integers or text.  For integers, I'll use a sequence like 1001, 2101, 2102, 2201 ... etc. that allows for insertion of new values at an appropriate place.  I have increasingly used text strings for codes using 2 or three letters for a code that make an understandable abbreviation of the description.  I also have used a combination of letters and numbers for codes, such as  A01, A02, B01, C01, C05 ... etc. where the letter would be an abbreviation for the group and the number would be the order in the group.

If you are using a python script, you might try creating a dictionary of domain codes and values for a custom sort.  Just an idea...‌

ChristopherRoss1
New Contributor II

Here is a dictionary example I used to populated a text domain,

TestDomain = {"ZA":"First Option","AZ":"Second Option","QA":"Third Option","BT":"Fourth Option","TC":"Fifth Option"}

Results:

We can see that it has populated using neither an alphabetical order or the index order of the dictionary.

So while I entered the values in the dictionary using the order I wanted, the result is scrambled as you can see. Do you know of a different way to organize the dictionary that would maintain dictionary order, or is the scramble a function of Add Coded Value To Domain?

At this point I am wondering if we can avoid adding a sortable prefix, which in my opinion, negates the value of using a text code.

0 Kudos
RandyBurton
MVP Alum

Here's an idea:

def sort_it(d, order):
  return  [d[k] for k in sorted(order, key=order.get)]

d = { 'QA': 'Third Option',
      'BT': 'Fourth Option',
      'AZ': 'Second Option',
      'ZA': 'First Option',
      'TC': 'Fifth Option'
      }

order = {
    'ZA': 0,
    'AZ': 1, 
    'QA': 2,
    'BT': 3,
    'TC': 4
    }

print sort_it(d, order)

# ['First Option', 'Second Option', 'Third Option', 'Fourth Option', 'Fifth Option']
0 Kudos
ChristopherRoss1
New Contributor II

Were you able to implement this to solve the output scramble of Add Coded Value To Domain?

AddCodedValueToDomain_management (in_workspace, domain_name, code, code_description)

0 Kudos
RandyBurton
MVP Alum

Since a regular dictionary does not track the insertion order, iterating over it produces the values in order based on how the keys are stored in the hash table.  You need to use some sort of sorting when you iterate it.  Or use an ordered dictionary where the insertion order is remembered.

import collections

domDict = { 'ZA': 'First Option',
            'AZ': 'Second Option',
            'QA': 'Third Option',
            'BT': 'Fourth Option',
            'TC': 'Fifth Option'
            }

print '\nunorderd dictionary'   
for code in domDict:
    print "{} : {}".format(code, domDict[code])

order = {
    'ZA': 0,
    'AZ': 1, 
    'QA': 2,
    'BT': 3,
    'TC': 4
    }

print '\nsorted dictionary'
for code in sorted(order, key=order.get):
    print "{} : {}".format(code, domDict[code])

od = collections.OrderedDict( [
    ('ZA','First Option'),
    ('AZ','Second Option'),
    ('QA','Third Option'),
    ('BT','Fourth Option'),
    ('TC','Fifth Option')
    ] )

print '\nordered dictionary'
for code in od:
    print "{} : {}".format(code, od[code])

# for code in od:
#     arcpy.AddCodedValueToDomain_management(gdb, domName, code, od
)

Even using an ordered dictionary, you still may find your domain isn't in the order you want.  This is why I would recommend using either codes or descriptions that can be sorted using the Sort Coded Domain tool (similar to suggestions in first post).  Then you can add new domain entries and easily resort the domain.

RhettZufelt
MVP Frequent Contributor

I have a lookup table that I keep my domains in (first column is code, second is description).

If I use the TableToDomain tool with the "replace" option, the dropdown order matches what I have in the original table exactly.  If I ever have to add/remove/modify any of them, I just modify the table, then re-run the script and they are in the order desired.

I'm on 10.2.1, but this works for me:

arcpy.TableToDomain_management("C:/ArcGIS/Default.gdb/sorted","code","desc","C:/ArcGIS/testdomainadds.gdb","sorted","desc","REPLACE")

R_