You are on page 1of 27

PeopleCode

Day 3
PeopleCode
[A comprehensive 2 day tour on the capabilities of the SQR language and its usage
in PeopleSoft]

People Tools - 3 Day Class


PeopleCode

Table of Contents

1.1: Review 3 days Agenda ................................................................................ 3


Day 3:........................................................................................................................... 4
3.1: Review day 3 Agenda .................................................................................. 4
3.2: Using Variables............................................................................................... 4
3.3: Built-In Functions........................................................................................ 15
3.4: Classes and accessing data using classes ....................................... 23
PeopleCode

1.1: Review 3 days Agenda


We will be covering this section on PeopleCode over a period of three days. A brief
breakup of the material is as given below

Day 1 will cover following areas


 Understanding PeopleCode (PC) development environment
 Understanding Component Processor & Events
 PeopleCode Event Listing
 Writing and Debugging Programs
 Object orientation in PeopleCode

DAY 2 will cover following areas


 Explaining component buffer
 Understanding execution flow in multi level pages
 Understanding PeopleCode language
 Understanding events in detail
 Understanding Add mode Processing
 Understanding Deferred Processing

DAY 3 will cover following areas


 Classes and accessing data using classes
 Using Variables
 Built-in functions
PeopleCode

Day 3:

3.1: Review day 3 Agenda

Day 3 will cover following topics:


 Using Variables
 Built-in functions
 Classes and accessing data using classes

3.2: Using Variables

This topic will cover.


 User defined variable
 System variables
 Derived/Work fields
 Variable prompts

User Defined Variables


User Defined variables are created and used within PeopleCode program. User-defined
variables are created to temporarily hold data. They act and work like variables in any
other language.
User defined variables are named using following convention:
1. Must begin with &
2. Name can be up to 1000 character long
3. May consist of alphabets, numbers and characters #, $, _ and @

Scope determines how long a variable will remain in memory


Scope can be
 Local: Life of the program in which it is defined
 Component: Life of the component in which it is defined
 Global: Life of the entire session
PeopleCode

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

Activity 15 – Create A function to populate Emplid in Add mode

In this activity, students will create code to automatically assign emplid to new
employee being added in “ADD” mode.

1. Create a table <STU_INITIALS>_INSTALLATION. This table is a single row table


with no keys.

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

4. Open table <STU_INITIALS>_PERSONAL. Change the default for field


<STU_INITIALS>_EMPLID to “New”.

5. Create a Derived record <STU_INITIALS>_FUNCLIB to store the function you are


going to create.

6. Add a field <STU_INITIALS>_EMPLID. Write the function to which returns the


Last_emplid from Installation 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.

8. It then also updates the <STU_INITIALS>_LAST_EMPLID on


<STU_INITIALS>_INSTALLATION with the incremented value.

System Variables

Some characteristics of system variable are:


 Are created when a user logs on to PeopleSoft.
 Exist for the duration of the current PeopleSoft session.
 Begin with “%”.
 Are maintained internally.
 Can be referred to in PeopleCode programs at any time.
PeopleCode

Some common system variables are:


 System Date and Time
o %Date
o %Time
o %DateTime
 others
o %EmployeeId
o %Menu
o %Mode
o %PrimaryPermissionList (Field-level security)
o %UserId
o %Page
o %Component
o %SQLRows
There are many more. Please refer to PeopleBooks for the same.

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

Use derived/work fields instead of variables when:

• You need to display values on a field, such as calculated fields.

• Generally, relational databases do not store calculated fields.

• Variables cannot be displayed on a page.


• You need a push button and don’t want to store the action.
PeopleCode

To use a derived/work field, you:

• 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).

• Add the derived/work field to a page to allocate space in memory.


• Use it in PeopleCode programs.

In order for the Component Processor to allocate space in memory for the value of a

derived/work field, it needs to be added to the page definition. The Component


Processor

uses page definitions to determine buffer allocation..

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.

• Derived/work fields can be placed on any occurs level.

• 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.

Activity 16 – Walkthrough on a derived field

See the field from PIA which is a derived field


PeopleCode

Press Ctrl+J to get the component definition name.

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

Activity 17 – Add a field to display age in Years in <STU_INITIALS>_PERSONAL

In this activity, we will add a field on <STU_INITIALS>_PERSONAL page to display the


person’s age in years.
1. Modify the table, page associated with <STU_INITIALS>_PERSONAL to add a date
field <STU_INITIALS>_DT_BIRTH
2. Create a new field of type Number with length 3.0. Name the field
<STU_INITIALS>_AGE_YRS
3. Create a new record <STU_INITIALS>_HR_WRK. Add field
<STU_INITIALS>_AGE_YRS to this record.
PeopleCode

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.

Essentially it means that there is a field Record.DERIVED.RECNAME_EDIT which will be


present on the JOB page. The value of this field will be manipulated in run time. This
value will be the name of the actual Prompt Table which will be used at run time for data
edit validation.

The associated code to manipulate the same is given below


PeopleCode

3.3: Built-In Functions

Some categories of PeopleCode built-in functions include:


