Select to view content in your preferred language

Two issues creating a script tool

6464
25
07-17-2015 07:35 AM
BradJones
Deactivated User

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

0 Kudos
25 Replies
BradJones
Deactivated User

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.

0 Kudos
WesMiller
Deactivated User

Have a good weekend

0 Kudos
WesMiller
Deactivated User

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()  
 
0 Kudos
IanMurray
Honored Contributor

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

0 Kudos
BradJones
Deactivated User

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. 

0 Kudos
LukeWebb
Frequent Contributor

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!

0 Kudos