1

I can get the following code to run in an mxd with a single dataframe. I need it, however, to run and loop through an mxd that has multiple dataframes with identically named files and data sources to those in my lyrlist.

EDIT Additional Info - The intent of the last if statement was to provide a workaround for the inability of arcpy to set the Display Expression in the layer properties dialog by re-adding a file with a name field. So, the crux of the question is how best to update a layers Display Expression in an automated a way as possible (preferably with python as I have no familiarity with ArcObjects).

import arcpy
lyrlist = ['Inset Bridges','Bridges', 'Transportation Points', 'Transportation Lines']
mxd = arcpy.mapping.MapDocument("Current")
dflist = arcpy.mapping.ListDataFrames(mxd)
for df in dflist:
   if df.scale <= 126720:
      for lyr in (arcpy.mapping.ListLayers(mxd, "", df)):
         if lyr.supports("DEFINITIONQUERY"):
            if lyr.name in lyrlist:
                NewFile = arcpy.mapping.Layer(lyr.dataSource)
                OldFN = lyr.name
                NewFile.name ="NewFi"
                lyr.name = "OldFi"
                arcpy.mapping.InsertLayer(df, lyr, NewFile, "AFTER")
                #the following line results in the ValueError when run in an
                #mxd that has multiple dataframes with filenames from lyrlist
                updateLyr = arcpy.mapping.Layer("NewFi")
                sourceLyr = arcpy.mapping.Layer("OldFi")
                arcpy.mapping.UpdateLayer(df, updateLyr, sourceLyr, True)
                updateLyr.name = OldFN
                arcpy.mapping.RemoveLayer(df, lyr)
arcpy.RefreshTOC()
arcpy.RefreshActiveView
print "script complete"
del mxd

The code works well until it gets to the where I assign the updateLyr variable. That gives me the following error:

Runtime error Traceback (most recent call last):

File "", line 44, in

File "c:\program files (x86)\arcgis\desktop10.1\arcpy\arcpy\arcobjects\mixins.py", line 389, in init super(LayerMixin, self).init(lyrfile)

File "c:\program files (x86)\arcgis\desktop10.1\arcpy\arcpy\arcobjects_base.py", line 47, in init for arg in args))

ValueError: Object: CreateObject Layer invalid data source

  • 1
    Do you have an invalid layer in there somewhere? (red exclamation mark next to it) Check the isBroken property of the layer object. – Michael Stimson Aug 21 '14 at 21:50
  • The mxd checked out ok with no broken/invalid layers. – Bernie Aug 22 '14 at 13:15
  • Would you be able to edit your question to include a text explanation of what you are trying to achieve within your last if statement, please? – PolyGeo Aug 22 '14 at 22:52
1

To debug this I recommend that you change:

for df in dflist:
   if df.scale <= 126720:
      for lyr in (arcpy.mapping.ListLayers(mxd, "", df)):
         if lyr.supports("DEFINITIONQUERY"):

to:

for df in dflist:
   if df.scale <= 126720:
      for lyr in (arcpy.mapping.ListLayers(mxd, "", df)):
         print df.name + ": " + lyr.name
         if lyr.supports("DEFINITIONQUERY"):

I have not tested the above but it should let you pinpoint the data frame and layer within it that is triggering your error.

  • Your line illustrates my problem but I'm not sure how to overcome it. My hang up tied to having multiple dataframes with identical file names. If I run my script in an mxd with one df, it executes without error. In an mxd with multiple dfs, the error pops up on the first df iteration. – Bernie Aug 22 '14 at 13:20
  • 1
    It is hard to help without see the output against a known dataset, and then looking at the code that throws the error against that. I recommend that you create a test MXD with one data frame to which you add one layer, and then make a copy of that data frame in the same mxd. Running your code against that and posting the output and error should make this easy to advise on. – PolyGeo Aug 22 '14 at 22:39
1

I got good debugging ideas which helped me ultimately come up with my solution which ended up being simpler than what I was trying to do. Basically, I let the arcpy UpdateLayer do more of the work of fixing my Display Expression problem. I'm not sure what was the source of my original problem but the following solution did what I wanted:

* EDIT Here's my solution. It's been edited to change the last UpdateLayer parameter to False. This was critical as it then applies the whole layer template and not just the legend to the file whose Display needed updating. See ESRI's documentation for more info.

import arcpy
mxd = arcpy.mapping.MapDocument("Current")
dflist = arcpy.mapping.ListDataFrames(mxd)
for df in dflist:
    if df.scale <= 126720:
        for lyr in (arcpy.mapping.ListLayers(mxd, "", df)):
            if lyr.supports("DEFINITIONQUERY"):
                if lyr.name == "Bridges":
                    sourceLyr = arcpy.mapping.Layer(r"C:\Bridgefile.lyr")
                    arcpy.mapping.UpdateLayer(df, lyr, sourceLyr, False)
                    print lyr.name + " updated"
                elif lyr.name == "Transportation Lines":
                    sourceLyr = arcpy.mapping.Layer(r":C:\TransFile.lyr")
                    arcpy.mapping.UpdateLayer(df, lyr, sourceLyr, False)
                    print lyr.name + " updated"

arcpy.RefreshTOC()
arcpy.RefreshActiveView
print "script complete"
del mxd

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.