• Component Buffer functions - Used to modify fields, values, and variables within the
buffers of the component. For instance, they can update the value of a field, hide a field,
or retrieve the value of a field for other processing
• Logical functions - Used to check if values exist for a field. For instance, they can be
used to check if a field contains a value or if a set of fields either all have values or none
have values
• Date and time functions - Used to calculate and manipulate dates easily. For instance,
they can get the exact date 18 months from now or parse out dates into their day,
month, and year components
• String functions - Work with character strings. They can convert strings to
numbers and vice versa, get a substring, and convert the case of a string.
• Number functions - Work with numeric values
 Message Catalog Function -Retrieve text messages from the message catalog

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 Message Catalog:


• Provides one central place to create and maintain messages, rather than hard-coding
them into all your PeopleCode programs.
• Allows you to reuse (and share) messages between programs.
• Facilitates translation

The screen shot below shows that there is a code on field “Lines on Paysheet”. The
runtime output is shown below

The code which triggers this is

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.

Message Number is sequential number automatically assigned by PeopleCode and its


maximum value is is 32,767.
Severity: This is used in conjunction with the MessageBox function. Typically, you will
use the Message option.
Message Text: Text displayed; can be up to 100 characters in length.
Explanation: Additional information about the message.
Each message set is given a long description and a short description. Message sets
20,000–32,767 are available for use by customers. All other message sets are owned by
PeopleSoft and are subject to overwrite at upgrade time.

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)

In above message, %1 will be replaced by %objectId at run time.

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)

Where fieldlist is an arbitrary-length list of field names in the form:

[recordname.]fieldname1 [, [recordname.]fieldname2] ...

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

None Checks that a field or lists of fields have no value.

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:

If All(RETURN_DT, BEGIN_DT) and


8 * (RETURN_DT - BEGIN_DT) (DURATION_DAYS * 8 + DURATION_HOURS)
Then
Warning MsgGet(1000, 1, "Duration of absence exceeds standard hours for number of
days absent.");
End-if;

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.

Substring (source_str, start_pos, 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])

The following removes leading blanks from &DESCR:


&OUTSTRING = LTrim(&DESCR);
PeopleCode

The following removes leading punctuation marks from &DESCRLONG:


&OUTSTRING = LTrim(&DESCRLONG, ".,;:!?");

The following example removes trailing blanks from &DESCR:


&OUTSTRING = RTrim(&DESCR);

The following example removes trailing punctuation marks from &DESCRLONG:


&OUTSTRING = RTrim(&DESCRLONG, ".,;:!?");

Find returns the starting position of string within within_string. If it is not found, it
returns zero.
Find(string, within_string [, number])

&Index = Find(“e”, “Reference”) – will return 2


&Index = Find(“e”, “Reference”,3) – will return 4
&Index = Find(“e”, “Reference”,7) – will return 9
&Index = Find(“t”, “Reference”) – will return 0

Len returns the length of string including leading and trailing spaces.
Len(string)

&length = Len( “Reference”) will set &length to 9.


&length = Len (Ltrim(Rtrim(“Reference”, “e”),”Re”)) will set &length to 6.

Some Other Functions


AddToDateTime is used to add to any component of a datetime to a datetime.

AddToDateTime(datetime, years, months, days, hours, minutes, seconds)

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.

AddToDateTime(<STU_INITIALS>_BORROW_DT, 2, 4, 12, 0, 0, 0);

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.

3.4: Classes and accessing data using classes

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

Traversing the Data Buffer Hierarchy Example

Suppose you want to access the BRIEFING_STATUS field at level 2 of the following
page:

Employee Checklist page


PeopleCode

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();

Rowsets Contain Rows


The next object to get is a row. As this code is working with data that is loaded from a
page, there will only be one row at level 0.
&LEVEL0_ROW = &LEVEL0(1);
PeopleCode

Rows Can Contain Child Rowsets


To get to the level 2 rowset traverse through the level 1 rowset first. Therefore, the next
object we want to get is the level 1 rowset.
&LEVEL1 = &LEVEL0_ROW.GetRowset(SCROLL.EMPL_CHECKLIST);

Rowsets Contain Rows


If you're traversing a page, the first thing to always do after you get a rowset is to get
the appropriate row. Because we want to process all the rows of the rowset, we set this
up in a loop.
For &I = 1 to &LEVEL1.ActiveRowCount
&LEVEL1_ROW = &LEVEL1(&I);
........
End-For;

Rows Can Contain Child Rowsets, Rowsets Contain Rows


We need to traverse down another level in our page structure (second level rowset).
Then access the rows in the second level rowset, in another loop.

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

Rows Contain Records


Rows also contain records. In fact, a row will always contain a record, and may contain
only a child rowset, depending on how your page is set up. GetRecord is the default
method for a row, so all you have to specify is the record name.
Because we're processing all the rows at the level 2, 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;
.........
End-For;
End-For;

Records Contain Fields


Records are made up of fields. GetField is the default method for a record, so all you
have to specify is the field name.

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.

Activity 18 – Use a RowSet in a multiple Occur Level Page

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.

We will create three Derived/Work fields which will display


1. Total number of volumes available for a specific title.
2. Of this the number of volumes that can be borrowed.
3. Number of volumes that have been borrowed at this moment. The logic to be used is
to find any blank row which has <STU_INITIALS>_RETURN_DT blank. This should be
counted as borrowed but not returned.

You might also like