I have this script below. When the three arguments are set as variables and I run the script in the ArcMap Python window to test it it runs perfectly. I created a tool for this script. In the parameters for the tool properties I have the Data Types for the 3 arguments are set as "SQL expressions" and all the data types for the feature layers created are "Feature Layers" with a "Type: Derived" and "Direction: Output".
First problem: when I run the tool with the script as is i get this error 'RuntimeError: LayerObject: Set attribute showLabels does not exist'. I remove the code block that applies the labels then I get this error 'ValueError: Unknown value for Extent argument'. Running the script in the mxd both code blocks work perfectly.
Second Problem: I remove both code blocks from the script and run the tool and nothing happens. No errors. Just doesn't add layers.
# Import modules import os, arcpy # Set arguments pws = arcpy.GetParameterAsText(0) ass_pws = arcpy.GetParameterAsText(1) mtr_recpws = arcpy.GetParameterAsText(2) # Set variables sources = r"V:\Source Water Protection\SWAP Model\SWAP.code_newrasters\GIS\SWAP.gdb\sources" # Will need to change if used outside of SWPP staff because of directory permissions. "Sources" feature class is in WATER_FACILITY.gdb assessment = r"V:\Source Water Protection\SWAP Model\SWAP.code_newrasters\GIS\SWAP.gdb\assessment_areas" # Will need to change if used outside of SWPP staff because of directory permissions. "Assessments" feature class not in WATER_FACILITY.gdb.. meter = r"V:\WATER_FACILITY\WATER_FACILITY.gdb\MASTER_METER" files = ["BACTI", "DBP", "DBP_STAGE2", "OFFICE", "PRV", "PUMP_STATION", "SERVICE_AREA_COMBO", "TANK", "VALVE_MISCELLANEOUS", "WTP"] # list all names used for feature classes ans .lyr files. layers = ["Bacti", "DBP", "DBP Stage 2", "Office", "PRV", "Pump Station", "Service Area", "Tank","Valve", "Water Treatment Plant"] src_layer = "Source" ass_layer = "Assessment Area" mtr_layer = "Master Meter" src_symb = r"V:\Source Water Protection\PWS_ID_Tool\SOURCE.lyr" ass_symb = r"V:\Source Water Protection\PWS_ID_Tool\ASSESSMENT.lyr" mtr_symb = r"V:\Source Water Protection\PWS_ID_Tool\MASTER_METER.lyr" root = r"V:\WATER_FACILITY\WATER_FACILITY.gdb" symRoot = r"V:\Source Water Protection\PWS_ID_Tool" # Create directory paths, make feature layers, and apply symbologies. for i, file in enumerate(files): path = os.path.join(root, files) # Create directory path for featureclasses symPath = os.path.join(symRoot, files + ".lyr") # Create directory path for .lyr files arcpy.MakeFeatureLayer_management(paths, layers, pws) # Make all the layers from "files" list arcpy.ApplySymbologyFromLayer_management(layers, symPaths) # Apply the symbologies from "symNames" list. arcpy.MakeFeatureLayer_management(assessment, ass_layer, ass_pws) arcpy.ApplySymbologyFromLayer_management(ass_layer, ass_symb) arcpy.MakeFeatureLayer_management(meter, mtr_layer, mtr_recpws) arcpy.ApplySymbologyFromLayer_management(mtr_layer, mtr_symb) arcpy.MakeFeatureLayer_management(sources, src_layer, pws) # Ordered to have the "Source" layer in the 0 position. arcpy.ApplySymbologyFromLayer_management(src_layer, src_symb) # Apply label mxd = arcpy.mapping.MapDocument("CURRENT") # Reference to current open map document. Could insert path. layer = arcpy.mapping.ListLayers(mxd, "")[0] # Indexing for first layer in table of contents. "Make feature layers" functions ordered so "Source" is in 0 position. if layer.supports("LABELCLASSES"): for lblclass in layer.labelClasses: lblclass.showClassLabels = True lblclass.expression = '"%s" & [SOURCE_ID] & "%s"' % ("<CLR red='255'><FNT size = '12'>", "</FNT></CLR>") layer.showLabels = True arcpy.RefreshActiveView() #Apply extent from "Source" layer mxd = arcpy.mapping.MapDocument("CURRENT") # Using current map, can also use a path to an mxd here df = arcpy.mapping.ListDataFrames(mxd)[0] lyr = arcpy.mapping.ListLayers(mxd, "", df)[0] ext = lyr.getExtent() df.extent = ext
Message was edited by: Brad Jones
Thanks, Wes. I will give that a try on Monday. I'm packing up and heading home for the weekend. I will let you know then. I feel like Python opened a can of whoop-ass on me the last couple of hours.
Have a good weekend.
Have a good weekend
In addition to what Ian Murray said you may want to try the code as posted below. That way if the layer doesn't support label classes it will just skip it. I tested with a group layer and a raster layer neither support label classes it worked fine for the raster that supports extent and bombed on the group layer. Don't forget to change the field name
mxd = arcpy.mapping.MapDocument("CURRENT") # Using current map, can also use a path to an mxd here df = arcpy.mapping.ListDataFrames(mxd)[0] lyr = arcpy.mapping.ListLayers(mxd, "", df)[0] #Check to see if layer supports label classes #http://resources.arcgis.com/en/help/main/10.1/index.html#//00s30000002t000000 if lyr.supports("LABELCLASSES"): for lblclass in lyr.labelClasses: lblclass.showClassLabels = True lblclass.expression = '"%s" & [Type] & "%s"' % ("<CLR red='255'><FNT size = '12'>", "</FNT></CLR>") lyr.showLabels = True #Apply extent from "Source" layer ext = lyr.getExtent() df.extent = ext arcpy.RefreshActiveView()
I would make sure you are getting the correct layer with layer = arcpy.mapping.ListLayers(mxd, "")[0]. It seems like you are returning a layer that doesn't support layer.showLabels, which is what is crashing it. You do a good a job checking it for the for-loop but don't check again after it when you put in layer.showLabels = True. If the layer it accessing doesn't support it, it will crash.
Try commenting out everything after:
layer = arcpy.mapping.ListLayers(mxd, "")[0]
and then adding
print layer.name
Perhaps you aren't getting the layer you think you are getting
The fixed script runs fine in the Python window but not as a tool, including adding labels and extent. But when run as a tool the layers don't get created. Doing a search i found this thread about the layers not being added. Once I get the layer to add to the mxd then I can debug the rest of the script. Today I'm travelling to a conference so I wont be able to work on it much.
When you run a script as a tool, depending on configuration, it does not add the 'layers' from the script to your 'MXD', they happen in different processes and are not connected.
You are trying to refer to layers that exist within the "Python" process, that you have not added to the "MXD" at any point, so when you run listDatasets[0], it is returning whatever is already inside the MXD at the top at the time your tool was run, not any of the layers you created earlier in the script.
To fix this, add the layers to the MXD within the code if you want to refer to them later on!