Create Attribute Rule that populates a field in the feature class based on two conditions in the related inspection table.

829
7
Jump to solution
03-30-2023 05:25 AM
EricGlover3
New Contributor II

Hi ESRI Community,

I have another attribute rule question I need to ask, since you were so helpful last time. I have a drainage network layer that consists of a feature class with a field that I want to have populated based on two conditions in the related inspection table.

The inspection table has a field “InspectionReason” which gets populated, via a dropdown, with either “Condition Rating” or “Maintenance Activity”. 

The inspection table also has a field “OtherDrainageRatable” which gets populated via a dropdown.

The feature class name is CTDOT_Planning_OtherDrainage and has a field named “ConditionRatingInspectionStatus”.

 

The logic would work like this:

If the “InspectionReason” = “Condition Rating” and the “OtherDrainageRatable” = “Yes” then the “ConditionRatingInspectionStatus” in the feature = “Inspection Completed”.

If the “InspectionReason” = “Condition Rating” and the “OtherDrainageRatable” is not “Yes” then the “ConditionRatingInspectionStatus” in the feature = “Inspection Attempted”.

I was able to get the first part to work but I don’t know how to handle the else part of the second condition.

 

I’m currently testing using a fgdb in Pro, however, this will be moved to Enterprise for use in web app and Field Maps.

ArcGIS Pro 2.8.8

Arc Enterprise 10.9.1

Thank you in advance for any assistance.

0 Kudos
5 Solutions

Accepted Solutions
JohannesLindner
MVP Frequent Contributor

So the things you need to know for this are the logical operators in Arcade.

  • ==    equal
  • !=     not equal,
  • <, <=, >, >=    less than, less than or equal, greater than, greater than or equal
  • &&   and
  • ||       or

You can write your logic like this:

var rating_status = When(
  $feature.InspectionReason == "Condition Rating" && $feature.OtherDrainageRatable == "Yes",
  "Inspection Completed",
  $feature.InspectionReason == "Condition Rating" && $feature.OtherDrainageRatable != "Yes",
  "Inspection attemted",
  null  // default value, for example when InspectionReason is not "Condition Rating"
)

 

 

And if we combine that with the rule from your previous question:

// abort if there is no ParnetGUID
var parent_id = $feature.ParentGUID
if (IsEmpty(parent_id)) { return parent_id }

// get the inspection status
var inspection_status= When(
  $feature.InspectionReason == "Condition Rating" && $feature.OtherDrainageRatable == "Yes",
  "Inspection Completed",
  $feature.InspectionReason == "Condition Rating" && $feature.OtherDrainageRatable != "Yes",
  "Inspection attemted",
  null  // default value, for example when InspectionReason is not "Condition Rating"
)

// get the date field that should be updated
var date_field = When(
  $feature.InspectionReason == "Condition Rating", "LastConditionRatingInspectDate",
  $feature.InspectionReason == "Maintenance Activity", "LastMaintenanceActivityDate",
  null // some other inspection reason
)

// construct the update instructions
var update = {"globalID": parent_id, "attributes": {}}
update.attributes[date_field] = $feature.InspectionDate
update.attributes["ConditionRatingInspectionStatus"] = inspection_status

return {
  'edit': [{
    'className': 'CTDOT_Planning_OtherDrainage',
    'updates': [update]
  }]
}

Have a great day!
Johannes

View solution in original post

0 Kudos
EricGlover3
New Contributor II

Hi Johannes,

I want to thank you again for your help, the script you provided worked perfectly.

I tried to make a modification to it to incorporate the last automation process I need to do for this workflow.  I followed your workflow to try to get this step to work but I'm getting an error message.  I tried matching what you did for the date field.  

Below is your script with the areas I'm trying to update noted in Bold comments. Again, any advice would be greatly appreciated.

Thank you again!

// abort if there is no ParnetGUID
var parent_id = $feature.ParentGUID
if (IsEmpty(parent_id)) { return parent_id }

// get the inspection status
var inspection_status= When(
$feature.InspectionReason == "Condition Rating" && $feature.OtherDrainageRatable == "Yes",
"Inspection Completed",
$feature.InspectionReason == "Condition Rating" && $feature.OtherDrainageRatable != "Yes",
"Inspection Attempted",
null // default value, for example when InspectionReason is not "Condition Rating"
)


// My change. Populate the MaintenanceActivityStatus field in the feature with the attribute from the MaintenanceReason (dropdown) field in the inspection table, when it's not null.
// When the field has no attrubute selected then nothing happens to the feature.
var update_field = When(
$feature.MaintenanceReason != null, "MaintenanceActivityStatus",
null // some other inspection reason
)


// get the date field that should be updated
var date_field = When(
$feature.InspectionReason == "Condition Rating", "LastConditionRatingInspectDate",
$feature.InspectionReason == "Maintenance Activity", "LastMaintenanceActivityDate",
null // some other inspection reason
)

// construct the update instructions
var update = {"globalID": parent_id, "attributes": {}}
update.attributes[date_field] = $feature.InspectionDate
update.attributes["ConditionRatingInspectionStatus"] = inspection_status

