I currently have about fifty rivers and creeks in a map, and none of the features contain the name of the waterbody. However, the features are named correctly in the table of contents

Ideally, I would have a script that created a field named 'NameFromLYR', and then took the name of the feature from the TOC and inserted it into the new field in the attribute table.

This is the script so far:

import arcpy

mxd = arcpy.mapping.MapDocument (r'C:\Users\athom\Documents\ArcGIS\2014\ScriptTest.mxd')

lyrList = arcpy.mapping.ListLayers (mxd)
for lyr in lyrList:
    layerName = lyr.name
    NameVar = lyr.dataSource
    arcpy.AddField_management (NameVar, "NameFromLYR", "TEXT")

    expression = "reClass(!NameFromLYR!)"
    codeBlock = """def reClass(lyrName):
        return (layerName)"""

    arcpy.CalculateField_management (NameVar, "NameFromLYR", expression, "PYTHON", codeBlock)
    print layerName
    del layerName
    del codeBlock

del mxd
del lyr
del lyrList

The script works, but there is one flaw - it uses the name of the first feature in the TOC and inserts it into all the features.

As you can see in the image below, 'AOI' has been added into NameFromLYR field in all the features, not just the feature called AOI.


Does anyone have any hints on what is wrong with this script? It appears as though the name of the first feature in the TOC does not get deleted, as it stays with the script for a few minutes after the features in the TOC have been shuffled, or ArcMap and PyScripter has been turned off and then on again.

I realize that using an update cursor is the smart way (easier and faster), but I have spent enough time on trying to use the arcpy.CalculateField_management that it would be nice to know what is wrong.

EDIT: The script work with an update cursor if the expression, codeBlock and arcpy.CalculateField_management are replaced with this:

with arcpy.da.UpdateCursor (NameVar, "NameFromLYR") as cursor:
    for row in cursor:
        row[0] = layerName

1 Answer 1


Just replace your expression with

expression = '"' + layerName + '"'

and don't use a code block (it's an optional argument, that you can just leave out of the CalculateField call. I would expect that to work.

There's also no reason to be refreshing the TOC every iterations either, as far as I can tell, so I would remove arcpy.RefreshTOC().

  • I knew there was a simpler method than using a code block.
    – Adam Thom
    Oct 30, 2014 at 22:37

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.