Correct use of the PositionOf and PositionIn Intrinsic functions

Date:1 May 2007
Product/Release:Visual LANSA V11
Abstract:PositionOf/PositionIn are useful intrinsic functions, however care must be taken when used on RDML Alpha fields
Submitted By:LANSA Technical Support

PositionOf and PositionIn are 2 useful intrinsic functions introduced in V11.0, which find the first occurance of one string within another string. They can be used to easily parse wordstrings or do simple string searching for validation. However when used with Alphanumeric (RDML) fields care must be taken with regards to 'trailing spaces'

Details:

Firstly, it should be noted that PositionOf and PositionIn are interchangeable and either one can be used depending on the developer's preference. The difference is in the way that the code reads in the IDE (note there are optional arguments with these functions that are not specified below):

#FoundPos := #SearchString.PositionIn(#InputString)

vs.

#FoundPos := #InputString.PositionOf(#SearchString)

Where #InputString is the string to be searched, #SearchString is the string to be searched for, and #FoundPos is the location at which #SearchString is found in #InputString

Special Consideration when using Alpha (RDML) field types:

It should be noted that one major distinction between Alpha and String field types, is the significance of trailing spaces. In Alpha fields, trailing spaces are insignificant, and are not used in processing. On the other hand, trailing spaces are significant in String fields

This is important if you are using PositionOf/PositionIn to search for " " blanks in a parsing algorithm. Setting an alpha field #SearchString to *blanks or " " is the same as setting it to nothing (""). Using this with PositionOf/PositionIn will not give the correct results.

The solution is to ensure #SearchString is defined as a String field. Alternatively you can manually code the search string as follows:

#FoundPos := (" ").PositionIn( #InputString )

Usage examples:

Parse an input string

#w_string := 'Hello World Goodbye'
#w_blank := ' '

#w_pos := #w_string.PositionOf( #w_blank )
dowhile ( #w_pos > 0 )
  * Loop until no more spaces are found
  #w_token := #w_string.LeftMost( (#w_pos - 1) )
  Use Ov_Message_Box #w_token

  #w_string := #w_string.Substring( (#w_pos + 1) )
  #w_pos := #w_string.PositionOf( #w_blank )
endwhile
* Get last word
#w_token := #w_string
Use Ov_Message_Box #w_string2

Validate an input string

* Crude Email Validity Checking
If Cond(#Email.PositionOf('@') = 0)
 Use Builtin(Ov_Message_Box) With_Args('Invalid Email Address')
Endif

Note: Both code examples can be easily adapted to use PositionIn as noted above.