Select to view content in your preferred language

Attribute Rule for incremental numbers

846
3
07-18-2023 07:34 AM
BenPaynter
New Contributor II

Hello everyone, 

I'm trying to use an attribute rule to do something that seems relatively simple. I want to take a field with numbers that are incremented by one and have the attribute rule create the next highest number for that field when a new feature is created. I thought that I could just use the Max() function to find the highest number in the list and then simply add a "+1" to calculate the next number.

I'm not interested in the database sequence solution because I want the script to be able to find the maximum value and add one. If I were to create the sequence, it wouldn't necessarily find that value and the numbers could get out of sync.

Has anyone had luck with this? I've looked at several different forums and my script has become more and more complicated for a seemingly simple and probably common task.

I started with:

var lastpolenum = Max($feature.ApexPoleNumber)

return lastpolenum + 1

This was a valid expression but I would get an error that the value was not recognized as a number when trying to create a new feature. ApexPoleNumber is a "Double" numeric field with numbers from 1 to 4779.

After looking at several posts, it seemed like my problem was that I needed to populate array for the Max() function to work and have some work around for a null value occurring. So my script is now looking like this:

var poles = FeatureSetByName($datastore, 'Pole_NumberingTest', ['ApexPoleNumber'], false);
var polenumarray = []
for (var i in poles){
  if (poles == null){
      return null;}
  else{
     Push(polenumarray, poles[i]);
   }
}

return Max(polenumarray) + 1;

.... kind of seems like overkill but maybe it is the right direction?

This script won't validate because I get an error referring to line 7: "Dictionary type expected".

Any help would be greatly appreciated!

Thanks.

 

Best,

Ben Paynter

3 Replies
RhettZufelt
MVP Notable Contributor

I do something similar, but my ID field is text as I want the ID's prefixed with text (TTA0001, TTA0002, etc.).

if(isempty($feature.ID)){

var vals = FeatureSetByName($datastore,"StripingPoints",['ID'],false)
var TTAvals = Filter(vals, "ID LIKE 'TTA0%'")  //filter to only apply to specific features
var numarray = []

for (var n in TTAvals){
    var nn = Number(Replace(n.ID, 'TTA',''))
    Push(numarray, nn)
}
var maxnum = Max(numarray)
var maxtext = Concatenate('TTA',(Text(maxnum + 1, '00000')))

return maxtext
}

// example input for ID filed = TTA00001

Like I said, this if for text field, but should give you an idea of how to make it happen with numeric.

First, check to make sure the ID field isn't already populated (unless you want to overwrite existing ID's), load the data layer, filter to matching features (not needed if you apply the same att rule to all feature in the feature class),  loop through all the features and strip of the 'TTA' and return a number (instead of text) that is pushed into the numarray.

Then, find max value of the numarray, concatenate that back to text with formatting (again, not needed if text field), return the new, incremented number.

R_

0 Kudos
BenPaynter
New Contributor II

Thanks, Rhett. I tried matching some of your syntax with my data and it is saying it is valid but returns a null value when I try to create a new feature and seems to not do the rule calculation. I skipped some steps that you had because I'm just dealing with a number field with values that don't have a prefix. This is what I changed it to:

if(isempty($feature.ApexPoleNumber)){

var poles = Number(FeatureSetByName($datastore, 'Pole_NumberingTest', ['ApexPoleNumber']));
var polenums = []
for (var x in poles){
         Push(polenums, poles)
}
var maxnum = Max(polenums)
return maxnum

}

 

Any ideas?

 

Thanks for your help on this.

0 Kudos
RhettZufelt
MVP Notable Contributor

This should work for you and give you an idea of the syntax:

if(isempty($feature.ApexPoleNumber)){

var poles = FeatureSetByName($datastore,"Pole_NumberingTest",['ApexPoleNumber'],false)
var polenums = []

for (var n in poles){
    var nn = Number(n.ApexPoleNumber)
    Push(polenums, nn)
}
var maxnum = Max(polenums)
var newnum = maxnum + 1

return newnum
}

So, it checks if the current feature ID field is empty, loads the feature class with ApexPoleNumber field, iterates through them all and adds the existing values to a list, finds the max of the list, adds 1 to it, and returns the new number.  Some of the lines could be combined, but I think it's easier to read like this.

I should point out that this will fail if there is not at least one feature in the featureclass with a number in it's ApexPoleNumber field.

Also, this link on inserting code will make things a lot nicer and easier to see what is going on in the future.

R_

0 Kudos