Arcade expression to increase number value by 1 for every new feature

734
6
Jump to solution
02-21-2024 06:23 AM
Labels (3)
James_Shreeve
New Contributor III

Hi, 

I have a dataset which is our primary use case for editing and when capturing new features I'm setting up smart forms to help the user. The main one I'm struggling with is our reference number and the ability to auto populate the next sequential number. The data field, just to confuse matters more, is a string. I'm getting better at arcade but still in my learning days so I think what I need to do is...

Our standard reference number format is "ESCO - 1234" and I'm just looking to increase the highest value by 1 each time a new record is created. The reference number is stored in the field "ESCO_Ref".

1) convert the string to an integer. The reference number will always be the last 4 characters of the string. 

 

var ESCO_num = Number(Right('$feature.ESCO_Ref', -7));

 

2) find the highest number and then add one to the value (taken from Go Beyond the Smart Editor using Smart Forms (esri.com))

 

// Define the edit context so the value is only calculated when the feature is created

if ($editContext.editType == "INSERT") {

  // Lookup the value for the last created feature

  var last_feature = First(OrderBy($layer, 'ESCO_Ref DESC'));

  // If the last value was empty write 1, otherwise add 1 to the value

  return IIf(IsEmpty(last_feature), 1, last_feature.ESCO_Ref + 1)

} else {r(Right('$feature.ESCO_Ref', -7));
  // When the feature is updated, return the existing value in this field

  // and do not calculate a new value

  $feature.ESCO_Ref

}

 

3) prefix the new value with "ESCO - "

 

return "ESCO - " + variable above

 

Whilst the above may be very clunky and possibly not correct, I'm just struggling with how to put the steps into one seamless expression. Any help would be greatly received folks! 

Many thanks!

0 Kudos
1 Solution

Accepted Solutions
James_Shreeve
New Contributor III

Hi, thanks for getting back to me. It's been helpful, I kept trying to make the number array work but I could never seem to retrieve the number but I did hash together the below from using your code and the code in my original post which has worked a treat. 

// Define the edit context so the value is only calculated when the feature is created
if ($editContext.editType == "INSERT") {
  // Lookup the value for the last created feature
  var last_feature = First(OrderBy($layer, 'ESCO_Ref DESC'))
  // Extract the ESCO_Ref field
  var lf_esco = last_feature.ESCO_Ref
  // Convert to Number and remove prefix text
  var lf_esco_num = Number(lf_esco, 'ESCO - ####')
  // Add 1 to the number
  var lf_esco_new_num = lf_esco_num + 1
  // Convert back to text
  var lf_esco_text = Text(lf_esco_new_num)
  // Concatenate together with the prefix
  var new_esco_ref = Concatenate('ESCO - ', lf_esco_text)
  return new_esco_ref
} else {
  // When the feature is updated, return the existing value in this field
  // and do not calculate a new value
  $feature.ESCO_Ref
}

View solution in original post

6 Replies
RhettZufelt
MVP Frequent Contributor

See this link for posting code.

Don't have time to modify/test for your data, but this is how I have accomplished this task for online data.

//  example ID = 'LT00002'


if(isempty($feature.ID) && $feature.SYMBOL_TYPE == "2SL"){

var vals = FeatureSetByName($datastore,"Testing4Pro.DBO.StripingPoints",['ID'],false)
var LTvals = Filter(vals, "ID LIKE 'LT0%'")
var numarray = []

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

return maxtext
}

 

First checks to see if the ID field is empty, and the correct feature type (I have multiple feature types in the same feature class with their own ID prefix).

Grabs the featureset with the ID field.

Filters to just the matching features (remember, this is for multiple feature types).

create an empty array

iterate through the filtered features, strip off the text prefix (in this case 'LT') and add to the array as a number.

now, find the max number in the array

concatenate the prefix back on with the max number incremented by one, and formated as text with 5 digits.

Done.

Hope this gives you an idea.

 

R_

 

0 Kudos
James_Shreeve
New Contributor III

Hi, thanks for getting back to me. It's been helpful, I kept trying to make the number array work but I could never seem to retrieve the number but I did hash together the below from using your code and the code in my original post which has worked a treat. 

// Define the edit context so the value is only calculated when the feature is created
if ($editContext.editType == "INSERT") {
  // Lookup the value for the last created feature
  var last_feature = First(OrderBy($layer, 'ESCO_Ref DESC'))
  // Extract the ESCO_Ref field
  var lf_esco = last_feature.ESCO_Ref
  // Convert to Number and remove prefix text
  var lf_esco_num = Number(lf_esco, 'ESCO - ####')
  // Add 1 to the number
  var lf_esco_new_num = lf_esco_num + 1
  // Convert back to text
  var lf_esco_text = Text(lf_esco_new_num)
  // Concatenate together with the prefix
  var new_esco_ref = Concatenate('ESCO - ', lf_esco_text)
  return new_esco_ref
} else {
  // When the feature is updated, return the existing value in this field
  // and do not calculate a new value
  $feature.ESCO_Ref
}
RhettZufelt
MVP Frequent Contributor

Nice.  I didn't realize there was a 'Remove text characters from number.' option for Number().

I may have to update some scripts with that instead of Replace().

R_

0 Kudos
James_Shreeve
New Contributor III

I didn't realise either, only after looking at some documentation that I noticed it. Thanks for your help!

0 Kudos
BillFox
MVP Frequent Contributor

Is this in a versioned multi-user workflow?

0 Kudos
RhettZufelt
MVP Frequent Contributor

I only use it for AGOL (online), FGDB or traditional versioning moving edits to base as I believe it may 'miss' some values in other versions if not reconcile/posted first.

R_

0 Kudos