Author Topic: Side Effects of the F(..) Function  (Read 4344 times)

precisonline

  • President
  • Administrator
  • Rock Star
  • *****
  • Posts: 1612
    • Precision Solutions
Side Effects of the F(..) Function
« on: August 06, 2007, 08:16:33 AM »
If you've worked with SB+ for any time at all you're probably intimately familiar with the F(..) function in the expression language.  The general form of this function is:

F(file,key)<attr>

where "file" is a file name (usually a quoted literal), "key" is the field name or expression used to derive the key, and "attr" is the attribute number you want returned.  There is also a variant of this that eliminates the <attr> part of the expression that returns the entire record instead of a single attribute.

Last week, a customer reported some problems with a paragraph called after read on a report that was loading a record and then checking to see if there was another record in a work file.  If one of the secondary records existed, then that input record was to be suppressed from the report.  Generally the process was something like this: (lower case used in place of actual details)

READ @OTHER.REC FROM "file",key
IF @RTN.FLAG = 0 THEN
  IF F('WRK.':@PORT,@OTHER.REC<1>) = '' THEN
    EXIT 1 ;* Skip this record on the report
  END
  *
  IF F('WRK.':@PORT,@OTHER.REC<2>) = '' THEN
    EXIT 1 ;* Skip this record on the report
  END
END

The first IF (referencing @OTHER.REC<1>) was working just fine.  However, it seemed like the second one didn't ever find the record in the work file, when clearly the input record (@OTHER.REC) attribute 2 pointed to existing records.

What was not immediately obvious is that the F(..) function without an attribute number overwrites whatever is in @OTHER.REC.  If you look at the F(..) function in /EEGC with the attribute number part of the syntax you'll see that the function effectively translates to a READV in BASIC.  Without the attribute number, however, this function reads into - and overwrites whatever is currently stored in - @OTHER.REC.

In this case we had a couple of options for correcting this issue.  First, we could have changed the input record to read into a local variable rather than use @OTHER.REC.  We actually didn't choose this option.  Instead, we changed the F(..) function to include <1> so that @OTHER.REC would not be disturbed and the process began working as expected.
« Last Edit: August 06, 2007, 08:18:22 AM by precisonline »
-Kevin
Accidents "happen"; success, however, is planned and executed.