//error in next line. Invalid expression, Error on line 36, String type expected.
update.attributes[update_field] = $feature.MaintenanceReason


return {
'edit': [{
'className': 'CTDOT_Planning_OtherDrainage',
'updates': [update]
}]
}

View solution in original post

0 Kudos
JohannesLindner
MVP Frequent Contributor

I tried matching what you did for the date field.  

What we did with the date field is not applicable here.

For the date field, we have to decide which one of two fields to update based on the inspection reason.

For this problem, you want to copy the value in MaintenanceReason over to parent.MaintenanceActivityStatus. If there is no such value, don't edit the parent field. You can do that with a simple if statement (and remove your update_field part):

if($feature.MaintenanceReason != null) {
    update.attributes["MaintenanceActivityStatus"] = $feature.MaintenanceReason
}

 

All together:

// abort if there is no ParnetGUID
var parent_id = $feature.ParentGUID
if (IsEmpty(parent_id)) { return parent_id }

// get the inspection status
var inspection_status= When(
  $feature.InspectionReason == "Condition Rating" && $feature.OtherDrainageRatable == "Yes",
  "Inspection Completed",
  $feature.InspectionReason == "Condition Rating" && $feature.OtherDrainageRatable != "Yes",
  "Inspection attemted",
  null  // default value, for example when InspectionReason is not "Condition Rating"
)

// get the date field that should be updated
var date_field = When(
  $feature.InspectionReason == "Condition Rating", "LastConditionRatingInspectDate",
  $feature.InspectionReason == "Maintenance Activity", "LastMaintenanceActivityDate",
  null // some other inspection reason
)

// construct the update instructions
var update = {"globalID": parent_id, "attributes": {}}
update.attributes[date_field] = $feature.InspectionDate
update.attributes["ConditionRatingInspectionStatus"] = inspection_status
if($feature.MaintenanceReason != null) {
    update.attributes["MaintenanceActivityStatus"] = $feature.MaintenanceReason
}

return {
  'edit': [{
    'className': 'CTDOT_Planning_OtherDrainage',
    'updates': [update]
  }]
}

Have a great day!
Johannes

View solution in original post

0 Kudos
EricGlover3
New Contributor II

Hi Johannes,

I took your revised script and tested it with my FGDB and everything worked fine.  I then tested it in our SDE staging Portal and configured the inspection table with Field Maps.  Everything worked perfectly! I demonstrated it to the units that I'm building this for, and they loved it.  I made sure to give you all of the credit that you so rightly deserve for this.  I want to personally thank you for all of your help and that I truly appreciate your effort and knowledge in this matter.  The cost savings and data integrity will be immense.

Thank you!!!!!!!!

Eric

 

View solution in original post

0 Kudos
JohannesLindner
MVP Frequent Contributor

Glad to have helped. Please select an answer as solution so that this question is shown as answered.


Have a great day!
Johannes

View solution in original post

0 Kudos
7 Replies
JohannesLindner
MVP Frequent Contributor

So the things you need to know for this are the logical operators in Arcade.

  • ==    equal
  • !=     not equal,
  • <, <=, >, >=    less than, less than or equal, greater than, greater than or equal
  • &&   and
  • ||       or

You can write your logic like this:

var rating_status = When(
  $feature.InspectionReason == "Condition Rating" && $feature.OtherDrainageRatable == "Yes",
  "Inspection Completed",
  $feature.InspectionReason == "Condition Rating" && $feature.OtherDrainageRatable != "Yes",
  "Inspection attemted",
  null  // default value, for example when InspectionReason is not "Condition Rating"
)

 

 

And if we combine that with the rule from your previous question:

// abort if there is no ParnetGUID
var parent_id = $feature.ParentGUID
if (IsEmpty(parent_id)) { return parent_id }

// get the inspection status
var inspection_status= When(
  $feature.InspectionReason == "Condition Rating" && $feature.OtherDrainageRatable == "Yes",
  "Inspection Completed",
  $feature.InspectionReason == "Condition Rating" && $feature.OtherDrainageRatable != "Yes",
  "Inspection attemted",
  null  // default value, for example when InspectionReason is not "Condition Rating"
)

// get the date field that should be updated
var date_field = When(
  $feature.InspectionReason == "Condition Rating", "LastConditionRatingInspectDate",
  $feature.InspectionReason == "Maintenance Activity", "LastMaintenanceActivityDate",
  null // some other inspection reason
)

// construct the update instructions
var update = {"globalID": parent_id, "attributes": {}}
update.attributes[date_field] = $feature.InspectionDate
update.attributes["ConditionRatingInspectionStatus"] = inspection_status

return {
  'edit': [{
    'className': 'CTDOT_Planning_OtherDrainage',
    'updates': [update]
  }]
}

Have a great day!
Johannes
0 Kudos
EricGlover3
New Contributor II

Hi Johannes,

I want to thank you again for your help, the script you provided worked perfectly.

I tried to make a modification to it to incorporate the last automation process I need to do for this workflow.  I followed your workflow to try to get this step to work but I'm getting an error message.  I tried matching what you did for the date field.  

