Monday, July 12, 2010

Using Rowid to tune an App-engine

Most UPDATE statements get written using the technique:

UPDATE

SET =

WHERE

However, if the value that you’re setting the field to is a fairly complex SQL statement of its own there may be a better way (particularly if you have an Oracle DB). You can take advantage of the fact that ROWID is the fastest way to locate a row (faster even than the primary key). Run the first bit of SQL to select the rowid of the row to update and the value to update it to, and then the second bit to run the updates. This can be done either as 2 SQL blocks or with an App Engine Step containing DoSelect and SQL actions.

The Select Statement

SELECT rowidtochar(rowid),

FROM

WHERE

The Update Statement

UPDATE

SET =

WHERE rowidtochar(rowid) = rowidtochar(rowid)

If you are doing this inside an App Engine, you’d need to add the rowid and value fields to the state record, and put a %Select at the start of the SELECT statement. Then you can refer to the value and the rowid in the UPDATE statement using %Bind.

Example

The Select Statement – Inside a DoSelect Action

%Select(ROWNAME1, JRNL_TOTAL_LINES, JRNL_TOTAL_DEBITS, JRNL_TOT_CREDITS)

SELECT rowidtochar(H.rowid) row_id

, (SELECT MAX(L1.JOURNAL_LINE)

FROM PS_JRNL_LN L1

WHERE L1.business_unit = h.business_unit

AND L1.journal_id = h.journal_id

AND L1.journal_date = h.journal_date

AND L1.unpost_seq = h.unpost_seq) MAX

, NVL((SELECT SUM(L2.MONETARY_AMOUNT)

FROM PS_JRNL_LN L2

WHERE L2.business_unit = h.business_unit

AND L2.journal_id = h.journal_id

AND L2.journal_date = h.journal_date

AND L2.unpost_seq = h.unpost_seq

AND L2.MONETARY_AMOUNT > 0),0) SUM_DEBITS

