Passing Arguments

Procedure arguments are treated as local variables. Arguments can be numeric, date, or text variables or strings. If an argument is preceded with a colon, its value is passed back to the calling procedure.

In the following code example, spell_number takes two arguments. The first argument is the check amount. This argument is a number, and the program passes it to the procedure. The procedure does not need to pass it back.

The second argument is the result that the procedure passes back to the calling program. We precede this variable with a colon, which means that the value of this argument is copied back at the end of the procedure. The colon is used only when the argument is declared in the BEGIN-PROCEDURE command.

Look at the following sample program. It is not a complete program, but it is the spell_number procedure, which is stored in the spell.inc file. The check printing sample program includes this code by using an #INCLUDE command.

File spell.inc 
begin-procedure spell_number(#num,:$str)
   let $str = ''
   ! break the number to it's 3-digit parts
   let #trillions  = floor(#num / 1000000000000)
   let #billions   = mod(floor(#num / 1000000000),1000)
   let #millions   = mod(floor(#num / 1000000),1000)
   let #thousands  = mod(floor(#num / 1000),1000)
   let #ones       = mod(floor(#num),1000)
   ! spell each 3-digit part
   do spell_3digit(#trillions,'trillion',$str)
   do spell_3digit(#billions,'billion',$str)
   do spell_3digit(#millions,'million',$str)
   do spell_3digit(#thousands,'thousand',$str)
   do spell_3digit(#ones,'',$str)
end-procedure ! spell_number
begin-procedure spell_3digit(#num,$part_name,:$str)
   let #hundreds = floor(#num / 100)
   let #rest     = mod(#num,100)
   if #hundreds
      do spell_digit(#hundreds,$str)
      concat 'hundred ' with $str
   end-if
   if #rest
   do spell_2digit(#rest,$str)
   end-if
   if #hundreds or #rest
      if $part_name != ''
         concat $part_name with $str
          concat ' ' with $str
      end-if
   end-if
end-procedure ! spell_3digit
begin-procedure spell_2digit(#num,:$str)
   let #tens     = floor(#num / 10)
   let #ones     = mod(#num,10)
   if #num < 20 and #num > 9
      evaluate #num
       when = 10
         concat 'ten ' with $str
         break
       when = 11
         concat 'eleven ' with $str
         break
   when = 12
         concat 'twelve ' with $str
         break
      when = 13
         concat 'thirteen ' with $str
         break
       when = 14
         concat 'fourteen ' with $str
         break
     when = 15
         concat 'fifteen ' with $str
         break
       when = 16
         concat 'sixteen ' with $str
         break
       when = 17
         concat 'seventeen ' with $str
         break
       when = 18
         concat 'eighteen ' with $str
         break
       when = 19
         concat 'nineteen ' with $str
         break
      end-evaluate
   else
      evaluate #tens
       when = 2
         concat 'twenty' with $str
         break
       when = 3
         concat 'thirty' with $str
         break
       when = 4
         concat 'forty' with $str
         break
      when = 5
         concat 'fifty' with $str
         break
       when = 6
         concat 'sixty' with $str
          break
      when = 7
         concat 'seventy' with $str
         break
       when = 8
         concat 'eighty' with $str
         break
       when = 9
         concat 'ninety' with $str
         break
       end-evaluate
     if #num > 20
          if #ones
             concat '-' with $str
          else
             concat ' ' with $str
          end-if
       end-if
       if #ones
          do spell_digit(#ones,$str)
       end-if
   end-if
end-procedure ! spell_2digit
begin-procedure spell_digit(#num,:$str)
   evaluate #num
      when = 1
         concat 'one ' with $str
         break
      when = 2
         concat 'two ' with $str
         break
      when = 3
         concat 'three ' with $str
         break
      when = 4
         concat 'four ' with $str
         break
      when = 5
         concat 'five ' with $str
         break
      when = 6
         concat 'six ' with $str
         break
      when = 7
         concat 'seven ' with $str
         break
      when = 8
         concat 'eight ' with $str
         break
      when = 9
         concat 'nine ' with $str
         break
   end-evaluate
end-procedure ! spell_digit

The result argument is reset in the procedure because the program begins with an empty string and keeps concatenating the parts of the number to it. The program supports numbers up to 999 trillion only.

The number is divided into its three-digit parts: trillions, billions, millions, thousands, and ones. Another procedure spells out the three-digit numbers, such as one hundred twelve. Note that the word and is inserted only between dollars and cents, but not between three-digit parts. This format is common for check printing in dollars.

Note the use of math functions, such as floor and mod. SQR for PeopleSoft has a large set of functions that can be used in expressions. These functions are listed and described under the LET command.

See SQR Commands.

The series of EVALUATE commands in the number spelling procedures are used to correlate the numbers that are stored in the variables with the strings that are used to spell them out.

This is the sample program that prints checks:

Program ex17a.sqr
#include 'spell.inc'
begin-setup
  declare-layout default
  end-declare
end-setup
begin-program
  do main
end-program
begin-procedure main
  alter-printer font=5 point-size=15
begin-select
name                               &name
sum(d.price * c.quantity) * 0.10   &refund 
  do print_check(&refund)
from  customers a, orders b,
      ordlines c, products d
  where a.cust_num = b.cust_num
  and   b.order_num = c.order_num
  and   c.product_code = d.product_code
 group by name
 having sum(d.price * c.quantity) * 0.10 >= 0.01
end-select
end-procedure ! main
begin-procedure print_check(#amount)
  print $_current-date (3,45) edit 'DD-Mon-YYYY'
   print &_name (8,12)
  move #amount to $display_amt 9,999,990.99
  ! enclose number with asterisks for security
  let $display_amt = '**' || ltrim($display_amt,' ') || '**'
  print $display_amt (8,58)
  if #amount < 1.00
    let $spelled_amount = 'Zero dollars '
  else
    do spell_number(#amount,$spelled_amount)
    let #len = length($spelled_amount)
    ! Change the first letter to uppercase
    let $spelled_amount = upper(substr($spelled_amount,1,1))
                 || substr($spelled_amount,2,#len - 1)
    concat 'dollars ' with $spelled_amount
  end-if
  let #cents = round(mod(#amount,1) * 100, 0)
  let $cents_amount = 'and ' || edit(#cents,'00') || ' cents'
  concat $cents_amount with $spelled_amount
  print $spelled_amount (12,12)
  print 'Rebate'        (16,12)
  print ' ' (20)
  next-listing need=20
end-procedure ! print_check

The main procedure starts by setting the font to 15-point Times Roman. The select paragraph is a join of several tables. (A join is created when you select data from more than one database table in the same select paragraph.) The customers table has the customer’s name. The program joins it with the orders and ordlines tables to get the customer’s order details. It also joins with the products table for the price.

The following expression adds up all of the customer’s purchases and calculates a 10 percent rebate:

sum(d.price * c.quantity) * 0.10

The statement groups the records by the customer name, one check per customer, using the following clause:

group by name
having sum(d.price * c.quantity) * 0.10 >= 0.01

The having clause eliminates checks for less than 1 cent.

The print_check procedure is a local procedure. Note the way that it references the date and customer name with &_current-date and &_name, respectively.

See SQR Language Reference for PeopleSoft.