Search This Blog

Wednesday, September 16, 2009

Handy PeopleCode for beginners


Hide a Row in a Grid or Scroll Area Using PeopleCode:

The picture below shows a gird with 2 rows, one of Address Type "Home" and the other with Address Type "Mailing". I would like to hide rows on the grid that have anything other than Address Type "Home": Now what I would like to accomplish is this: And now the code on how to go about doing this:

Local Rowset &Level1;
&Level1 = GetLevel0()(1).GetRowset(Scroll.PERSON_ADDRESS);
For &i = 1 To &Level1.ActiveRowCount
&AddrType = FetchValue(Scroll.PERSON_ADDRESS, &i, PERSON_ADDRESS.ADDRESS_TYPE);
If &AddrType <> "HOME" Then
&Level1(&i).Visible = False;
End-If;
End-For;

Visible Property Description:

If this property is True, the row is visible if displayed on the current page. This property can be set False to hide the row. When Visible is set to False to hide a row, the row moves to the end of the rowset. This means that the row number of the row being hidden, and any subsequent rows, changes as a result of hiding a row.


If the row is later made visible again, it is not moved back to its original position, but remains at the end of the rowset. It is just moved to the start of all the other hidden rows. For example, if there are 4 rows in a rowset and row 2 is hidden (that is, Visible = False), that row now becomes row 4. In order to make that row visible again, row 4 must be set to Visible = True.


Alternatively, you can use a row object reference: this remains valid even though the row number of the row may have been changed. You cannot hide rows in the current context of the executing program. This means Visible cannot hide the row containing the executing program, or in a child rowset and be executed against its parent rowset. Place your PeopleCode in a parent rowset and execute it against a child rowset.


Pass Dynamic Value to a Grid Label:

A grid label is the blue (normally) colored grid header that you see on PeopleSoft pages. The grid text label can be easily edited using the Grid Properties in app designer. Once you have the grid properties box open, click the Label tab > Properties and there you can see the Label Text area. You can choose between a Static Text type or Message Catalog. I would almost always go with Message Catalog type as this could be easily updated online.

Now, what if you would like to have a part of the grid label text to be dynamic. For example, you want the grid on the Self Service Phone Numbers page to say "Phone Numbers for some user" instead of just "Phone Numbers".

Step one:
Create your message catalog. Mine is (25000, 5) and at the subject line I entered "Phone Number for %1". The %1 will be later substituted with the user name accessing his/her self service.

Step two:
Open the phone numbers self service page in app designer and double click on the grid > Label tab > click 1st properties button (Header Area - Display title) > Type = Message Catalog > enter your Message Set/Number.

Step three:
Add the following code to your page activate event.

Declare Function get_person_name PeopleCode FUNCLIB_NAME.PERSON_NAME FieldFormula;
/* this line might already be there but this is needed if you are working on a custom page*/
&GRID = GetGrid(Panel.HR_PERSONAL_PHONE, "PERSONAL_PHONE");
/* This function converts the name to a user friendly format */
&Name = get_person_name(%UserId, "", "", "");
&GRID.Label = MsgGetText(25000, 5, "Message Not Found", &Name);

There you have it, save and navigate to the page and you should see the user's name showing in the grid label text.


Check for Data Duplicates on a Grid:

Here is a piece of code to prevent duplicate data on a specific field on a page grid. You can of course modify it to check for multiple fields or even the whole row.

/* Check for data duplicates on a grid. */
Local Row &row1, &row2;
Local number &r, &r1;

&rs = GetLevel0().GetRow(1).GetRowset(Scroll.grid_table);
For &r = 1 To &rs.ActiveRowCount
/*Get grid row*/
&row1 = &rs.GetRow(&r);
/*once we have a row, we are going to loop through the grid rows and make sure a specific field value is unique*/
For &r1 = 1 To &rs.ActiveRowCount
&row2 = &rs.GetRow(&r1);
/* if this is a different row, and the field_name value matches then throw an error*/
If &r1 <> &r And
&row1.grid_table.field_name.Value = &row2.grid_table.field_name.Value Then
MessageBox(0, "", 0, 0, "Error. Duplicate values are not allowed.");
End-If;
End-For;
End-For;

I recommend storing your Error message into the message catalog. If you do that then just replace the last two zeros in the MessageBox Function with your message_set and message_num accordingly.

Send Emails from People Code (Send Mail Function):

You can use the SendMail PeopleCode function to send emails from within PeopleCode. You can also call this function from an Application Engine.
Note: Make sure your SMTP server is configured properly or the SendMail function will fail.

Local string &MAIL_CC, &MAIL_TO, &MAIL_BCC, &MAIL_SUBJECT, &MAIL_TITLES, &MAIL_TEXT, &MAIL_FILES, &MAIL_FROM, &REPLYTO, &SENDER;
Local number &MAIL_FLAGS;

&MAIL_FLAGS = 0;
&MAIL_TO = "email-address-message-going-to";
&MAIL_CC = "";
&MAIL_BCC = "";
&MAIL_SUBJECT = "Test email";
&MAIL_TEXT = "Sending an email from PeopleCode.";
&MAIL_FILES = "";
&MAIL_TITLES = "";
&MAIL_FROM = "email-address-message-is-from";
&MAIL_SEP = ";";
&CONTTYPE = "";
&REPLYTO = "";
&SENDER = "";