, NVL((SELECT SUM(L3.MONETARY_AMOUNT)

FROM PS_JRNL_LN L3

WHERE L3.business_unit = h.business_unit

AND L3.journal_id = h.journal_id

AND L3.journal_date = h.journal_date

AND L3.unpost_seq = h.unpost_seq

AND L3.MONETARY_AMOUNT <>

FROM PS_JRNL_HEADER H

WHERE (H.JOURNAL_ID LIKE 'OBAL%' OR H.JOURNAL_ID LIKE 'CBAL%')

The Update Statement – Inside a SQL Action

UPDATE PS_JRNL_HEADER

SET JRNL_TOTAL_LINES = %Bind(JRNL_TOTAL_LINES)

, JRNL_TOTAL_DEBITS = %Bind(JRNL_TOTAL_DEBITS)

, JRNL_TOT_CREDITS = %Bind(JRNL_TOT_CREDITS)

WHERE rowid = %Bind(ROWNAME1)


list all the components that a user has access

SELECT DISTINCT A.ITEMNAME COMPONENT, A.ITEMLABEL LABEL
FROM PSMENUITEM A
, PSPNLGRPDEFN B
, PSAUTHITEM C
WHERE A.ITEMTYPE = 5
AND A.PNLGRPNAME = B.PNLGRPNAME
AND A.MARKET = B.MARKET
AND C.MENUNAME = A.MENUNAME
AND C.BARNAME = A.BARNAME
AND C.BARITEMNAME = A.ITEMNAME
AND C.CLASSID IN
(SELECT D.CLASSID FROM PSROLECLASS D
WHERE D.ROLENAME IN
(SELECT E.ROLENAME FROM PSROLEUSER E
WHERE E.ROLEUSER=))

SQL to find the process name from component name

SQL to find the process name from component name :

SELECT * FROM PS_PRCSDEFNPNL WHERE PNLGRPNAME =;

How to find out Patch Level of Your Current Application

The below query will fetch you the patches applied to your application -

SELECT
UPDATE_ID,
DESCR,
DESCRLONG,
DTTM_IMPORTED,
FIXOPRID,
APPLYOPRID,
PRODUCT_LINE FROM PS_MAINTENANCE_LOG
ORDER BY 1

Peoplesoft Hot Keys

We all probably know that “CTRL J” hot key gives us the system information. But did you know that there are a lot more available. But you do not have to trouble your brain to remember them, simply press navigate to a search or transaction page and invoke hot key “CTRL K” to get all the information. Below are the results from PeopleSoft “CTRL K”.

Accessing your application using the keyboard
Keyboard navigation is controlled by Hot keys and Access keys .

List of Hot Keys
Alt 1 — Executes different buttons depending on the page type
> Save button on the Toolbar in a page
> OK button on a secondary page
> Search or Add button on a Search or Lookup page
Alt 2 — Return to Search
Alt 3 — Next in List
Alt 4 — Previous in List
Alt 5 — Valid Lookup Values
Alt 6 — Related Links
Alt 7 — Insert Row in grid or scroll area
Alt 8 — Delete Row in grid or scroll area
Alt 0 — Refreshes the page by invoking the Refresh button on the Toolbar
Alt . — Next set of rows in grid or scroll area [e.g., Alt period]
Alt , — Previous set of rows in grid or scroll area [e.g., Alt comma]
Alt / — Find in grid or scroll area [e.g., Alt forward slash]
Alt ‘ — View All in grid or scroll area [e.g., Alt prime]
Alt \ — Toggle between Add and Update on the Search page [e.g., Alt backslash]
Ctrl J — System Information
Ctrl K — Keyboard Information
Ctrl Y — Toggle menu between collapse and expand.
Ctrl Tab — Toggles focus through the frame set
Enter — Invokes the following buttons where present: OK, Search, Lookup
Esc — Cancel

List of Access Keys
Alt 9 — Takes you to the Help line
Alt \ — Takes you to the Toolbar [e.g., Alt backslash Enter]
Ctrl Z — Takes you to the Search box of the Menu

Menu Access Keys
The Ctrl Z combination will focus your cursor onto the menuing system. From there, you can use your tab key (or shift-tab to reverse direction) to navigate through the menu hierarchy.

About Access keys and Hot keys
> An Access Key is an Alt key combination that moves focus to a specified field on the current page.
For example, Alt \ moves focus to first button on the Toolbar. Then pressing the Enter key would invoke that action. Or, you may use the Tab key to move you to the next Toolbar button.
> A Hot Key performs an immediate action. For example, when focus is in a field that has lookup processing, Alt 5 invokes the Lookup page without having to press the Enter key.

Hiding a field w scroll levels using People Code


Hello, I am trying to figure out how to hide a field in scroll level 2 in Component Level PeopleCode. I know I need to loop through to get the scroll level and invoke the code that way to hide the field.
This is what I have so far.
&Rs1 = GetRowset(Scroll.RHPRR022_CFG2);
If %Component = "RH_RHPRR022" Then
For &I = 1 To &Rs1.ActiveRowCount
&Row = &Rs1.GetRow(&I);
&Rec = &Row.GetRecord(Record.RHPRR022_CFG2);
If &Rs1.(&I).YourRecordName.RecordFieldName.Value > 0 Then
&Rs1.&Row.visible = False;

End-If;
End-For;
End-If;
The error message I get is:
'Rowset' does not support property or Method 'Value'.....

Resolving unique constraint violations in PeopleSoft processes

Anyone who has supported PeopleSoft applications long enough is all too familiar with the dreaded ORA-0805 error, a unique constraint violation. That error most frequently occurs when a process tries to insert a row into a table with the same key values as a row that is already there, although it can also happen on an update statement.

Fortunately, this is one problem that can be fixed rather rapidly if you're adept at trouble-shooting. I see it most often on the voucher posting process, which is an App Engine, so I'll approach the problem from that standpoint, but a lot of this holds true for SQRs, too, although it's a little trickier because data might not have been committed at any point during the process.

Let's assume that your process has failed. The log file should display the entire insert statement; if you've got AE trace enabled, you can also get it from the trace file. Copy that statement and run it in a SQL tool. I use TOAD, because I can have numerous windows open at a time and statements can be recalled simply by hitting F8. Run the statement in the SQL tool and if you're lucky, you'll get the same error. That's not always the case, though, if statements that preceded the insert were rolled back after the error occurred. In that case, you'll have to go to the trace file, find the last commit that occurred prior to the error, and run all of the statements up to and including the one that fails. Be sure to keep track of the statements that insert or update data, though, because you'll want to put things back the way they were after you've got the problem resolved and before you restart the AE process. If AE trace was not enabled, turn it on in the Process Scheduler config file and restart the failed process. It will fail again, but now you'll at least have a trace file. Be sure to disable trace, though, or pretty soon you'll have space problems on the Process Scheduler box.

Once you've replicated the error, it's a simple matter of finding the bad row and deleting it from what is usually an AE temp table. How do you find it? First, you need to determine the keys of the table into which the row is being inserted. Second, you need to analyze the insert statement to determine the source of the bad row. In the case of the voucher post process, it's usually VCHR_TEMP_LNx, where x is the instance number of the table being used. Third, you need to write a query to find the row in the source table that is a duplicate of a row in the target table. You do that by querying the two tables for rows with duplicate key values. Your SQL statement will end up looking something like this:

SELECT * FROM PS_VCHR_TEMP_LN11 A
WHERE EXISTS
(SELECT 'X' FROM PS_VCHR_ACCTG_LINE B
WHERE A.BUSINESS_UNIT=B.BUSINESS_UNIT
AND A.VOUCHER_ID=B.VOUCHER_ID
AND A.UNPOST_SEQ=B.UNPOST_SEQ
AND A.APPL_JRNL_ID=B.APPL_JRNL_ID
AND A.DST_ACCT_TYPE=B.DST_ACCT_TYPE
AND A.PYMNT_CNT=B.PYMNT_CNT
AND A.VOUCHER_LINE_NUM=B.VOUCHER_LINE_NUM
AND A.DISTRIB_LINE_NUM=B.DISTRIB_LINE_NUM
AND A.DST_ACCT_TYPE=B.DST_ACCT_TYPE
AND A.CF_BAL_LINE_NUM=B.CF_BAL_LINE_NUM
AND A.LEDGER=B.LEDGER)


If your query returns a row or rows, than you need to query the target table and make absolutely certain that the incoming row is a duplicate. Once that has been ascertained, you can safely delete the row from the temp table. Your work isn't done yet, though, because all you've done so far is solve a problem that occurred with this particular process. To prevent the problem from occurring in the future, you need to go back to the source record and update a flag there. In the case of voucher posting, that means updating VOUCHER.POST_STATUS_AP to a value of "P" (an incorrect value of "U" is what caused the problem to begin with). You've already written a query to find the offending row, so you can fix the problem at its source by adding a few lines to that query:

UPDATE PS_VOUCHER SET POST_STATUS_AP='P' WHERE POST_STATUS_AP='U' AND (BUSINESS_UNIT,VOUCHER_ID) IN
(SELECT BUSINESS_UNIT,VOUCHER_ID FROM PS_VCHR_TEMP_LN11 A
WHERE EXISTS
(SELECT 'X' FROM PS_VCHR_ACCTG_LINE B
WHERE A.BUSINESS_UNIT=B.BUSINESS_UNIT
AND A.VOUCHER_ID=B.VOUCHER_ID
AND A.UNPOST_SEQ=B.UNPOST_SEQ
AND A.APPL_JRNL_ID=B.APPL_JRNL_ID
AND A.DST_ACCT_TYPE=B.DST_ACCT_TYPE
AND A.PYMNT_CNT=B.PYMNT_CNT
AND A.VOUCHER_LINE_NUM=B.VOUCHER_LINE_NUM
AND A.DISTRIB_LINE_NUM=B.DISTRIB_LINE_NUM
AND A.DST_ACCT_TYPE=B.DST_ACCT_TYPE
AND A.CF_BAL_LINE_NUM=B.CF_BAL_LINE_NUM
AND A.LEDGER=B.LEDGER))


Once you've got the problem resolved at its source, you can delete the record from the temp table and restart the process, which should then complete successfully:

DELETE FROM PS_VCHR_TEMP_LN11 A
WHERE EXISTS
(SELECT 'X' FROM PS_VCHR_ACCTG_LINE B
WHERE A.BUSINESS_UNIT=B.BUSINESS_UNIT
AND A.VOUCHER_ID=B.VOUCHER_ID
AND A.UNPOST_SEQ=B.UNPOST_SEQ
AND A.APPL_JRNL_ID=B.APPL_JRNL_ID
AND A.DST_ACCT_TYPE=B.DST_ACCT_TYPE
AND A.PYMNT_CNT=B.PYMNT_CNT
AND A.VOUCHER_LINE_NUM=B.VOUCHER_LINE_NUM
AND A.DISTRIB_LINE_NUM=B.DISTRIB_LINE_NUM
AND A.DST_ACCT_TYPE=B.DST_ACCT_TYPE
AND A.CF_BAL_LINE_NUM=B.CF_BAL_LINE_NUM
AND A.LEDGER=B.LEDGER)


There are also occasions in which there is no duplicate row in the target table and your query does not return any rows. In that case, the problem is usually the result of a bad join between source tables that creates more than one row to insert. It could also be the result of a "GROUP BY" statement that summarizes data on the key fields and one or two non-key fields, and there are two or more rows with different non-key values but identical key values. In that case, you need to figure out why one is different and correct it. Don't try adding that field as a key, though- you might solve today's problems, but you'll just be creating headaches further down the road.

The One Concept Every PeopleSoft Professional Must Know

If I had to tell someone what the most important concept they need to understand as a PeopleSoft professional, I would quickly answer. It is the Component Processor and how it allocates Buffer space, how it places information in the buffer, and how to ensure that you maximize its use.

The PeopleSoft application is an extremely powerful and highly configurable product that runs many different applications. Every application that is accessed online through the PeopleSoft Internet Architecture is part of a component. When you navigate to a particular content reference or menu item to access a particular page, the Component Processor is what performs all of the activity including executing SQL, PeopleCode, loading the component/page, and filling the buffer with the necessary data that was requested. More importantly, all of these activities happen in a specific order.

It is this overall process that every PeopleSoft developer and analyst needs to understand thoroughly. If you understand how the component processor works and how it allocates buffer space, than debugging, performance tuning, designing, and developing your PeopleSoft applications will be simple for you. However, if you miss this concept or don̢۪t fully understand it, your design and development process and your online performance will be inadequate. In addition, it will become more difficult for you to debug your applications without understanding the component processor.

The Component Processor is the core engine of the PeopleSoft PIA and is responsible for the following:

Builds and displays the search page so the user can select a high level key to retrieve the data.

Performs search processing, where it will retrieve and save the search key values that were selected for the component.

Makes calls to the database to retrieve the metadata that is needed to build the component.

Builds the component, including all of its pages, fields, PeopleCode programs, and data, creating buffers for the component data.

Performs any additional processing for the component or the page.

Displays the component and waits for user action.


If you build PeopleSoft applications and write PeopleCode, than you must fully understand the component processor and how it allocated buffer space and places objects and data into the buffer. Every time you access a component, the component processor queries the database and moves relevant data from the database to the application server. The Component processor manages this data according to special rules. Therefore, your Component design has a crucial impact and it is extremely important to understand how the buffers are allocated and maintained by the component processor.

There is a lot more detail to discuss in regards to the component processor and the component buffer. Too much to place in a single blog/article. If you wish to read more about the Component Processor and the Component Buffer, download the eBook -

Enhance "processing" waring in PeopleSoft pages

Enhance "processing" waring in PeopleSoft pages
Two weeks ago, I was navigating through a new development we finished in our PeopleSoft application, and while I was waiting for a page to show me some results, I kept thinking "how awful is this processing warning, why we can̢۪t have some fancy Ajax-like waiting window?". Also I figured that one interesting performance issue we had was because some pages take a while to load and users get desperate and start clicking some other controls in the page. Sometimes those inappropriate clicks send a second or third request to the server and everything gets even slower.
So, after thinking for a while I got with the following simple solution, which will make your PeopleSoft application looks in a fancier way. There are 2 ways to implement this solution, page by page or enable the script through monkeygrease for the site.
Here it is the solution for the page by page option:
1. Add an HTML area to your page
2. Set its property to static HTML and copy the following code in it:

script language='JavaScript' type='text/javascript'
var wait=document.getElementsByTagName('div')[0];
wait.style.position='absolute';
wait.style.top=0;
wait.style.left=0;
wait.style.width='500%';
wait.style.height='500%';
wait.style.zindex='5000';
wait.style.backgroundColor='#FFF';
wait.style.filter="alpha(opacity=80)";
wait.innerHTML = 'img style="position:absolute;top:10%;left:10%;" src="
http://erpfinprod.banxico.org.mx:8050/erp8prod/BANXICO/azul2.gif" alt="Procesando..." title="Procesando..." /';
/script
3. Save the page
So as you could see this simple script will increase the usability of your site in seconds. After we implemented this solution, the client was so excited. Hope it helps!

How to avoid passwords expiring in PeopleSoft

One of the more often customer requirements regarding security is to implement password expiration. PeopleSoft provides this functionality using the Password Controls component under:
PeopleTools > Security > Password Configuration > Password Controls
This component provides the alternative to enable or disable password expiration controls for all users. Now, what happens if we want a certain user's password to never expire?
There are plenty of situations where we might want this to happen, for instance:
* The password for the user set in the Process Scheduler or Application Server configuration should not expire or otherwise the system may not work.
* Same happens with if a user is set as a Guest in a Web Profile.
* Also, you may want to disable password expiration for PTWEBSERVER, the user set by default to let the Web Server recover Web Profiles from PeopleSoft environment.
Unfortunately, PeopleSoft does not provide the ability of disabling password expiration for a given user. Good news are that it is quite easy to do by setting the last password change date to a future date using the following SQL sentence:

update PSOPRDEFN
set LASTPSWDCHANGE = '2050-01-01'
where OPRID in ('SOLICITANTE', 'PS', 'PTWEBSERVER')

Call App Engine from peoplecode

The PeopleCode below will show you how to call an Application Engine from PeopleCode. Some refer to this as “Real-Time Application Engine Processing.” For example, when a user save’s a page, you may want a specific App engine program to run. You can also execute this code in a field change event.
The following code calls the Application Engine program named YouAppEngProg, and passes it the necessary initialization values.

&MYRECORD = CreateRecord(RECORD.MY_INIT_VALUES);

&MYRECORD.FIELD1.Value = "123abc"; /* here you are setting the initial values needed by your application engine */

CallAppEngine("YouAppEngProg", &MYRECORD);
First, your state record should have fields like AE_APPLID and AE_SECTION.
Also check whether you have populated these fields properly before the
dynamic section call.
Before the call section , put a peoplecode and code something like that.

CE_ACT_COST_AET.AE_APPLID = "CE_ACTCR_CST";
CE_ACT_COST_AET.AE_SECTION = "Process";

Difference Between MsgGet, MessageBox, & MsgGetText PeopleCode Functions

Wondering why there are 3 different functions or ways to get text
from a message catalog? Check the comparison below and decide which one
best fits your needs.
MsgGet(message_set, message_num, default_msg_txt [, paramlist])
The MsgGet function
retrieves a message from the PeopleCode Message Catalog and substitutes
in the values of the parameters into the text message.
Example: &MsgText = MsgGet(30000, 2, "Message not found");

Run an SQR From a PeopleSoft Application Engine

Here is a good sample of how to launch an SQR from within PeopleCode. You can use the peoplecode function called “ScheduleProcess”. Here is the example:

&PROCESS_NAME = "SQRNAME";
&PROCESS_TYPE = "SQR Report"; (or "SQR Process")
&RUN_CNTL_ID = "YOUR_RUN_ID";
&RUN_CONTROL = ScheduleProcess(&PROCESS_TYPE, &PROCESS_NAME, "2", &RUN_CNTL_ID, &PRCS_INST);

If &RC != 0 /*"1" = client "2" = server*/
Winmessage("Error: Error Scheduling SQR Process, RC = " | &RUN_CONTROL);
End-If;

Vendor Pending Transactions

A quick function that will allow you to verify if a specific vendor has any pending transaction(s).

Function vendor_pnding_transactions();
&VENDOR = VENDOR_ID;
SQLExec("select 'X' from ps_voucher a, ps_pymnt_vchr_xref b where a.voucher_id = b.voucher_id and a.business_unit = b.business_unit and a.vendor_id = :1 and a.entry_status in ('P', 'R')and a.close_status = 'O' and b.pymnt_selct_status in ('N', 'D', 'R')", &VENDOR, &EXISTS);
If All(&EXISTS) Then
Error Messagebox(0,"",0,0,("Vendor has pending transaction(s).");
End-If;

Trace Application Engine Processes Using Process Definitions

In this post I will show you how to trace an application engine process using the Process Definitions without setting the trace in the Process Scheduler’s psprcs.cfg configuration file.
Navigate to the process definition of the application engine that you would like to trace (PeopleTools > Process Scheduler > Processes). Go to the Overrride Options tab, and from the Parameter List drop down select Append, and in the edit box next to it add the following line:

-TRACE 7 -TOOLSTRACEPC 4044

TRACE application engine using process definition

Who Modified this PeopleCode?

Nothing frustrates me more than developers modifying delivered PeopleSoft code without adding comments. It is easy to figure out who was the last person to touch a record by clicking on the Record Properties button in application designer. BUT it is not that easy when it comes to PeopleCode.

I have written the following SQL to help me identify the last person to modify a Record Field PeopleCode Event.

SELECT objectvalue1 record_name, objectvalue2 field_name,
objectvalue3 peoplecode_event, lastupddttm, lastupdoprid

A List of Pages a Peoplesoft Role Name can Access

A query that will take a PeopleSoft role name as an input and returns all pages that could be access by that role. The query will also indicate what kind of operations a user can perform on that page. Example, Add Update/Display and so forth.

SELECT b.menuname, b.barname, b.baritemname, d.pnlname, c.pageaccessdescr
FROM psroleclass a,
psauthitem b,
pspgeaccessdesc c,
pspnlgroup d,
psmenuitem e
WHERE a.classid = b.classid
AND d.pnlgrpname = e.pnlgrpname
AND b.menuname = e.menuname

Get Edit Tables Behind a Record Fields

A straight forward SQL to get edit tables behind field(s) for a specific record. The SQL execludes any edit tables that start with "%" as those are dynamic edit tables with values populated by PeopleCode at run time and thus will not be of a good use in this query.

SELECT R.FIELDNAME
, R.EDITTABLE
FROM PSRECFIELDDB R
, PSDBFIELD F
WHERE R.RECNAME = :RecordName
AND SUBSTR(R.EDITTABLE,1,1) <> '%'
AND R.EDITTABLE <> ' '
AND R.FIELDNAME = F.FIELDNAME
AND F.FLDNOTUSED = 0;

Dynamic Prompt Table Depending on a Drop Down Value

In this post I will attempt to explain how to dynamically assign a prompt table depending on a drop down value (see image below)
The table behind the grid is PORTAL_SECDYVW and as you can see from the image below, the PORTAL_AUTHNAME field has %EDITTABLE defined as a prompt table. The PORTAL_AUTHNAME is the "Name" column you see on the grid.
Now, we would want to assign table PSCLASSDEFN_SRC as prompt if the drop down value is Permission list and PSROLEDEFN_SRCH if the value is Role.
/*Record PeopleCode: PORTAL_SECDYVW.PORTAL_AUTHNAME.FieldChange*/
Evaluate PORTAL_SECDYVW.PORTAL_PERMTYPE2
When "P"
DERIVED.EDITTABLE = "PSCLASSDEFN_SRC";
PORTAL_SECDYVW.DESCR = PSCLASSDEFN.CLASSDEFNDESC.Value;
Break;

When "R"
DERIVED.EDITTABLE = "PSROLEDEFN_SRCH";
PORTAL_SECDYVW.DESCR = PSROLEDEFN.DESCR.Value;
Break;
When-Other

End-Evaluate;

How to search for navigation

A fairly common scenario. You have a component name (or even a page name) but you don’t know the navigation path to find it in the PIA.

The next alternative is using a piece of SQL to query the PRSMDEFN record to retrieve the path.

SELECT P3.PORTAL_LABEL L3
, P2.PORTAL_LABEL L2
, P1.PORTAL_LABEL L1
, P.PORTAL_LABEL L0
, P.*
FROM PSPRSMDEFN P
, PSPRSMDEFN P1
, PSPRSMDEFN P2
, PSPRSMDEFN P3
WHERE P.PORTAL_URI_SEG2 = ‘COMPONENT’
AND P.PORTAL_PRNTOBJNAME = P1.PORTAL_OBJNAME
AND P1.PORTAL_PRNTOBJNAME = P2.PORTAL_OBJNAME
AND P2.PORTAL_PRNTOBJNAME = P3.PORTAL_OBJNAME
AND P.PORTAL_NAME = P1.PORTAL_NAME
AND P1.PORTAL_NAME = P2.PORTAL_NAME
AND P2.PORTAL_NAME = P3.PORTAL_NAME

Bypass Component Search Page

We can bypass the component search page in different ways.

1. One way is to set the key values using peoplecode and use the peoplecode function SetSearchDialogBehavior. You can write the code in the SearchInit PeopleCode. Suppose Employee Id is the only key, then the code will look like,
EMPLID = %EmployeeId;
SetSearchDialogBehavior(0);
2. There is another method of using a record with no keys as the component search record. This will also bypass the search.
Based on the requirement you can use any of the above methods.

SQR code to send email

Here is the piece of code you can use to send email with attachments in SQR.

BEGIN-PROCEDURE sendmail
let $subject = 'Subject of the Email Here'
let $to_list = 'email@email.com'
let $ReportID = 'G:\PeopleSoft\Reports\Report_Name.pdf'
let $alias ='Attachment File Name Alias including the file extension'
let $enter = chr(10)chr(13)
let $body_txt = 'Hi,'$enter$enter'Please Find the Report attached with this email.'$enter$enter'Regards,'$enter 'Peoplesoft Application Support'$enter$enter'PS: We request you not to reply to this automated mail trigger.'

let $mail-cmd = 'F:\PSFT819\bin\server\winx86\psmail -TO"'$to_list'" -SUBJECT"'$subject'" -BODY"'$body_txt'" -FILE"' $ReportID '" -ALIAS"'$alias'"'
CALL SYSTEM USING $mail-cmd #Status
end-procedure

You would have to change the value of the variable $mail-cmd based on the path of your PS_HOME.

How to search for navigation

A fairly common scenario. You have a component name (or even a page name) but you don’t know the navigation path to find it in the PIA.

The next alternative is using a piece of SQL to query the PRSMDEFN record to retrieve the path.


SELECT P3.PORTAL_LABEL L3
, P2.PORTAL_LABEL L2
, P1.PORTAL_LABEL L1
, P.PORTAL_LABEL L0
, P.*
FROM PSPRSMDEFN P
, PSPRSMDEFN P1
, PSPRSMDEFN P2
, PSPRSMDEFN P3
WHERE P.PORTAL_URI_SEG2 = ‘COMPONENT’
AND P.PORTAL_PRNTOBJNAME = P1.PORTAL_OBJNAME
AND P1.PORTAL_PRNTOBJNAME = P2.PORTAL_OBJNAME
AND P2.PORTAL_PRNTOBJNAME = P3.PORTAL_OBJNAME
AND P.PORTAL_NAME = P1.PORTAL_NAME
AND P1.PORTAL_NAME = P2.PORTAL_NAME
AND P2.PORTAL_NAME = P3.PORTAL_NAME