Script Tool to calculate field with selected rows not working

1070
15
Jump to solution
06-05-2024 09:17 AM
MichaelBowers
Emerging Contributor

Although having a few years experience using ArcGIS Pro, I just started learning Python a few weeks ago so if this is all over the place... bare with me I'm doing the best I can right now.

I am trying to create a Script Tool that will 1)  select records in my feature layer based on a date range in a date field (date only), and then 2) calculate a field for those selected records ONLY to a desired string that the layer's symbology is based off of.

The script:

# Process: Select Layer By Date And Time (Select Layer By Date And Time) (ca)
Project_Selection, Row_Count = arcpy.ca.SelectLayerByDateAndTime(in_layer_or_view=Project_Layer, selection_type="NEW_SELECTION", time_type="SINGLE_TIME_FIELD", date_field="Date", selection_options=["DATE"], date_selection_type="DATE_RANGE", start_date=StartDate, end_date=EndDate)

# Process: Calculate Field with Selection (Calculate Field) (management)
Project_Calc = arcpy.management.CalculateField(in_table=Project_Selection, field="Symbology", expression="\"Beyond 90\"")

 

This is the result of my Script Tool right now. It has the records selected accurately based on my date range, but calculates the entire layer's Symbology field to "Beyond 90" when I need it to only calculate the selected records. 

MichaelBowers_1-1717604073418.png

If I perform this process manually, the calculate field tool will use the 18 selected records and update those 18 selected records' fields only.

Please let me know if you have any suggestions.

0 Kudos
15 Replies
MichaelBowers
Emerging Contributor

Sure thing. Here is the parameter in the properties pane and in the geoprocessing pane.

MichaelBowers_0-1718197158284.png

MichaelBowers_1-1718197266442.png

 

 

0 Kudos
BlakeTerhune
MVP Regular Contributor

Since you are choosing a layer as your input parameter, there's no need to get the layer from the Project again.

def UpdateSymbology():
    
    # To allow overwriting outputs change overwriteOutput option to True.
    arcpy.env.overwriteOutput = True

    # Model Environment Setting
    Projects_Layer = arcpy.GetParameter(0)  # Input parameter

    # ... rest of the code ...
0 Kudos
MichaelBowers
Emerging Contributor

Alright, I've removed that portion from the tool. I ran it again but still calculating for all records.

0 Kudos
MichaelBowers
Emerging Contributor

I've looked at trying to use da.UpdateCursor instead of Field Calculator, as described in this post I found: https://gis.stackexchange.com/questions/298714/using-select-by-attributes-then-calculate-field-on-se...

My attempts were unsuccessful thus far, but I'm not familiar with SQL, Python 'for' loops, nor the 'with' and 'as' Python keywords at all so I'm probably not setting up the update cursor properly.

Could this tool work instead of calculate field?

0 Kudos
BlakeTerhune
MVP Regular Contributor

I have a question about your logic. You are creating a new field called DATE (which is a reserved word, so I suggest you pick a different name) and setting all the (selected) records to the same value: StartDate

Then you are making a selection on that same DATE field where the value is between StartDate and EndDate. Wouldn't that always select everything you just calculated? Why do you need the first step to create and calc the DATE field? Here's an example using an UpdateCursor and a where clause. I didn't put in a field name because I'm not sure what you actually want to compare StartDate to.

expression = f"your_field_name >= date '{StartDate}' and your_field_name <= date '{EndDate}'"
with arcpy.da.UpdateCursor(Project_Layer, ["Symbology"], where_clause=expression) as u_cursor:
    for row in u_cursor:
        u_cursor.updateRow(["Beyond 90"])

This SQL expression should work in a file geodatabase and SQL Server. I'm not sure what dbms your data is in.

MichaelBowers
Emerging Contributor

I needed the first step to add the DATE field because SelectLayerByDateAndTime() requires the input field to be a date field. The existing field in my Projects layer (!Start_Date!) is a Text field, so that select tool won’t run using it.

My logic was to add a Type = Date Only field to the layer and calculate it equal to the values in the  !Start_Date! text field. This all occurred before any selection took place. Once created, I could use the {date_selection_type} option to select these dates relative to a date range. I assigned variables to {start_date} and {end_date} using the datetime lib, date.today(), today.strftime(), datetime.datetime(), and datetime.timedelta() to fetch the current date, change it “x” amount of days, and return a string to input into those parameters. The selection works! But,  I can’t get it to calculate those selected records. I still feel like the SelectLayerByDateAndTime() -> CalculateField() method should work… and still don't know why what I was doing did not...

Your UpdateCursor with SQL where clause works! It updates only those 18 records that qualify in my date range. I don’t even need any selection either since it just reads the data, so I removed that completely. I’m sure I was making this more complicated than it needed to be, but within the limits of my Python and ArcGIS Pro knowledge what I was doing made sense to me.

@BlakeTerhune and @AlfredBaldenweck thank you for the help. This is the first Script Tool I've ever written and I wouldn't have been able to figure it out on my own.