Info-Basic Programming (jBC)
By Abrham Bokan
Program Management Office (PMO)
CBE
Contents
Overview
Benefits of jBC
Program Structure
Compiling and cataloging jBC programs
Variables, data types, comments, Statements…
Operators
Control statements
Looping Constructs
Arrays
Strings and string functions
Subroutines
T24 programming standards
Introduction to OFS
Overview
It is a sophisticated superset of Dartmouth BASIC supporting
structured programming techniques
The terms Info-basic, jBC, Jbase Basic, JBasic are used interchangeably
to refer the same language
It is compiled language
The compilation process first converts the source code to C, which in
turn is compiled for the target platform with the usage of standard c
compiler.
It is aimed primarily at writing business applications that can utilize a
multi value database or third party DBMS depending on the
configuration it is given.
It contains all the constructs needed to access and modify files and
their data efficiently
Benefits of jBC
jBC comes with built in debugger
Calls can be made to OS functions
It is able to open/read/write OS files
File and record level locking capability
Has lots of APIs that simplify business application development and
increase developer productivity
Program Structure
jBC Program
1. PROGRAM programName
2. IncludeStatements ($INCLUDE)
3. Comments
4. Statements
5. END
Program components explained
PROGRAM - a keyword that tells the compiler that the jBC code is to
be executed from shell
SUBROUTINE – a keyword that tells the compiler that the jBC code is
to be executed from within GLOBUS
IncludeStatements – files whose contents are accessed/referenced
with in the body of the program and therefore should be included
Comments – can appear anywhere with in the source file. They are
used for documentation (code explanation).
Statements – A unit with which a program is constructed.
RETURN –transfer control to the caller
END –
Compiling, Cataloging, and Decataloging
Compile - creates the object code and put it in the same directory by
prefixing ‘$’ sign
BASIC dirName pgmFileName
E.g. If we have a program named HELLO in directory TEST.BP
BASIC TEST.BP HELLO
Catalog - command is used to create UNIX executables and shared
libraries from the application source code. Once you have cataloged your
programs, you can run them like any other command on the system.
CATALOG dirName pgmFileName
E.g. E.g. If we have a program named HELLO in directory TEST.BP
CATALOG TEST.BP HELLO
Decatalog - commands are used to remove the run-time versions of
cataloged jBC programs. Executables and shared library objects can be
removed from the bin and lib directories by using the DECATALOG
command.
DECATALOG dirName pgmFileName
E.g. E.g. If we have a program named HELLO in directory TEST.BP
DECATALOG TEST.BP HELLO
Exercise 1
Create a directory with your firstName.TEST.BP in bnk.run
E.g if your name is Dawit the directory name should be
DAWIT.TEST.BP
Write a program that prints “Welcome to infobasic programming!” to
the screen then compile, catalog and run the program. Append your
name to your program name. E.g. EXE1.DAWIT or
WELCOME.DAWIT
1. Write the program
PROGRAM WELCOME.DAWIT
PRINT “Welcome to infobasic programming!”
END
Note: To print a string to screen you can use the commands PRINT,
CRT, or DISPLAY.
Exercise 1
2. Compile the program
jsh> BASIC DAWIT.TEST.BP WELCOME.DAWIT
After successful compilation, the object code will be placed in DAWIT.TEST.BP
bnk.run/DAWIT.TEST.BP/$WELCOME.DAWIT
3. Catalog the program
jsh> CATALOG DAWIT.TEST.BP WELCOME.DAWIT
After successful cataloging the program is included in the library and the executable file
will be placed in bnk.run/bin/WELCOME.DAWIT
Run the program
jsh> WELCOME.DAWIT
Jsh > Welcome to infobasic programming!
Decatalog the program
jsh> DECATALOG DAWIT.TEST.BP WELCOME.DAWIT
After successful decataloging the program is removed from the library and the executable
file will be removed from bnk.run/bin/WELCOME.DAWIT
Run the program again
jsh> WELCOME.DAWIT
Jsh > WELCOME.DAWIT: No such file or directory
Variables, data types, comments, Statements…
A variable is a representation of data. A data stored in a variable can be
changed dynamically during program execution
Naming rule –
a jBC variable should start with alphabet followed by any sequence of
ASCII character except spaces, commas, hyphens, and mathematical
operators.
E.g. a1254, pi, p#23, are valid identifiers
125, 5a@, a-b, are invalid identifiers
jBC reserved words can’t be used as variable names. E.g ABORT,
PROGRAM, SUBROUTINE, LEN, END, WRITE …
jBC variables are case sensitive
• Constants – are similar to variables except their values doesn’t change
through out the program execution.
E.g EQUATE PI TO 3.1415926 – numeric constant
EQUATE LOG.LEVEL= “ERROR” – string constant
Variables, Data types, comments, Statements…
Assignment
Assignment statement is used to allocate a value to a variable
Syntax: variable = expression
Expression – could be a literal or statement
E.g.
Literal: age = 25
Statement: total = subtotal1 + subtotal2
Data Types –
in many programming languages, variables are typed. I.e. they can hold
certain type of data (int, char, string, …). In jBC variables are type less
allowing any type of data to be stored within them.
Since there are no data types there is no variable declaration
Implicit type conversion is performed by jBC compiler
Variables, Data types, Comments, Statements…
Comments
Has no effect on the program execution. I.e. ignored by compiler
Should start with one of the following tokens
REM, !, *
E.g
REM This a a comment that starts with REM
token
* This comment starts with asterisk
* Another asterisk comment
! Exclamation mark comment
Volume = width * height * length
Variables, Data types, Comments, Statements…
A jBC statement is an entity or command that can be sequenced with
other statements to build up an application program
Normally refer to single operation and are usually kept in a single line
Several statements, however, can be placed on the same line. In such
cases, each statement should be separated by semi colon
Statements can optionally start with a label. This is used to allow a
statement or a line to be referenced from another part of the program.
A label could be numeric or alphanumeric. If alphanumeric, it should
end with a colon.
* One statement per line
width = 12
* Multiple statements per line
height = 15; length = 25
* Statement with label
label1: volume = width * height * length; PRINT volume; * alphanumeric label
2 area = length *width ; PRINT area; * numeric label
Operators and Expressions
Arithmetic operators and expression
Arithmetic Operator Arithmetic Expression
+ 5+2; a+5
- 5-2; a-5
* 5*2; a*5
/ 5/2; a/5
^ ** exponential 5^2
Increment operator (++) - E.g var = 10
increase value by 1 ++var increments/decrements the variable “var” by 1 before its
value is used in expression
E.g. PRINT ++var; * will display 11
var++ increments/decrements the variable “var” by 1 after its
value is used in expression
E.g. PRINT ++var; * will display 10
Decrement operator (--) - Same as increment expression
decrease a value by 1
Operators and Expressions
Relational operators and expressions
A relational expression compares values or expression resultants to provide
an outcome of true (1) or false (0).
Relational Operator Relational expression
= EQ – Equal to IF A = B THEN PRINT “Equal” END
> GT – Greater than IF A > B THEN PRINT “Greater” END
< LT – Less than IF A < B THEN PRINT “Lesser” END
>= GE – Greater than or equal to IF A >= B THEN PRINT “Greater or equal”
END
<= LE – Less than or equal to IF A <= B THEN PRINT “Lesser or equal” END
# <> NE !– Not equal to IF A <> B THEN PRINT “Not equal” END
MATCHES Pattern Match
If strings are used, evaluation will be based on the corresponding ASCII values of the characters
with in the strings.
Operators and Expressions
Logical operators and expressions
Logical operators are used to perform Boolean tests in relational and
arithmetic expression
Logical Operator Logical expression
AND – returns true if both arguments are IF A AND B THEN PRINT “Both true”
true else false END
OR – returns false if both arguments are IF NOT (A OR B) THEN PRINT “Both
false else true false” END
The NOT function can be used to invert the result of the expression
Assignment operator and expressions
Assignment Operator Assignment expression
= assigns a value to a variable A = 5;
B = “HI THERE!”
Control statements
The following commands and constructs are used to change the
execution path of the linear program flow by branching to another part
of the current or even another program. The branches can be
Unconditional – as with GOTO and GOSUB statements
Conditional – on the result of an expression as with IF and CASE statements
GOTO
Syntax: GOTO label
As in most programming languages it is not recommended to use GOTO. It
usually results in spaghetti code which is difficult to read and maintain.
PRINT “Your Name”
INPUT name
GOTO DISPLAY; * executes DISPLAY line
PRINT “After GOTO statement”; * This statement will never be executed
DISPLAY: PRINT name: “Welcome to jBC programming” *
Control statements
GOSUB
The GOSUB command is used to branch to a local subroutine, which is
identified by the line label used. When a RETURN statement is encountered
in the subroutine, the program is transferred back, and execution continues
at the line following the GOSUB.
Care should be taken to structure the usage of GOSUB, and not to exit a
subroutine other than with the RETURN command. RETURN always
returns to the statement following the last executed GOSUB.
Syntax: GOSUB label
PRINT “Your Name”
INPUT name
GOSUB DISPLAY;
PRINT “After GOTO statement”; *Executed after DISPLAY statements
DISPLAY:
PRINT name: “Welcome to jBC programming”
PRINT “From DISPLAY local subroutine”
RETURN
Control statements
IF, THEN, ELSE statement
Syntax
IF expression THEN
expression(s)
END ELSE
expression(s)
END
This construct allows the conditional execution of a sequence of statements.
The conditional expression is evaluated and if the resultant value is 1 or
true, then the sequence of statements following the THEN command are
executed. If the value is 0 or false, the statements following the ELSE
command (if any) are executed.
It is possible to perform actions based on complex testing of parameters by
nesting, or successively repeating an IF ...THEN clause as part of another.
Control statements
IF, THEN, ELSE statement
IF INCOME GT 100000 THEN
PRINT “You are rich”
END
ELSE
PRINT “You need to work hard”
END
Nested if
IF SALARY < 600 THEN
TAX = 0
END ELSE
IF SALARY < 1000 THEN
TAX = 0.1 * SALARY
END ELSE
TAX = 0.2 * SALARY
END
END
Control statements
CASE statement
Syntax
BEGIN CASE
CASE expression
statement(s)
CASE expression
statement(s)
END CASE
The IF condition allows nested processing of tests, but can become unwieldy
in practice. For a number of mutually exclusive possibilities you can use the
CASE construction instead.
The CASE construction sets up a series of tests with the actions to take if the
test evaluates true. However only the first test which evaluates true is
taken; at the next CASE statement processing jumps beyond the end of the
case statement.
It makes the program much more modular and easier to follow.
Control statements
CASE statement
PRINT “ENTER YOUR ROLE”
INPUT ROLE
BEGIN CASE
CASE ROLE EQ “CSM”
CALL DISPLAY.MENU (“CSM”)
CASE ROLE EQ “FMAKER”
CALL DISPLAY.MENU (“FMAKER”)
CASE ROLE EQ “FCHECKER”
CALL DISPLAY.MENU (“FCHECKER”)
CASE 1
PRINT “ERROR: INVALID ROLE”
END CASE
Exercise 2
Write a program that takes basic salary of an employee as an input and
prints the basic salary, tax, pension (7%), and net income. If non
numeric value is supplied, the system should throw the error “Invalid
Input: Enter numeric value only”
1. Using IF…ELSE…THEN
2. Using CASE statement
Use GOSUB for structuring your program
Looping Constructs
A loop is a series of statements that are executed repeatedly for a
specified number of repetitions, or until specified conditions are met.
There are two types of loops:
counted loops: the number of times a process needs to be repeated is
known.
open loops: the number of times a process needs to be repeated is
not known.
BREAK will cause the immediate termination of the innermost loop.
CONTINUE will abandon the current iteration of the loop and
immediately begin the next iteration of the loop.
Looping Constructs
FOR loop
Syntax
FOR I = X TO Y
statement(s)
NEXT
X and Y could be variables or literal values
* Receive 10 numbers from the user and display their sum
MYSUM = 0
PRINT “Enter Your Numbers”
FOR I =1 TO 10
PRINT “Num”:I
INPUT USRNUM
MYSUM +=USRNUM
NEXT I
PRINT “The sum of your numbers is: “:MYSUM
Looping Constructs
OPEN loop
Syntax
LOOP
statements
WHILE condition DO
statements
REPEAT
* Receive any number of numbers from the user and display their sum
MYSUM = 0
I=1
PRINT “Enter Your Numbers or ‘Y’ when you finish”
LOOP
PRINT “Num”:I
INPUT USRNUM
WHILE USRNUM NE “Y” DO
MYSUM +=USRNUM
++I
REPEAT
PRINT “The sum of your numbers is: “:MYSUM
Arrays
An array is a variable where related data is held together as separate
entities.
Each entity is referred to as an element of the array.
An array takes the form of an ordered set of data and each element can
be addressed separately.
An array variable holds continuous memory locations. Thus, accessing
array elements is a fast operation.
All variables in Infobasic are treated as Dynamic Arrays
jBC allows the use of two types of array :
Dimensioned arrays: for holding data in the form of lists or tables.
Dynamic arrays: for holding file data and lists of unknown length.
Arrays
A dimensioned array provide more efficient means of creating and
manipulating tables of data elements where the number of dimensions
and the extent (number of elements) of each dimension is known and is
not likely to change.
Dimensioned arrays generally take the form of a vector (list) or matrix
(table)
Declaration
DIMENSION arrayName (row,column)
DIMENSION MULT (12,12)
Accessing elements of dimensioned array
MULT (i,j) – to access the element in the ith row and jth column
Dynamic arrays are, as the name implies, dynamic in both the number,
dimensions and their extents. Dynamic arrays are especially useful in
providing the ability to manipulate variable length records with a
variable length of fields and/or values within fields etc. A dynamic
array is just a string of characters that contain one or more delimiter
characters.
Arrays
Dynamic arrays
A dynamic array is just a string of characters that contain one or more
delimiter characters. The delimiter characters are :
Field Marker (FM), Value Marker (VM), and Sub-value Marker (SM)
E.g. WorldCities = “Africa]Ethiopia\Addis Ababa\Adama\Bahir
Dar]Egypt\Cairo\Alexandria^Europe]Germany\Berlin\Frankfurt]France\Paris\
Lyon”
Declaration
Dynamic arrays do not need any explicit declaration. Initialisation would suffice.
ARRAY = ‘’ A dynamic array being initialised.
Accessing elements of dimensioned array
arrayName <field#,value#,sub-value#>
E.g. WorldCities <1,1,1> is Addis Ababa
WorldCities <2,1,2> is Frankfurt
Strings and String functions
String
Is a sequence of numeric, alphabetic, or alphanumeric characters
String Concatenation
Strings are concatenated using the operator “:”
“Addis Ababa”:”,“:” Ethiopia” = Addis Ababa, Ethiopia
Concatenation of two strings appends the second string to the first. Concatenation
of a series of strings is done in order from left to right, and parentheses may be
used to make a particular operation take precedence.
Substring Extraction and Assignment
Substring extraction takes out part of a string and assignment allocates that part to
a variable or expression or as a value.
Syntax: S[start#,extract#]
S is the original string variable, and start# gives the starting character position, whilst
extract# gives the number of characters to extract from the string.
E.g. A="abcdef" ; X=A[3,2] assigns characters cd to X
Strings and String functions
Commonly used String functions
LEN (str) - Length of the string str
E.g:
X = LEN(“Hi There!); * X is 9
COUNT (str1,str2) – Count the number of occurrences of str1 in str2
E.g.
X = COUNT (“St”, “Strings and String functions”; *X is 2
DCOUNT (str1,str2) – Count the number of occurrences of str1 in str2 and
adds 1 to it
E.g.
X = COUNT (“St”, “Strings and String functions”; *X is 3
UPCASE (str1) – Converts str1 to upper case
E.g.
X = UPCASE (“hello”); *X is HELLO
Strings and String functions
Commonly used String functions
DOWNCASE (str1) – Converts str1 to lower case
E.g.
X = DOWNCASE(“THERE”); *X is there
TRIM (str1) – Removes excess white space from str1
E.g.
X = TRIM (“ THERE ”); *X is THERE
CHANGE (str1,str2,str3) – Change every occurrence of str2 to str3 in str1
E.g.
X = CHANGE (“Strings and String functions”,”St”,00); *X is 00rings and 00ring
functions
OCONV
ICONV
Exercise 3
Write a program that displays the name and rank of students sorted by
students’ rank. The students are taking five subjects
Input: comma separated name and marks of a given student. You should
continue to accept student records until the user finishes.
E.g. Abiy, 89,86,98,90,88
Trump,56,53,42,58,69
Output
Name (in all CAPS), average, rank sorted by rank
ABIY 90.2 1
TRUMP 55.6 2
Use
Open loops, counted loops
Dynamic arrays, Dimensioned arrays
String functions where appropriate
More on programs
Program Arguments
The SENTENCE function allows a program to locate the command used to
invoke it and the arguments it was given. It has the general form
SENTENCE ({expression})
expression should always evaluate to +ve integer. –ve integer will return a null string
SENTENCE (0) – returns the command itself. I.e. the program name. SENTENCE (i) –
the ith argument
Alternatively you can use @SENTENCE system variable. This variable holds
the full text of the last sentence executed.
EXERCISE 4
PROGRAM A1
Param = ""
ProgName = SENTENCE (0)
PRINT ProgName
FOR I = 1 TO 4
Param <I> = SENTENCE (I)
PRINT Param <I>
NEXT I
END
PROGRAM A2
PRINT @SENTENCE
END
Run the programs
jsh> A1 125 456 563 ASD ERT
A1
125
456
563
ASD
jsh> A1 125 456 563 ASD ERT
A1 125 456 563 ASD ERT
Subroutines
Programs that are executed within Globus (T24) are called subroutines.
They make use of Globus (T24) Files
They have to capacity to read, write, modify, delete data in Globus
(T24) files.
jBC subroutine
1. SUBROUTINE subroutineName
2. IncludeStatements ($INCLUDE)
$INSERT I_COMMON
$INSERT I_EQUATE
3. Comments
4. Statements
5. RETURN
6. END
Subroutines
All subroutines have to begin with the line SUBROTUINE
SubroutineName and end with RETURN and END.
The subroutine name and the name of the file where the subroutine is
to be stored should have the same name. This is a convention to be
followed to avoid unnecessary confusion.
I_COMMON and I_EQUATE are two main insert files available in
Globus.
I_COMMON defines all common global variables that can be used
across subroutines and the file I_EQUATE initializes those common
variables. It is a good practice to include these files in every subroutine
we write irrespective of whether we are to use common global
variables or not.
These insert files are available in T24.BP.
EXERCISE 5
Write a subroutine that will display the details(Id, Mnemonic and
Nationality)of some customer.
Step 1. Get some customer ID
jsh>LIST FBNK.CUSTOMER SAMPLE 1 ONLY> myCustId
Step 2. Open the Customer File
Step 3. Read the Customer file and extract the record with id myCustId
Step 4. From the extracted record obtain the mnemonic and nationality
Step 5. Display the customer id, mnemonic and
nationality.
EXERCISE 5 - Solution
1. Get some customer ID
jsh>LIST FBNK.CUSTOMER SAMPLE 1 ONLY
myCustId = 1001383883
2. Open the Customer File – we have 2 ways
Using jBase command “OPEN”
OPEN FBNK.CUSTOMER
When we use the jBase command “OPEN” to open a file, we need to supply the
exact file name(along with the prefix). If programs are written using OPEN
statements, they do not become portable across lead companies.
For E.g there are two lead companies in CBE right now. FBNK and FBK2. If we try
to execute the subroutine in lead company 2, the subroutine would return a fatal
error saying that it cannot open the file. The customer file belonging to lead
company 2 is FBK2.CUSTOMER.
Using T24 subroutine “OPF”
OPF (fileName,filePath)
FN.CUS = “FBNK.CUSTOMER”
F.CUS = “”
CALL OPF (FN.CUS,F.CUS)
EXERCISE 5 - Solution
Whenever any file needs to be opened in Globus, the core Globus subroutine OPF
is to be used. It takes in 2 parameters:
1 - The name of the file to be opened
2 - Path of the file
Both the above mentioned parameters are to be stored in variables and then passed
to the OPF subroutine.
FN.CUS = ‘F.CUSTOMER’
The name of the variable that is to store the file name has to begin with “FN.”
followed by a string that denotes the file that is to be opened. Just supply the
value “F.” followed by the name of the file to open like above to the variable
FN.CUS.
When the OPF subroutine gets executed, the FILE.CONTROL record of the file
is read to find out the type of file(INT,CUS or FIN) and then the COMPANY file
is read to find out the mnemonic of the bank. Once the mnemonic is extracted,
the ‘F.’ in the file name gets replaced with “FBankMnemonic” - FBNK thus
making subroutines portable across branches.
F.CUS = ‘’
The name of the variable that will hold the path of the file has to begin with a
‘F.’ followed by a string that denotes the file that is to be opened. This string has
to be the same as that of the file name(FN) variable. This variable should be
equated to a null(‘’).
When OPF gets executed, the VOC entry for the file is read and the path of the
data file gets populated in this variable.
EXERCISE 5 - Solution
3. Read the Customer file and extract the record with id myCustId =
1001383883 – we have twp ways
Using jBase command “READ”
READ FBNK.CUSTOMER……………
The jBase READ statement can be used to read data from a file in T24. But it has the
same problem as that of OPEN. The programs written using READ are not portable
across lead companies of the same bank.
Using the T24 subroutine F.READ(1,2,3,4,5)
1 - File name
2 - Id of the record to be read
3 - Dynamic array that will hold the read record
4 - File Path
5 – ErrorVariable
CALL F.READ(FN.CUS,” 1001383883”,R.CUSTOMER,F.CUS,CUS.ERR1)
The error variable will contain null(‘’) if the read is successful else will contain
either 1 or 2.
EXERCISE 5 - Solution
4. From the extracted record obtain the mnemonic and nationality
Contents of R.CUSTOMER
BAD0004565^ESHETIE WORKU ADEM^ESHETIE WORKU ADEM^^BDAR
03^B97^^^ET^^^^^^^^^^^^^^1000^6022^^1499^1^ET^1^ET^^^7030004565^^^^^^^^^^^
^1^^^ET0010023^^^^NO^^^^^^^^^^^MALE^^^^203377^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^NULL^NULL^^^NULL^NULL^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]3000^^^1^7026_
GTUSER__OFS_DM.OFS.SRC^1206021938^7026_GTUSER_OFS_DM.OFS.SRC^ET0010001^1
Once a record is extracted this is how it will be stored in the dynamic array. All fields
will be delimited by a field markers, multi values by value markers and sub values by
sub value markers. From this array we can extract the necessary details.
EXERCISE 5 - Solution
Most of the files in T24 have insert files which begin with ‘I_F.’ followed by
the name of the file. They will be available under T24.BP. These files hold
the definitions for all the fields. The fields could have prefixes/suffixes.
They hold the names and the field positions of the various fields.
In the customer file the prefix used is EB.CUS. suffix used is NIL
Y.MNEMONIC = R.CUSTOMER<EB.CUS.MNEMONIC>
Y.NATIONALITY = R.CUSTOMER<EB.CUS.NATIONALITY>
To extract values from a dynamic array, angular brackets “< >” need to be
used.(Use ‘()’ for dimensioned arrays)
We can extract data from the dynamic array by specifying field positions as follows
Y.MNEMONIC = R.CUSTOMER<1> or by specifying the actual name of the field
like above.
It is always advisable to use field names ‘coz field positions could change from one
release of Globus to another.
Here 1 is the field position of the field mnemonic in the CUSTOMER file. Refer the
I_F.CUSTOMER file for field names and field positions.
EXERCISE 5 - Solution
CRT “Customer Id: “:Y.CUS.ID
CRT “Customer Mnemonic: “:Y.MNEMONIC
CRT “Customer Nationality: “:Y.NATIONALITY
Use the concatenation operator “:” to concatenate values.
The full code
*Subroutine to display the details of customer 1001383883
SUBROUTINE CUS.DISPLAY.DETAILS
$INSERT I_COMMON
$INSERT I_EQUATE
$INSERT I_F.CUSTOMER
GOSUB INIT
GOSUB OPENFILES
GOSUB PROCESS
RETURN
INIT:
FN.CUS = ‘F.CUSTOMER’
F.CUS = ‘’
Y.CUS.ID = 1001383883
Y.MNEMONIC = ‘’
Y.NATIONALITY = ‘’
R.CUSTOMER = ‘’
CUS.ERR1 = ‘’
RETURN
EXERCISE 5 - Solution
OPENFILES:
CALL OPF(FN.CUS,F.CUS)
RETURN
PROCESS:
CALL F.READ(FN.CUS,Y.CUS.ID,R.CUSTOMER,F.CUS,CUS.ERR1)
Y.MNEMONIC = R.CUSTOMER<EB.CUS.MNEMONIC>
Y.NATIONALITY = R.CUSTOMER<EB.CUS.NATIONALITY>
CRT “Customer Id: “:Y.CUS.ID
CRT “Customer Mnemonic: “:Y.MNEMONIC
CRT ‘Customer Nationality: “:Y.NATIONALITY
RETURN
END
Compile and catalog the subroutine
BASIC DAWIT.TETR.BP CUS.DISPLAY.DETAILS
CATALOG DAWIT.TEST.BP CUS.DISPLAY.DETAILS
EXERCISE 5 - Solution
Execute the subroutine
Subroutines are always executed within Globus
Make an entry in the PGM with type set to ‘M’
In the PGM.FILE an entry is to be made for the subroutine.
ID - CUS.DISPLAY.DETAILS(name of the subroutine)
Type - M (Mainline program)
PRODUCT - EB(System Core)- Can supply any valid product name here like AC,ST etc
The field ‘Product’ here has no significance to our subroutine. We need to supply a
value to this field , ‘coz it is a mandatory field.
To execute the subroutine, login to T24 and type the subroutine name on the
application prompt and click enter
DEBUGGING
Sometimes the subroutine we wrote may have runtime fatal error or
logical error. In such cases, we may need to debug the subroutine in
order to identify where the problem lies.
To invoke jBase debugger, we need to add DEBUG statement in our
source code and compile it.
OPENFILES:
CALL OPF(FN.CUS,F.CUS)
RETURN
PROCESS:
DEBUG
CALL F.READ(FN.CUS,Y.CUS.ID,R.CUSTOMER,F.CUS,CUS.ERR1)
Y.MNEMONIC = R.CUSTOMER<EB.CUS.MNEMONIC>
Y.NATIONALITY = R.CUSTOMER<EB.CUS.NATIONALITY>
CRT “Customer Id: “:Y.CUS.ID
CRT “Customer Mnemonic: “:Y.MNEMONIC
CRT ‘Customer Nationality: “:Y.NATIONALITY
RETURN
END
Then rerun the program from T24 application prompt in classic.
DEBUGGING
DEBUGGING
DEBUG commands
S – execute next line
V variableName – display the value of variableName
A – executes abort statement. Returns control to T24.
Q - Quit program, issue a STOP statement
EXERCISE 6
Modify exercise 6 to display mnemonic and nationality of 10 random
customers
Algorithm
Step 1. Open the Customer File
Step 2. Select random 10 the customer ids
Step 3. Remove one customer id from the selected list
Step 4. For the extracted customer id extract the corresponding record from the customer file
Step 5. From the extracted record extract the mnemonic and nationality
Step 6. Display the customer id, mnemonic and the nationality
Repeat Steps 3 to 6 for all customers
EXERCISE 6 - Solution
Step 1. Open the Customer File – already shown on exercise 6
Step 2. Select random 10 the customer ids
Use T24 API for selecting ids of a given file – EB.READLIST
EB.READLIST(1,2,3,4,5)
EB.READLIST takes in 5 parameters.
1 - The select statement to be executed. Give the name of the variable that holds the
select statement here.
2 - The name of a dynamic array that will hold the result of the select statement
Please note that a select statement here can only select ids from the respective file.
Therefore this dynamic arrays will only hold the ids of the records that have been
selected. All the ids will be delimited by a field marker(FM).
3 - This is an optional parameter. This is the name of a file in the hard disk that can
hold the result of the select statement. Usually this is set to NULL (‘’)
4 - A variable that will hold the number of records selected.
5 - A variable to hold the return code. Will contain null if the select statement was
successful else will contain 1 or 2.
EXERCISE 6 - Solution
SEL.CMD = “SELECT FBNK.CUSTOMER SAMPLE 10” – a select query that
selects the ids of 10 customer records
SEL.LIST = “” – a variable to hold the selected IDs.
NO.OF.RECS = 0 – a variable to hold the number of records selected
SEL.ERR – a variable to hold return code. NULL => success, else error
CALL EB.READLIST (SEL.CMD,SEL.LIST,””,NO.OF.RECS,SEL.ERR)
Step 3. Remove one customer id from the selected list
REMOVE will successively extract delimited strings from a dynamic array
Syntax REMOVE variable FROM array SETTING setvar
variable is the variable which is to receive the extracted string.
array is the dynamic array from which the string is to be extracted.
setvar is set by the system during the extraction to indicate the type of delimiter found. 0 –
end of array, 2 – FM, 3 – VM, 4 - SM
REMOVE Y.CUS.ID FROM SEL.LIST SETTING POS
Step 4 – 6 already shown in previous exercixes
EXERCISE 6 - Solution
The full code
*Subroutine to display the mnemonic and nationality of sample all customers
SUBROUTINE CUS.DISPLAY.DETAILS
$INSERT I_COMMON
$INSERT I_EQUATE
$INSERT I_F.CUSTOMER
DEBUG
GOSUB INIT
GOSUB OPENFILES
GOSUB PROCESS
RETURN
INIT:
FN.CUS = 'F.CUSTOMER'
F.CUS = ''
Y.CUS.ID = ''
R.CUSTOMER = '‘
CUS.ERR1 = ''
Y.MNEMONIC = ''
Y.NATIONALITY = ''
SEL.CMD = ''
SEL.LIST = ''
NO.OF.REC = 0
RET.CODE = ''
RETURN
EXERCISE 6 - Solution
OPENFILES:
CALL OPF(FN.CUS,F.CUS)
RETURN
PROCESS:
SEL.CMD = "SELECT ":FN.CUS
CALL EB.READLIST(SEL.CMD,SEL.LIST,'',NO.OF.REC,RET.CODE)
LOOP
REMOVE Y.CUS.ID FROM SEL.LIST SETTING POS
WHILE Y.CUS.ID:POS
CALL F.READ(FN.CUS,Y.CUS.ID,R.CUSTOMER,F.CUS,CUS.ERR1)
Y.MNEMONIC = R.CUSTOMER<EB.CUS.MNEMONIC>
Y.NATIONALITY = R.CUSTOMER<EB.CUS.NATIONALITY>
CRT "Customer Id: ":Y.CUS.ID
CRT "Customer Mnemonic: ":Y.MNEMONIC
CRT "Customer Nationality: ":Y.NATIONALITY
REPEAT
RETURN
END
•Put DEBUG statement where you want to start debugging from
•Compile and catalog the subroutine
•Execute the routine from T24
EXERCISE 7
Modify Exercise 7
to store the extracted mnemonic and nationality of all customers in an
array(do not display them) delimited by a ‘,’. The array should contain data
as follows
CusId,Mnemonic,NationalityFMCusId,Mnemoic,nationalityFM…
Write the array to file
Algorithm
Step 1. Open the Customer File
Step 2. Select random 10 the customer ids
Step 3. Remove one customer id from the selected list
Step 4. For the extracted customer id extract the corresponding record from the customer file
Step 5. From the extracted record extract the mnemonic and nationality
Step 6 Store the customer id, mnemonic and the nationality in a dynamic array
Repeat Steps 3 to 6 for all customers
Step 7 Write the contents of the array to file
EXERCISE 7 - SOLUTION
Step 1 – 5 – already covered
Step 6 - Store the customer id, mnemonic and the nationality in a
dynamic array
Appending data in an array
myArray = “”
myArray <-1> = newValue
myArray <-1> = Y.CUS.ID:’,’:Y.MNEMONIC:’,’:Y.NATIONALITY
Step 7 - Write the contents of the array to file
To write contents of a variable to an array
Open the file using the API - OPENSEQ
Syntax: OPENSEQ Path TO FileVar THEN|ELSE statements
Path: the relative or absolute path of the target directory
FileVar: contains the file descriptor when open is successful
Statements: - jBase BASIC statements
OPENSEQ FILE.NAME TO FILE.PATH ELSE ; * Opens the file if it exists
CREATE FILE.PATH ELSE ABORT; * Creates the file if it doesn’t exist
END
EXERCISE 7 - SOLUTION
To write contents of a variable to an array
Write to the file using the API – WRITESEQ
Syntax: WRITESEQ(F) variable {APPEND} TO FileVar THEN|ELSE statements
• Variable – the variable whose value is to be written to file. It can also be literal value
• APPEND – appends new contents to file
• WRITESEQF – flushes the contents to file immediately
WRITESEQF myArray TO FILE.NAME THEN
CRT “Array written to file successfully”
END
ELSE
CRT “Unable to write to file”
END
EXERCISE 7 - SOLUTION
*Subroutine to store the id, mnemonic and nationality of all *customers in an array
SUBROUTINE CUS.DISPLAY.DETAILS
$INSERT I_COMMON
$INSERT I_EQUATE
$INSERT I_F.CUSTOMER
DEBUG
GOSUB INIT
GOSUB OPENFILES
GOSUB PROCESS
RETURN
INIT:
FN.CUS = 'F.CUSTOMER'
F.CUS = ''
Y.CUS.ID = ''
R.CUSTOMER = ''
CUS.ERR1 = ''
Y.MNEMONIC = ''
Y.NATIONALITY = ''
SEL.CMD = ''
SEL.LIST = ''
NO.OF.REC = 0
RET.CODE = ''
CUS.DETAILS.ARRAY = ''
FILE.NAME = “DAWIT.TEST.BP/CustData.yourName.csv”
FILE.PATH = “”
RETURN
EXERCISE 7 - SOLUTION
OPENFILES:
CALL OPF(FN.CUS,F.CUS)
OPENSEQ FILE.NAME TO FILE.PATH ELSE
CREATE FILE.PATH ELSE ABORT
END
RETURN
PROCESS:
SEL.CMD = "SELECT FBNK.CUSTOMER SAMPLE 10”
CALL EB.READLIST(SEL.CMD,SEL.LIST,'',NO.OF.REC,RET.CODE)
LOOP
REMOVE Y.CUS.ID FROM SEL.LIST SETTING POS
WHILE Y.CUS.ID:POS
CALL F.READ(FN.CUS,Y.CUS.ID,R.CUSTOMER,F.CUS,CUS.ERR1)
Y.MNEMONIC = R.CUSTOMER<EB.CUS.MNEMONIC>
Y.NATIONALITY = R.CUSTOMER<EB.CUS.NATIONALITY>
CUS.DETAILS.ARRAY<-1> =
Y.CUS.ID:’,':Y.MNEMONIC:’,':Y.NATIONALITY
REPEAT
WRITESEQF Y.CUS.ID TO FILE.NAME THEN
CRT “Array written to file successfully”
END
ELSE
CRT “Unable to write to file”
END
RETURN
END
More T24 APIs
F.WRITE(1,2,3) - Write data on to files
1 - File name
2 - Id of the record to be written
3 - Actual Record to be written
CALL F.WRITE(FN.CUS,Y.CUS.ID,R.CUSTOMER)
F.DELETE(1,2) – delete a record from file
1 - FileName
2 - Id of record to be deleted
CALL F.DELETE(FN.CUS,Y.CUS.ID)
T24 programming standards
All routines in T24 are called subroutines. Routines must not be written in such
a way that they are executed directly from jSHELL.
TEMPLATE programs should be less than 2000 lines. New template programs
should contain very little code, all code should be called from the subroutines
defined in the template e.g. FIELD.DEFINITIONS, CHECK.FIELDS &
CROSSVAL.
Subroutines should be less than 600 lines. Ideally the code should be broken
down into internal subroutines that can be viewed in its entirety on one screen
(i.e. 80 character wide by 23 lines deep).
Do not write TOP DOWN code. Each routine should have one main
controlling section with the detailed code written as subroutines. Do not
assume field 1 will be input before field 2;
Labels, Variables and Routines should not use the same names.
Labels and variables should have meaningful names. Numeric labels should
not be used. Labels must exist on their own line with no other text appended to
the label.
T24 programming standards
All code should be structured in a modular fashion and broken into small
units/paragraphs (less than 100 lines) and each unit should have a single entry and
exit point.
Avoid deeply nested IF's and large case constructs. If an IF construct exceeds 20
lines then use a GOSUB - nothing is harder to follow in a program than an IF that
starts on page 1 and ends on page 21.
DO NOT comment out existing code DELETE it.
DO NOT use asterisks (*) to create coding breaks, either use the “*---------------“
Subroutine names should be in upper case and should be as long as necessary to
describe their purpose. However subroutine names are limited to 35 characters. In
addition subroutine names should begin with the product prefix and then describe
the routine, e.g. RP.CHECK.FIELDS.
Subroutine names should not include the “$” or “_” character.
Subroutine names cannot be named with an extension of B (i.e. SC.CALC.YIELD.B).
The extension b is a reserved extension for c code and case insensitive systems such
as Windows and iSeries machines treat B the same as b. To ensure that no problems
are encountered, it is best to avoid using program names that end with ‘extensions’
that may be interpreted by the underlying system, i.e. Windows extensions .doc,
.xls, .txt, Language extensions .c, .C, .cpp, .jar, .java, .class.
T24 programming standards
Files and records
File Variable F.fileName F.ACCOUNT
File Name FN.fileName FN.ACCOUNT
Record Variable R.fileName R.ACCOUNT
Field Names and numbers
Fields must never be reference by their field number, except in conversion subroutines. You
should always use the field name as specified in the standard inserts.
Commons and Inserts
All routines MUST have I_COMMON and I_EQUATE inserted at the start of the program
Inserts must not contain inserts.
Introduction to OFS
OFS is a standard module within T24, with a module code OF. It is the
ONLY standard gateway to TEMENOS T24. Simply put, it means that
every single interaction with T24 is driven through OFS.
OFS is message driven , i.e. it works on a request-response based system.
The OFS syntax, or message structure is proprietary to TEMENOS T24. It is
the native way to represent requests to execute T24 transactions, enquiries
or routines.
The OFS module provides the infrastructure necessary to process the OFS
TEMENOS T24 technology platform products like TEMENOS Connector,
TEMENOS T24 Browser and TEMENOS Internet Bank use OFS to interact
with TEMENOS T24 Applications. This implies that when we input a
transaction , say a Funds Transfer in Browser, T24 actually receives an OFS
message for Funds Transfer. This also implies that the OFS processing is
not merely an update to the database, but goes through the same level of
validations, including SMS, as in a manual effort. messages.
Introduction to OFS
OFS - Syntax
There are 2 types of common requests in OFS. Each request follows a
particular syntax. One is a transaction request that will create, modify
or delete a record in any application in T24. The other is an enquiry
request, which queries data from T24.
OFS messages follow two formats
Native format –this is a simple string format, following a comma delimited pattern
XML format –OFS also understands an XML format which is described as the Browser
XML format since it is used only by TemenosBrowser.
You will study the native OFS format alone in this session.
OFS – Syntax
OFS – Syntax
OFS – Syntax
This diagram describes the syntax of a Transaction request.
Operation
We need to tell T24 the name of the application. Operation part of the message
contains the name of the Application. Eg: ACCOUNT.
Options
Options is optional since many of the parameters here may be defaulted. This
contains many sub-parts with each sub-part separated from the other using a
forward slash. The sub-parts are Version name/Function/Process type/
GTS.Control value/No.of.authorisers. E.g. TRG/I/VALIDATE//2
Version name –this must be a valid version name without the usual preceding
application name and comma. For eg to use a version name ACCOUNT,CLIENT
you will only specify CLIENT. Therefore comma versions are not valid.
Function –a T24 function such as I, R, A,H,V. Note that C and P is not supported.
Process Type –this may be VALIDATE or PROCESS and controls whether the
transaction is to be validated or processed.
Gts control will be discussed later. No of authorisers may be used to specify the
no of authorisers . I.e. zero, one or two. GTS control and no of authorisers if
supplied will override the corresponding settings in the Version.
OFS – Syntax
User Information
This consists of the Sign On Name/Password/Company code
E.g INPUTT/123456/GB0010001
Transaction ID
The Transaction Id part of the message contains the transaction id of the
record used in the transaction. This is optional for new transactions if the
underlying application is designed to allow this. In a case where it is allowed,
the ID may be automatically generated by the application.
The transaction ID is mandatory for See , Authorize , Delete functions. The
transaction ID can also contain an optional Message ID for the message.
For eg 20548/20081010001 .
In this case the 20548 is the record id and 20081010001 is the message id. This
message id could be used by external systems to uniquely identify each OFS
message.
OFS – Syntax
Message Data
The message data portion of the message structure contains the data
required to create or update the transaction. Message portion follows the
format
Fieldname=data
Eg CUSTOMER=100297
When you need to assign values to multi values or sub values , you may
follow the format
Fieldname :multi value number : sub value number = data
Eg CUSTOMER:1:1=100297
This implies the first sub value belonging to the first multi value of the field
CUSTOMER is assigned a value of 100297. The first multi value or sub value
is taken as the default in the absence of positions If ‘NULL’ is specified as
field data, OFS will blank the field of all data.
The message data portion of the message can be repeated for each field
separated by a comma (,).
OFS – Syntax
EXERCISE 8
OFS – Syntax
The diagram shows the syntax of OFS Enquiry type request
messages.All the main portions of the message for Enquiry type
requests are shown in it.
The structure is very much similar to a Transaction Request.You may
have noticed that the options part has been omitted,since it is not
relevant to an enquiry.However commas are given to indicate the
place-holder,and retain the general structure of an OFS message.
OFS – Syntax
OFS – Syntax
OFS – Syntax
The portions of an Enquiry Request are
ENQUIRY.SELECT
The first portion of an enquiry type request must always be ENQUIRY.SELECT.
This is the name of the routine that is used to run queries and return the data.
User information
The user information portion of the message structure is the same as that of the
transaction type request.
Enquiry Name
You will specify the name of the T24 Enquiry to run in this part.
The Enquiry name supplied here must be a valid T24 enquiry (i.e. it must be
found in the ENQUIRY application of T24).
What does the message data portion of the enquiry request contain?
The message data portion of the enquiry message structure contains the selection
criteria passed to the enquiry.
The message data portion of the message can be repeated for each selection
criteria separated by a comma(,).
OFS – Syntax
This is optional depending on the Enquiry
The three different parts of a Selection Criteria part of the
MESSAGEDATA are:
Selection Field – denotes the name of the field of that must be either a field in the
STANDARD. SELECTION for the file on which the enquiry is based(i.e.-the application that
is specified in FILE. NAME field of the ENQUIRY application)or a value set in SELECTION.
FLDS field of the ENQUIRY application.
Operand – denotes the operand that must be used for selection for the value specified in the
SELECTION. FLDS field of the ENQUIRY application. The operands can be
EQ,NE,GE,GT,LE,LT,UL,LK and NR. The operand must be separated from the selection
fields using a colon(:).
Field Value – denotes the data value for the values specified in the SELECTION. FLDS(field
of the ENQUIRY application)and the operand for selection. This must be separated from the
operand using an equal sign(=).
E.g.ACCOUNT.NUMBER:EQ=11107
OFS – Syntax
EXERCISE 9