3

The Coded Values are not being displayed within numeric order.

Final results look like: [10][13][12][27C][21][22][27A][33][31][30][27B].. How would we display Coded Values in numerical 0-36?

# Name: NEO Gas Systems.py
# Description: Create an attribute domain
# Author: jordan N. Miller
# Date: 02/17/2017


#Import system modules
import arcpy

try:
# Set the workspace (to avoid having to type in the full path to the data        every time)
arcpy.env.workspace = "C:/eis"

# Set local parameters
domName = "Gas Systems"
gdb = "UPDM.gdb"

# Process: Create the coded value domain
arcpy.CreateDomain_management("UPDM.gdb", domName, "Gas Systems", "TEXT", "CODED")

# Store all the domain values in a dictionary with the domain code as the  "key" and the
# domain description as the "value" (domDict[code])
domDict = {"9":"New Bedford", \
"10": "West Wooster",
"12": "Summitville Tile",
"13": "West Warren",
"21": "Winesburg",
"22": "Bowerston",
"27": "NEO/TCO/Timken",
"27A": "Timken Header Line",
"27B": "Timken Industrial Gases",
"27C": "Timken Houseline",
"30": "North Mount Hope",
"31": "Gross Lumber",
"33": "Nova Tech",
"34": "North Lawrence",
"35": "Anchor Hocking Plant #1",
"36": "Anchor Hocking Plant #2"}

# Process: Add valid material types to the domain
# use a for loop to cycle through all the domain codes in the dictionary
for code in domDict:
    arcpy.AddCodedValueToDomain_management(gdb, domName, code, domDict[code])

except Exception as err:
print(err.args[0])
2
  • Final results where? In the feature class properties? Why does it matter if they aren't in order they are still active and accomplish what they need to?
    – NULL.Dude
    Commented Feb 17, 2017 at 20:51
  • Where you are trying to display them? Can you edit your question to include a screenshot?
    – Midavalo
    Commented Feb 17, 2017 at 20:56

3 Answers 3

2

If I'm understanding your problem correctly, the reason your domains aren't showing in numeric order is because a python dictionary is not ordered. Python won't necessarily process it in the order you've written it.

As python lists are processed in order, to overcome this I would create a python list containing the Domain values, and then use the Dictionary to pull through the descriptions.

# Name: NEO Gas Systems.py
# Description: Create an attribute domain
# Author: jordan N. Miller
# Date: 02/17/2017

#Import system modules
import arcpy

# Set the workspace (to avoid having to type in the full path to the data        every time)
arcpy.env.workspace = "C:/eis"

# Set local parameters
domName = "Gas Systems"
gdb = "UPDM.gdb"

# Process: Create the coded value domain
arcpy.CreateDomain_management("UPDM.gdb", domName, "Gas Systems", "TEXT", "CODED")

# List of domain values in load order
domainList = ["9", "10", "12", "13", "21", "22", "27", "27A", "27B", "27C", "30", "31", "33", "34", "35", "36"]

# Store all the domain values in a dictionary with the domain code as the  "key" and the
# domain description as the "value" (domDict[code])
domDict = {"9": "New Bedford",
           "10": "West Wooster",
           "12": "Summitville Tile",
           "13": "West Warren",
           "21": "Winesburg",
           "22": "Bowerston",
           "27": "NEO/TCO/Timken",
           "27A": "Timken Header Line",
           "27B": "Timken Industrial Gases",
           "27C": "Timken Houseline",
           "30": "North Mount Hope",
           "31": "Gross Lumber",
           "33": "Nova Tech",
           "34": "North Lawrence",
           "35": "Anchor Hocking Plant #1",
           "36": "Anchor Hocking Plant #2"}

# Process: Add valid material types to the domain
# use a for loop to cycle through all the domain codes in the dictionary
for code in domainList:
    arcpy.AddCodedValueToDomain_management(gdb, domName, code, domDict[code])

print "Finished!"

If you wish to add another value, add the new code into the domainList and the code/description to the domDict. Just remember to add any new codes in the position you want to see it in the domain drop-down

5
  • OrderedDict
    – Paul
    Commented Feb 17, 2017 at 21:54
  • @Paul Yes Ordered Dictionary is an option, but personally I'm not a fan of constructing them, and I think they're messy and harder to read in the code. But definitely an option.
    – Midavalo
    Commented Feb 17, 2017 at 22:10
  • If you want to be evil, then from collections import OrderedDict as dict and d = dict(a=1, b=2, c=3).
    – Paul
    Commented Feb 17, 2017 at 22:30
  • @Paul - I tried what you posted and I'm not clear about how table = 'in_memory/table' is collecting the path of the geodatabase. When I run the script in ArcCatalog I get the following error: Runtime error Traceback (most recent call last): * *File "<string>", line 25, in <module> RuntimeError: create table I might not be in the right application/location for 'in memory' to read the UPDM.gdb?
    – Jordan
    Commented Feb 20, 2017 at 15:21
  • @Jordan Lets continue this in chat
    – Midavalo
    Commented Feb 20, 2017 at 15:24
2

We've used similar code, which can give significant speedups due to the overhead from multiple GP calls. Don't need to create the domain or add the values in a particular order -- this handles all of it. Just make sure the table is in the correct order, which is why you pass in a list of tuples (could easily be an OrdereDict, but there's no need).

import arcpy
import numpy as np

code_desc = [("9", "New Bedford"),
             ("10", "West Wooster"),
             ("12", "Summitville Tile"),
             ("13", "West Warren"),
             ("21", "Winesburg"),
             ("22", "Bowerston"),
             ("27", "NEO/TCO/Timken"),
             ("27A", "Timken Header Line"),
             ("27B", "Timken Industrial Gases"),
             ("27C", "Timken Houseline"),
             ("30", "North Mount Hope"),
             ("31", "Gross Lumber"),
             ("33", "Nova Tech"),
             ("34", "North Lawrence"),
             ("35", "Anchor Hocking Plant #1"),
             ("36", "Anchor Hocking Plant #2")]


array = np.array(code_desc, dtype=[('code', 'S3'), ('value', 'S50')])

table = 'in_memory/table'    
arcpy.da.NumPyArrayToTable(array, table)
arcpy.TableToDomain_management(table, 'code', 'value', gdb, 'my domain')

Otherwise, just create an OrderedDict with your original code.

from collections import OrderedDict
domDict = OrderedDict(code_desc)
2
  • Works well. Executed in python script, outside of a client session, but with an open client session. The domain did not show up in the client, even after Refreshing the file geodatabase. Had to close and reopen by project before it appeared. Just a note if anyone else tries this and assumes the code wasn't working. Commented Mar 16, 2023 at 11:46
  • Another heads up for other readers - TableToDomain does not support the field_type argument of CreateDomain. This response is certainly correct as originally posed - but will cannot be adapted for non-text field types. Commented Aug 11, 2023 at 16:20
2

OP,

If you simply want to display your coded domain values in ascending order within your domain (so that when the user chooses the drop-down, they are displayed in order from 0-36). Just use this:

arcpy.SortCodedValueDomain_management(gdb, domName, "CODE", "ASCENDING")

It also works well for alphabetising coded {str} values.

Cheers.

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.