Wednesday, July 11, 2007

Peoplecode collections

The above are the list i collected from different forums

PeopleCode: Comparing a variable to a list of values

I sometimes come across a chunk of PeopleCode that requires a variable be compared to a list of values — like the IN operator in SQL:
If &code = "ABCD" Or &code = "HIJK" Or &code = "OPQR" Then

If the condition needs to be checked multiple times within the code and the list changes, there will be some effort required to update the code.
A better coding approach is to use an array and its Find method:

Local array of string &list;
&list = CreateArray("ABCD", "HIJK", "OPQR");
...
If &list.Find(&code) > 0 Then
If the list of values changes, only the array will need to be updated.

Smarter coding techniques with arrays


you might want to collect a list email addresses this way, separating each item with a semicolon:

While &sqlEmails.Fetch(&email)
If none(&mail_list) Then
&mail_list = &mail_list ";" &email;
Else &mail_list = &email;
End-While;

Or you may want to collect a list of values to use in an IN clause for a subsequent SQL call:

For &i = 1 to &Rowset.RowCount
If &i = 1 Then &dept_list = Quote(&Rowset(&i).EMPLOYEES.DEPTID.Value);
Else
&dept_list = &dept_list "," Quote(&Rowset(&i).EMPLOYEES.DEPTID.Value);
End-If;
End-For;
&dept_list = "(" &dept_list ")";

PeopleCode arrays, with its Join() method makes this task easier. The above statements can be written as:
&Array1 = CreateArrayRept("", 0);
While &sqlEmails.Fetch(&email)
&Array1.Push(&email);
End-While;
&mail_list = &Array1.Join(";","","");
And
&Array1 = CreateArrayRept("", 0);
For &i = 1 to &Rowset.RowCount
&Array1.Push( Quote(&Rowset(&i).EMPLOYEES.DEPTID.Value) );
End-For;
&dept_list = &Array1.Join(",");

The Join() method concatenates all items in an array with a specified separator string. By default, it also encloses the concatenated value by a pair of parenthesis. These can be overridden by specifying a 2nd and 3rd parameter.

Direct access to component

Yet another thing I learned this week. It is possible to open a component directly, bypassing the search page — of course after logging in — from a URL link. In the URL, just add the search key field values in the query string. You’ll have to specify the exact search key fieldname and value pairs: ?EMPLID=AA01234&EFFSEQ=1

This could be useful when sending notifications to users via email, and you want to provide a link directly to the specific page and data.

Reading CSV file using file layout

If FileExists("c:\csv\final\dependent.csv", %FilePath_Absolute) Then
&MYFILE1 = GetFile("c:\csv\final\dependent.csv", "r", "a", %FilePath_Absolute);
End-If;
&MYFILE1.SetFileLayout(FileLayout.DEPENDENT_BENEF);
&RS1 = &MYFILE1.ReadRowset();
While &RS1 <> Null
&EMPLID = &RS1.GetRow(1).DEPENDENT_BENEF.EMPLID.Value;
...........
&RS1 = &MYFILE1.ReadRowset();
End-While;
&MYFILE1.Close();

SQL OBJECT

Local SQL &mysql;
Local record &rec;
&rec= createrecord (record.locations);
&mysql=createsql(“%selectall (:1) where setid=:2 and oprclass = :3”);
&mysql.execute(&rec,&setid, &oprclass);
If &mysql.fetch(&amp;rec) then

End-if;
&mysql.close();

To get all fields in record

Local Field &FLD;
Local Record &REC;

If CHECK_FIELD Then
&REC = GetRecord();
For &I = 1 to &amp;REC.FieldCount
&FLD = &REC.GetField(&I);
&LABELID = &FLD.Name;
&FLD.Label = &FLD.GetShortLabel(&LABELID);
End-For;
End-If;
&REC = GetRecord(); /*returns primary record */

The following returns the other record in the current row.

&REC2 = GetRecord(RECORD.CHKLST_ITM_TBL);

The following event uses the @ symbol to convert a record name that’s been passed in as a string to a component name.

Function set_sub_event_info(&REC As Record, &NAME As string)
&FLAGS = CreateRecord(RECORD.DR_LINE_FLG_SBR);
&REC.CopyFieldsTo(&FLAGS);
&INFO = GetRecord(@("RECORD." &amp;NAME));
If All(&INFO) Then
&FLAGS.CopyFieldsTo(&INFO);
End-If;
End-Function;