Problems trying to implement attribute rule example in Pro documentation

3915
18
01-24-2020 06:24 AM
AndrewZimba1
New Contributor III

Hello everyone,

I'm trying to implement essentially the same functionality as in one of the examples in the Pro documentation at Attribute rule script expression examples—Geodatabases | ArcGIS Desktop, specifically:

var fsStructureBoundary = FeatureSetByName($datastore, "Substation", ["name"], true)

var fsSubstation = Intersects(fsStructureBoundary, Geometry($feature))

var substation = First (fsSubstation)

var subname = ""

if (substation == null)

return {"errorMessage": "Transformers must be created in a substation."}

else subname = substation.name

return subname + " - " + $feature.assetid;

Of course my feature class names are different, but when I validate the expression I get:

Invalid expression

Error on line 1

Table not found {FC}

I've tried the FC name as it appears in the TOC, the name of the source FC in the geodatabase, and the full Database.DBO.FC source all with the same result.

What am I missing?  

0 Kudos
18 Replies
AndrewZimba1
New Contributor III

I may have spoken too soon.  For the polygon-attribute-flipping when it contains a point from another fc, it is the *point* that is being created/updated, not the polygon.  So we have sample areas polygons that are existing, and when a sample point is taken it get's the ID from the polygon.  We then need to simultaneously trigger the polygon to update its hasPoint field to "Yes" since it now contains a sample point.  I hope that makes sense.

0 Kudos
HusseinNasser2
Esri Contributor

Aha this is a little bit tricky. I will attempt to write the basic version of this but there are so many edge cases that this script doesn't solve. (Moving feature, deleting a bunch of features at once) .. But this is just a start..

Two classes

polygonClass

pointClass

On the pointClass add an attribute rule on insert

//on insert 
//check if we are intersecting a polygon. If yes, set the hasPoint field on the polygon to Yes
var fsPolygon = FeatureSetByName($datastore, "polygonClass", ["globalId"], false);
var intersectedPolygons = Intersects (fsPolygon, $feature);
var polygonFeature = null;
for (polygonFeature in intersectedPolygons) break;
if (polygonFeature == null) return $feature.field; // no polygon intersected found , quit..

//we found a polygon feature set its HasPoint to Yes
return {
          "result": $feature.field, 
          "edit": [
                   {
                        "className" : "polygonClass",
                        "updates": [
                                          {
                                                 "globalId": polygonFeature.globalId,
                                                 "attributes": {"hasPoint": "yes" }
                                      }
                            ]
                   }
                ]

}

On the pointClass add another attribute rule on Delete

//on delete
//check if we are intersecting a polygon. If yes, make sure we are the last point, if yes set hasPoint to No!

var fsPolygon = FeatureSetByName($datastore, "polygonClass", ["globalId"], true);
var intersectedPolygons = Intersects (fsPolygon, $feature);
var polygonFeature = null;
for (polygonFeature in intersectedPolygons) break;
if (polygonFeature == null) return $feature.field; // no polygon intersected found , quit..

//query the pointClass
var pointGlobalId = $feature.globalid;
var fsPoint = FeatureSetByName($datastore, "pointClass", ["globalId"], false);
var intersectedPoints = Filter(Intersects (fsPoint, Geometry(polygonFeature)), "globalId <> @pointGlobalId"); // find all points that are not me in the polygon

//there are still few points, quit!
if (Count(intersectedPoints) > 0) return $feature.field

//$feature was the last point, .. set hasPoint to No

//we found a polygon feature set its HasPoint to Yes
return {
          "result": $feature.field, 
          "edit": [
                   {
                        "className" : "polygonClass",
                        "updates": [
                                          {
                                                 "globalId": polygonFeature.globalId,
                                                 "attributes": {"hasPoint": "no" }
                                      }
                            ]
                   }
                ]

}

AndrewZimba1
New Contributor III

This is very helpful indeed Hussein!  Thank you so much.  I'm attempting to implement now.

0 Kudos
AndrewZimba1
New Contributor III

Close, but running into a problem here.  

This is my implementation.

var fsBuffer = FeatureSetByName($datastore, "Section3.DBO.PlannedSoilsSamplngLocationBuffers", ["GlobalID"], false);
var intersectPolys = Intersects(fsBuffer, $feature);
var fsBufferFeature = null;
for (fsBufferFeature in intersectPolys) break;
if (fsBufferFeature == null) return $feature.GlobalID;

//we found a polygon feature set its HasPoint to Yes
return {
"result": $feature.GlobalID,
"edit": [
{
"className" : "Section3.DBO.PlannedSoilsSamplingLocationsBuffers",
"updates": [
{
"GlobalID": fsBufferFeature.GlobalID,
"attributes": {"SampleComplete": "Yes"}
}
]
}
]
}

and this is the error I get:

I think I am mis-interpreting your $feature.field syntax. What field in the point feature class should this rule be attached to?  It looks like the only field available is SampleID (the one that is auto-calculated from the previous rule).

BTW, how do you insert that nice code block into the posts?

0 Kudos
HusseinNasser2
Esri Contributor

The attribute rules above Are added to a field on the pointClass called "Field"  it is just returning the same value indicating a no-op operation (don't do anything)

In your case you can just return the sample Id ($feature.sampleid) and assign the attribute rule..  

Your rule is complaining about the table that doesn't exist.. make sure that table Section3.DBO.PlannedSoilsSamplngLocationBuffers exists

0 Kudos
AndrewZimba1
New Contributor III

Hmm.  yes, it definitely exists.  It's the same polygon field that is contributing the SampleID from the previous rule (which works great, BTW.  TY!!).  I'm very confused as to why it's not finding it.  I would think if it didn't exist it would throw an error on line 1 and not validate.  

0 Kudos
AndrewZimba1
New Contributor III

Got it now...  human error (of course).  Thank you for all your help.  This has been extremely instructive.  Are there any resources that could help expose more of the capabilities of attribute rules?  For example, the update of attributes with the edit.[] block is not something I would have even known was possible from the examples shown in the Pro documentation.

0 Kudos
RossFindlay
New Contributor III

Hi, I am having a similair issue with an attribute rule I am trying to implement. Took Hussein's "Buffer a Point Feature Rule" and  changed the polygon classname to my layer on slqserver. 

"className" : "[Sandbox1].[coc\rfindlay].[INFRASTRUCTUREPROJECTS]".

it couldn't find the table. I figured the square braces was the right syntax, Catalog refers to the layer as  Sandbox1."coc\rfindlay".INFRASTRUCTUREPROJECTS, and the quotes and slashes i think are making trouble for me. 

Any help welcome. Cheers

 

0 Kudos
RossFindlay
New Contributor III

Just a follow up that I did solve my issue.

I created a variable fsBuffer = "InfrastructureProjects" that I then referenced in the "className" line. This passed the value and the buffer was created.