I wondering how could we labeling a layer with the values of stand-alone table (that is associated to the layer with 1-Many relationship)

For example, I wanted to label the parcels with their owners knowing that the parcel layer is associated with owners table with 1-Many relationship.

What might be the best practice to perform this task?

enter image description here enter image description here enter image description here enter image description here

2 Answers 2


You can do this by adapting the code in my Blog called Creating Labels with Related Table Data to your data. You do not have to concatenate the two fields in your table, but you do need to adapt the code to create a composite key for the dictionary key. Here is how the code could be adapted for your label (I am only using the English named field names in my example, since I do not use or understand Arabic). Make sure you change the parser for the Label to Python. I did not test the code with my own data, but I believe it should work once you supply the Related Table Path for the line that reads relatedFC = r"C:\YourPath\YourRelatedTableName" and change the field names to Arabic for the feature class (any unquoted field name in brackets).

# Initialize a global dictionary for a related feature class/table
relateDict = {}
def FindLabel ( [ParcelNumber], [BlockNumber] ):
  # declare the dictionary global so it can be built once and used for all labels
  global relateDict
  # only populate the dictionary if it has no keys
  if len(relateDict) == 0:
    # Provide the path to the relate feature class/table
    relateFC = r"C:\YourPath\YourRelatedTableName"
    # create a field list with the relate fields first (ParcelNumber, BlockNumber), 
    # followed by sort field(s) (OwnerName_Arabic)
    relateFieldsList = ["ParcelNumber", "BlcokNumber", "OwnerName_Arabic"]
    # process a da search cursor to transfer the data to the dictionary
    with arcpy.da.SearchCursor(relateFC, relateFieldsList) as relateRows:
      for relateRow in relateRows:
        # store the key value in a variable so the relate value 
        # is only read from the row once, improving speed
        relateKey = tuple(relateRow[0], relateRow[1])
        # if the relate key of the current row isn't found 
        # create the key and make it's value a list of a list of field values
        if not relateKey in relateDict:
          # [searchRow[2:]] is a list containing
          # a list of the field values after the key.
          relateDict[relateKey] = [relateRow[2:]]
          # if the relate key is already in the dictionary 
          # append the next list of field values to the 
          # existing list associated with the key
    # delete the cursor, and row to make sure all locks release
    del relateRows, relateRow
  # store the current label feature's relate key field value
  # so that it is only read once, improving speed
  labelKey = tuple([ParcelNumber], [BlockNumber])
  # start building a label expression.
  # My label has a bold key value header in a larger font
  expression = '<FNT name="Arial" size="12"><BOL>Parcel {} Block {}</BOL></FNT>'.format(labelKey[0], labelKey[1])
  # determine if the label key is in the dictionary
  if labelKey in relateDict:
    # sort the list of the list of fields
    sortedList = sorted(relateDict[labelKey])
    # add a record count to the label header in bold regular font
    expression += '\n<FNT name="Arial" size="10"><BOL>Owner Count = {}</BOL></FNT>'.format(len(sortedList))
    # process the sorted list
    for fieldValues in sortedList:
       # append related data to the label expression
       # my label shows a list of related
       # owners sorted in alphabetical order
       expression += '\n{}'.format(fieldValues[0])
    # clean up the list variables after completing the for loop
    del sortedList, fieldValues
    expression += '\n<FNT name="Arial" size="10"><BOL>Owner Count = 0</BOL></FNT>'
  # return the label expression to display
  return expression

The Blog provides examples of ways to format your list of owners, especially if you want multiple fields from the owners table laid out in a table like format. You also will need to change the font from Arial to a font that works for Arabic.


I think ArcGIS will take care of it for you once you've joined the table to the feature layer. Here is a tutorial that goes through it in some detail, http://grindgis.com/software/arcgis/arcgis-plotting-multiple-values though i can't vouch for the vba scripting.

The step you are missing is to have a unique primary/foreign key pair to perform the join. At the moment 'parcel number' and 'block number' form a 'composite' or 'concatenated' key. To create a unique key you could create a new field in both tables to act as a unique primary key. To populate this new field use field calculator to convert the block number and parcel number to strings and concatenate them. Remember to include a hyphen or similar in between, else 15 and 6 will come out the same as 1 and 56.

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.