Below is your script with the areas I'm trying to update noted in Bold comments. Again, any advice would be greatly appreciated.

Thank you again!

// abort if there is no ParnetGUID
var parent_id = $feature.ParentGUID
if (IsEmpty(parent_id)) { return parent_id }

// get the inspection status
var inspection_status= When(
$feature.InspectionReason == "Condition Rating" && $feature.OtherDrainageRatable == "Yes",
"Inspection Completed",
$feature.InspectionReason == "Condition Rating" && $feature.OtherDrainageRatable != "Yes",
"Inspection Attempted",
null // default value, for example when InspectionReason is not "Condition Rating"
)


// My change. Populate the MaintenanceActivityStatus field in the feature with the attribute from the MaintenanceReason (dropdown) field in the inspection table, when it's not null.
// When the field has no attrubute selected then nothing happens to the feature.
var update_field = When(
$feature.MaintenanceReason != null, "MaintenanceActivityStatus",
null // some other inspection reason
)


// get the date field that should be updated
var date_field = When(
$feature.InspectionReason == "Condition Rating", "LastConditionRatingInspectDate",
$feature.InspectionReason == "Maintenance Activity", "LastMaintenanceActivityDate",
null // some other inspection reason
)

// construct the update instructions
var update = {"globalID": parent_id, "attributes": {}}
update.attributes[date_field] = $feature.InspectionDate
update.attributes["ConditionRatingInspectionStatus"] = inspection_status

//error in next line. Invalid expression, Error on line 36, String type expected.
update.attributes[update_field] = $feature.MaintenanceReason


return {
'edit': [{
'className': 'CTDOT_Planning_OtherDrainage',
'updates': [update]
}]
}

0 Kudos
JohannesLindner
MVP Frequent Contributor

I tried matching what you did for the date field.  

What we did with the date field is not applicable here.

For the date field, we have to decide which one of two fields to update based on the inspection reason.

For this problem, you want to copy the value in MaintenanceReason over to parent.MaintenanceActivityStatus. If there is no such value, don't edit the parent field. You can do that with a simple if statement (and remove your update_field part):

if($feature.MaintenanceReason != null) {
    update.attributes["MaintenanceActivityStatus"] = $feature.MaintenanceReason
}

 

All together:

// abort if there is no ParnetGUID
var parent_id = $feature.ParentGUID
if (IsEmpty(parent_id)) { return parent_id }

// get the inspection status
var inspection_status= When(
  $feature.InspectionReason == "Condition Rating" && $feature.OtherDrainageRatable == "Yes",
  "Inspection Completed",
  $feature.InspectionReason == "Condition Rating" && $feature.OtherDrainageRatable != "Yes",
  "Inspection attemted",
  null  // default value, for example when InspectionReason is not "Condition Rating"
)

// get the date field that should be updated
var date_field = When(
  $feature.InspectionReason == "Condition Rating", "LastConditionRatingInspectDate",
  $feature.InspectionReason == "Maintenance Activity", "LastMaintenanceActivityDate",
  null // some other inspection reason
)

// construct the update instructions
var update = {"globalID": parent_id, "attributes": {}}
update.attributes[date_field] = $feature.InspectionDate
update.attributes["ConditionRatingInspectionStatus"] = inspection_status
if($feature.MaintenanceReason != null) {
    update.attributes["MaintenanceActivityStatus"] = $feature.MaintenanceReason
}

return {
  'edit': [{
    'className': 'CTDOT_Planning_OtherDrainage',
    'updates': [update]
  }]
}

Have a great day!
Johannes
0 Kudos
EricGlover3
New Contributor II

Hi Johannes,

I took your revised script and tested it with my FGDB and everything worked fine.  I then tested it in our SDE staging Portal and configured the inspection table with Field Maps.  Everything worked perfectly! I demonstrated it to the units that I'm building this for, and they loved it.  I made sure to give you all of the credit that you so rightly deserve for this.  I want to personally thank you for all of your help and that I truly appreciate your effort and knowledge in this matter.  The cost savings and data integrity will be immense.

Thank you!!!!!!!!

Eric

 

0 Kudos
JohannesLindner
MVP Frequent Contributor

Glad to have helped. Please select an answer as solution so that this question is shown as answered.


Have a great day!
Johannes
0 Kudos
Gene_Sipes
Occasional Contributor

I am curious how the first part of this question is achieved with arcade, i.e. the ability to reference the related record from the related table of the feature? I am trying to create an attribute rule on a feature class that populates a field on the feature class based on a value from its most recent related record. Can someone please point me in the correct direction?

0 Kudos
KristalWalsh
Occasional Contributor II

@JohannesLindner hi, this is an old post but I'm attempting a similar attribute rule expression for a project in Pro. This data was brought in from an .mdb and the relationships have already been established on a UID that is not a Global ID. To create an attribute rule to push a calculation of table entries to a cell in the feature class, I established a global id field for the new .fgdb feature classes. 1) Is it okay to leave the relationships as they are?  and 2) Do I need to add new GUID fields to the related tables? Thank you! 

Kristal Walsh, Florida Fish and Wildlife
Office of Conservation Planning
0 Kudos