&RET = SendMail(&MAIL_FLAGS, &MAIL_TO, &MAIL_CC, &MAIL_BCC, &MAIL_SUBJECT, &MAIL_TEXT, &MAIL_FILES, &MAIL_TITLES, &MAIL_FROM, &MAIL_SEP, &CONTTYPE, &REPLYTO, &SENDER);

If &RET <> 0 Then
MessageBox(0, "", 0, 0, "Return code from SendMail= " &RET);
/*Do error processing here*/
End-If;

Delete Grid Blank Rows Entered by Users When Saving:

Sometimes users click the "+" on the grid to enter data but end up clicking it more than once and getting some extra empty rows in the gird. The peopleCode to get rid of any extra empty grid rows when the user saves is as follows:

Local Rowset &pnlbuf;
Local Rowset &data;
Local number &Rows;
Local string &Ethnic, &Descr, &Primary;
/*If there is a blank row entered, delete the row*/
&pnlbuf = GetLevel0();
&data = &pnlbuf(1).GetRowset(Scroll.DIVERS_ETHNIC);
&Rows = &data.ActiveRowCount;
For &i = &Rows To 1 Step - 1
&Ethnic = &data.GetRow(&i).GetRecord(Record.DIVERS_ETHNIC).GetField(Field.ETHNIC_GRP_CD).Value;
&Descr = &data.GetRow(&i).GetRecord(Record.ETHNIC_GRP_TBL).GetField(Field.DESCR50).Value;
&Primary = &data.GetRow(&i).GetRecord(Record.DIVERS_ETHNIC).GetField(Field.PRIMARY_INDICATOR).Value;
If None(&Ethnic) And
None(&Descr) And
None(&Primary) Then
&data.DeleteRow(&i);
End-If;
End-For;


Hide a subpage:

There is no Peoplecode function to hide a subpage directly, BUT one way around that is putting the subpage in a group box and hid the group box instead. Hiding the group box will end up hiding your sub page.

Make sure to follow the following post, it will walk you through how to hide a group box on a page


Bypass search page by role:


Sometimes you would like to bypass the search page depending on the user's role. For some users, they need the ability to look at other employee’s time sheets, managers for example. However, for others, they should only be restricted to their own data. Below is PeopleCode example that will bypass the search page depending on users' role.

&FLAG_ROLE = "Y";
For &I = 1 To %Roles.Len;
If %Roles [&I] = "CSR" Or
%Roles [&I] = "Operations Service Center" Then
&FLAG_ROLE = "N";
/*Allow this person to enter the search page*/
SetSearchDialogBehavior(1);
/*Unhide name for user to be able to search */
UnHide(your_search_record_onthe_component.NAME);
End-If;
End-For;
If &FLAG_ROLE = "Y" Then
your_search_record_onthe_component.EMPLID = %EmployeeId;
/*Hide emplid and name so user can not search*/
Hide(your_search_record_onthe_component.EMPLID);
Hide(your_search_record_onthe_component.NAME);
/* skip search page */
SetSearchDialogBehavior(0);
AllowEmplIdChg( True);
End-If;


Read Data from Table or Views into a Rowset Object:

Grids are used all the time in PeopleSoft, and to populate them with dynamic data could be quite challenging. Use the "Select" function to read data from the database tables or views into either a row or rowset object.

The following example first flushes the hidden work scroll, then selects into it based on a field on the page, or any criteria that you add to the “where clause”.

&RS = GetLevel0()(1).GetRowset(Scroll.CHECKLIST_ITEM);
&RS.Flush();
&RS.Select(RECORD.CHECKLIST_ITEM, "where Checklist_CD = :1 and
EffDt = (Select Max(EffDt) from PS_CHECKLIST_ITEM Where CheckList_CD =
:2)", CHECKLIST_CD, CHECKLIST_CD);


People Code SearchSave Event:

SearchSave PeopleCode is performed after the user clicks the Search button or the Add button on the search page.


• User SearchSave to validate values entered in the search page fields.
• Place SearchSave PeopleCode on search key fields or alternate search key fields on a search record or component search record.
• User Error and Warning statement to validate search page fields.

Here is an example of a SearchSave PeopleCode event:

rem No spaces allowed in User Id
rem also do not allow the userid of PPLSOFT

if %Mode = "A" Then
&find = Find(" ", PSOPRDEFN_SRCH.OPRID);
if &find > 0 Then
Error MsgGet(48, 54, "Message not found.");
End-If;
if Upper(PSOPRDEFN_SRCH.OPRID = "PPLSOFT" Then
Error MsgGet(48, 235, "Message not found.");
End-If;
End-If;

Things to know about SearchInit PeopleCode event
• SearchInit PeopleCode is performed before the search page is displayed.
• User SearchInit to control processing before a user enters values in the search page.
• Place SearchInit PeopleCode on search key fields or alternate search key fields on a search record or component search record.
• Do not place errors or warnings in SearchInit

Here is an example that prevents a user from using the change password page to change another user's password!


rem Self Service user profile

PSUSERSELF_SRCH.OPRID = %UserID;
SetSearchDialogBehavior(0);

SetSearchDialogBehavior with a parameter of 0 will ship over the search page if the search key fields are populated ;)

4 comments:

  1. Thanks, your post solved my problem..

    ReplyDelete
  2. Hey I'm trying to get a figure on people code and I love you examples. Just wanted to let you know that:
    if Upper(PSOPRDEFN_SRCH.OPRID = "PPLSOFT" Then
    should logically be
    if Upper(PSOPRDEFN_SRCH.OPRID) = "PPLSOFT" Then

    ReplyDelete
  3. Thanks Bryce, that was a typo error,

    ReplyDelete