Professional Documents
Culture Documents
Day 3
PeopleCode
[A comprehensive 2 day tour on the capabilities of the SQR language and its usage
in PeopleSoft]
Table of Contents
Day 3:
Local
Exist for the duration of the current PeopleSoft program.
Most commonly used because there is no concern about conflict with variables
with the same name created in another program.
Should be explicitly declared in code. If not, created automatically, by
assignment.
If explicitly declared, may be assigned an initial value.
Component
• Exist for the duration of the current PeopleSoft component.
• Used to transfer values between PeopleCode programs in the current component.
• Provide a useful middle ground between the limitations of local variables and the
potential problems of global variables.
• Must be declared in each PeopleCode program in which they are used, before the
first line of executable code.
Global
• Exist for the duration of the current PeopleSoft session once it is declared.
• Should only be used to transfer values between components.
• Must be declared in each PeopleCode program in which they are used, before the
first line of executable code
Creating user-defined PeopleCode Variables
• Component and global variables must be declared before the first line of executable
code.
• As of PeopleTools 8.4, local variables can be declared anywhere.
• Declare a variable by specifying its scope, data type, and name.
Syntax:
<Scope> <data type> &varname [ = value ] [,&varname [ = value ] ...];
Example:
Component Integer &Min, &Max;
• If a variable is not explicitly declared, the PeopleCode editor will auto-declare it with
a scope of Local and a type of Any
PeopleCode
In this activity, students will create code to automatically assign emplid to new
employee being added in “ADD” mode.
2. Add a field <STU_INITIALS>_LAST_EMPLID to the table. This field stores the last
emplid assigned.
3. Create a page to access this Installation table. vendor Table and sync it with
Personal Table
7. Add code so that, in add mode, if no emplid is assigned, the code calls the above
defined function to get last emplid, increments the value by 1 and assigns the
value to Record.<STU_INITIALS>_PERSONAL.<STU_INITIALS>_EMPLID on the
new row being added.
System Variables
Derived/Work Fields
Derived work records
• Provide working storage for components.
• Exist for the duration of the current component.
• Are stored on derived/work records.
• Can be defined as edit fields, including prompt table edits, translate table edits, and
yes/no edits.
• Can be associated with push buttons
• Create a derived/work record definition (if a suitable one does not exist).
• Add a field to the derived/work record (if a suitable one does not exist).
In order for the Component Processor to allocate space in memory for the value of a
Derived/work fields are added to a page just like any other field and modified using Edit,
Page Field Properties.
PeopleCode
• Since derived/work fields are mainly updated by PeopleCode, they are usually made
display-only on a page.
• Since there is no application data stored in derived/work fields, they are allowed to
break the field order rule that all fields on the same level need to be attached to the
same record definition, unless they are related display fields.
• Besides this exception, the derived/work fields are treated the same as any other field
in a page definition. Therefore, all other field order rules apply. PeopleSoft allows
derived/work fields to be updated by a user, but the value only remains in memory until
the component is canceled.
We will see an example of how it is used to display a calculated value on a page which is
not stored in database. In this example we will show the use on Personal page where
age of an employee is calculated based on the birth date.
Open the page in Application Designer. Highlight the field and double click to look at the
field definition
Open the record DERIVED_HR and observe the field AGE_YEARS. Observe that record
DERIVED_HR is a work record.
PeopleCode
Now we have to examine and find out the code which is used to populate this based on
date of Birth. The most logical choice is the field Date of Birth. GO back to page,
highlight the field Birth date (BIRTHDATE), right click and select open definition. This will
open the record PERSON. Check if there is any FieldChange code associated with field
BIRTHDATE. Examine the code to find out the code lines responsible for populating the
AGE_YEARS derived field. Highlighted code line below is responsible for populating this
field based on date of birth. Note that it is a function.
PeopleCode
In this code line, highlight the text “AgeInYears”. Right click and click on option “View
Function AgeInYears”. This will open up the function
4. Open the page <STU_INITIALS>_PERSONAL and add this derived field. Make it
display only as the value is not editable and it will be calculated by PeopleCode.
5. Write a code
Record.<STU_INITIALS>_PERSONAL.<STU_INITIALS>_DT_BIRTH.FieldChange to
populate the “Age in Years” derived field.
6. Check your application
7. Do you see it working correctly? Do you see the value when you open an existing
record?
8. If not, discuss and place code in any other required field.
9. If time permits, move the code to a function which has a parameter Birth_date of
date type and returns the “Age in Years” based on the difference of system date and
Birth date.
10. Replace the code to leverage the function you have just written.
Variable Prompts
Often your business rules require that a particular field prompt different records
depending on factors that are determined at runtime, such as:
• Which component the field is on.
• Who the user is (OPRID).
• The value of another field on the component
We have seen that we specify the Prompt table name in record use properties.
This prompt table cannot be changed at run time. Now, consider a scenario where we
want the Prompt table needs to be changed at run time based on state of application
which could value in a particular field. The functionality of variable prompt takes care of
PeopleCode
this scenario. Its implementation allows the Prompt Table name to be changed
programmatically within PeopleCode.
The screenshot below shows the record JOB with TAX_LOCATION_CD highlighted.
Observe that field TAX_LOCATION_CD has %RECNAME_EDIT as the Prompt table name.
We will discuss some of the common functions. You are encouraged to refer to
PeopleBooks for a detailed description of all the PeopleCode built-in functions.
PeopleCode
The screen shot below shows that there is a code on field “Lines on Paysheet”. The
runtime output is shown below
As you can see, message set 2000,120 is used. There is also a default description in
code above which is displayed if the message 2000,120 is not found in database.
PeopleCode
There are two numbers which in combination define a unique message. First one is
Message Set number which is 2000 in this case. The other one is Message Number which
is 120 in this case.
MsgGet Function
The PeopleCode built-in function MsgGet retrieves a message from the Message Catalog
Syntax:
MsgGet (message_set, message_num, default_msg_txt [, paramlist])
PeopleCode
Example:
Error MsgGet(1000, 38, "Date of Death must be later than Birthdate.")
You can also pass parameters which will be dynamically replaced in the text string.
e.g. Error MsgGet(8, 1, "Message Not found", &objectId)
Two other functions that can be used to retrieve messages from the Message Catalog
include MsgGetText and MessageBox.
MessageBox retrieves messages from the Message Catalog, but provides the flexibility
to change the severity of a message through the Message Catalog, without modifying
PeopleCode.
MessageBox (style, title, message_set, message_num, default_txt [,paramlist])
MsgGetText is very similar to MsgGet except the message set and message number
will not appear after the text of the message.
MsgGetText (message_set, message_num, default_txt [, paramlist])
PeopleCode
Logical Functions
All and None check for the existence (or non-existence) of a value in a field or variable.
All (fieldlist)
Description
Use the All function to verify if a field contains a value, or if all the fields in a list of fields
contain values. If any of the fields are Null, then All returns False.
A blank character field, or a zero (0) numeric value in a required numeric field is
considered a null value.
Related Functions
AllOrNone Checks if either all the field parameters have values or none of them
have values. Use this in examples where if the user fills in one field,
she must fill in all the other related values.
OnlyOne Checks if exactly one field in the set has a value. Use this when the
user must fill in only one of a set of mutually exclusive fields.
OnlyOneOrNone Checks if no more than one field in the set has a value. Use this in
examples when a set of fields is both optional and mutually exclusive;
that is, if the user can put a value into one field in a set of fields, or
leave them all empty.
Returns
Returns a Boolean value based on the values in fieldlist. The All function returns True if
all of the specified fields have a value; it returns False if any one of the fields does not
contain a value.
Example
PeopleCode
The All function is commonly used in SaveEdit PeopleCode to ensure that a group of
related fields are all entered. For example:
Definition of a Null:
Character Field: Empty String (space)
Number Field: Zero
Others: Null
PriorValue can be used to retrieve the value of a field just before it changed.
PriorValue(FieldName);
String Functions
Substring extracts a substring from a string, beginning at a certain starting position, for
the specified length.
This example sets &PAGE_NAME to the first six characters of the name of the current
page:
&PAGE_NAME = Substring (%page, 1, 6);
RTrim and LTrim trim specified characters from the right or left of a string.
RTrim(source_str [, trim_str])
LTrim(source_str [, trim_str])
Find returns the starting position of string within within_string. If it is not found, it
returns zero.
Find(string, within_string [, number])
Len returns the length of string including leading and trailing spaces.
Len(string)
The AddToDateTime built-in function is used to add to any component of a date (day,
month, year). This function takes care of leap year, varying days across months to do
the calculation.
PeopleCode
Consider that we want to find the date 5 years from now. We cannot just add 365*5
days to get that as there might be 1 or 2 leap years in between. AddToDateTime and
AddToDate take all of that into consideration.
AddToDateTime uses seven parameters: the date, the number of years , months, days,
hours, minutes and seconds to add. Passing negative numbers as parameters will
subtract from the date.
The example shown below finds the date 2 year, 4 months, and 12 days from a date
field called <STU_INITIALS>_BORROW_DT.
AddToDate is similar except that it can manipulate only the date part and leaves the
time part untouched:
&4MonthsFromEffDt = AddToDate(&EFFDT, 0, 4, 0);
String and Value convert fields and variables to character strings and numbers.
String(number)
Value(string)
The String and Value built-in functions convert fields and variables to character strings
and numbers.
You may always want to store a number as a certain length, and so create it as a
character field. For instance, your invoice numbers may always have 5 characters, so
the first one would be “00001”, 2nd one “00002” and so on.
To compare two numbers and find the lesser value, PeopleCode requires that both fields
are numbers rather than strings. Otherwise, the comparison might not give the expected
results.
Reserved Words
When a program references an Application Designer definition name, PeopleCode uses
reserved words to identify the type of definition being referenced.
• RECORD.<recordName>
• PAGE.<pageName>
PeopleCode
• COMPONENT.<ComponentName>
Using this construct improves the maintainability of the code. If you rename a record,
then all reference using RECORD.<recordName> are automatically updated.
Component Buffers get loaded when you open a component. We use classes of objects
that access the structured component buffers.
There are four data buffer classes:
Rowset
Row
Record
Field
These four classes are the foundation for accessing Component Buffer.
A field object, which is instantiated from the Field class, is a single instance of
data within a record and is based on a field definition.
A record object, which is instantiated from the Record class, is a single instance
of a data within a row and is based on a record definition.
A row object, which is instantiated from the Row class, is a single row of data
that consists of one to n records of data. A single row in a component scroll is a
row. A row may have one to n child rowsets. For example, a row in a level 2
scroll may have n level 3 child rowsets.
A rowset object is a data structure used to describe hierarchical data. It is made
up of a collection of rows. A component scroll is a rowset. You can also have a
level 0 rowset.
The hierarchy to access data from the component buffer using classes is –
Rowset -- Row -- Record -- Field
Suppose you want to access the BRIEFING_STATUS field at level 2 of the following
page:
Start with level 0. Traverse the data hierarchy, through the level 1 rowset, to the level 2
rowset, before you can access the record that contains the field. Here's the hierarchy
again:
A rowset contains one or more rows, a row contains one or more records and zero or
more child rowsets, and a record contains one or more fields.
Rowset
Obtain the level 0 rowset, which is the PERSONAL_DATA rowset. However, you do not
need to know the name of the level 0 rowset to access it.
&LEVEL0 = GetLevel0();
Because we're processing all the rows at the level 1, we're just adding code to the
previous For loop. As we're processing through all the rows at level 2, we're adding a
second For loop. The new code is in bold.
For &I = 1 to &LEVEL1.ActiveRowCount
&LEVEL1_ROW = &LEVEL1(&I);
&LEVEL2 =
&LEVEL1_ROW.GetRowset(SCROLL.EMPL_CHKLST_ITM);
For &J = 1 to &LEVEL2.ActiveRowCount
&LEVEL2_ROW = &LEVEL2(&J);
.........
End-For;
End-For;
PeopleCode
Because we're processing all the rows at the level 1, we're just adding code to the
previous For loops. The new code is in bold.
For &I = 1 to &LEVEL1.ActiveRowCount
&LEVEL1_ROW = &LEVEL1(&I);
&LEVEL2 =
&LEVEL1_ROW.GetRowset(SCROLL.EMPL_CHKLST_ITM);
For &J = 1 to &LEVEL2.ActiveRowCount
&LEVEL2_ROW = &LEVEL2(&J);
&RECORD = &LEVEL2_ROW.EMPL_CHKLST_ITM;
&FIELD = &RECORD.BRIEFING_STATUS;
/* Do processing */
End-For;
End-For;
PeopleCode
Using Shortcuts
The previous code is the long way of accessing this field. What if you wanted to use all
the shortcuts, and access the field in one line of code? Here it is! The following code
assumes all rows are 1.
IN this activity, we will revisit the page that was created in activity 5 where we had
created the page to access three tables in the same page. These tables were
<STU_INITIALS>_TITLE_TBL; <STU_INITIALS>_VOLUME_TBL and
<STU_INITIALS>_BORROW_DTL.