Is there a way to perform a field calculate function based on attributes in another feature?

580
5
07-17-2018 01:21 PM
New Contributor

I have two fields that describe a points placement on a line. Each point has a unique ID, and a field describing the next ID "downstream". My goal is to compare a third field (field3) where the unique ID = the downstream ID.

The downstream (DownstreamID) value of the third field (Field3_2) should be less than the third field (Field3_1) of the upstream (UniqueID) feature.

I also included a section of visual basic code for performing a similar function in excel.

```For (Each Feature)
if UniqeID /*(from feature1)*/ = DownstreamID /*(from feature2)*/ & Field3_1 /*(from feature1)*/ > Field3_2 /*(from feature2)*/:
return(1)
else:
return(0)

__________________________________________________________________________________________________

If NextDownID <> -1 Then

NextDownRow = Application.Match(Cells(rw, 2), Columns(1), 0)

For i = 0 To 7 'create array with US Flows
If Cells(rw, USColumn + i).Value <> "" Then 'check if flow value exists
tmpUS(i) = Cells(rw, USColumn + i).Value 'if yes, add to array
Else
tmpUS(i) = 0 'else, put in 0 (null causes issues)
End If
Next i

For j = 0 To 7 'create array with DS Flows
tmpq = Application.Index(Columns(3 + j), NextDownRow)
If tmpq <> "" Then
tmpDS(j) = tmpq
Else
tmpDS(j) = 0
End If
Next j

For k = 0 To 7
tmpcmp(k) = tmpDS(k) - tmpUS(k) 'tmpCmp will be negative if US flows are > DS flows (i.e. flows are not increasing in the DS direction)
If tmpcmp(k) < 0 Then
Worksheets(outputsheet).Cells(outrw, 1).Value = NextDownID 'creates a row in the output sheet for the NextDownID. Only occurs if a DS flow need sto be replaced
NextDownNEW = Application.VLookup(NextDownID, Worksheets(inputsheet).Range("A:B"), 2, False) 'Determines the NextDownID associated with the Output Sheet HydroID i.e. InputSheet HydroID's NextDownID's NextDownID
Worksheets(outputsheet).Cells(outrw, 2).Value = NextDownNEW 'Prints NextDownNEW. Useful for iterating macro
Worksheets(outputsheet).Cells(outrw, k + 3).Value = tmpUS(k) 'Prints flows that need to be revised
FailCount = FailCount + 1
Else

End If
Next k
Else
End If

If Sheets(outputsheet).Cells(outrw, 1).Value <> 0 Then
outrw = outrw + 1 'If the Loop printed a HydroID, add 1 to outrow so on the next iteration the macro prints to the next row
Else
End If

rw = rw + 1
Loop```
Tags (3)
1 Solution

Accepted Solutions
MVP Honored Contributor

Ah, in that case, I would read all your features into a dictionary, using Downstream ID as the key, then loop through all the features with an Update Cursor and look up the values in the dictionary to populate the current feature in the cursor, matching the current Upstream ID to the key in the dictionary.

5 Replies
MVP Honored Contributor

Make a join, then calculate.

edit: using Python, you may be able to read all features of one feature class into a dictionary (depending on feature class size), then go through the features of the other feature class using an Update Cursor to change values.

New Contributor

I think I phrased my question a bit incorrectly, by feature I meant a single row in the same shapefile. So I would compare a Unique ID in field one with all the downstream IDs in field 2 for every feature to find a match within the same shapefile. I have a visual basic example of this code for excel, but I was trying to get a working python example for doing it directly in ArcMap.

MVP Honored Contributor

Ah, in that case, I would read all your features into a dictionary, using Downstream ID as the key, then loop through all the features with an Update Cursor and look up the values in the dictionary to populate the current feature in the cursor, matching the current Upstream ID to the key in the dictionary.

New Contributor

Thanks for this tip, I had started messing around with the "table to numpy array" tool but using a dictionary instead of an array might work better.

MVP Honored Contributor

You could do that, too. In any case, the pattern is similar: make a copy, join/match, calculate.