PeopleSoft PeopleCode - An Introduction

Overview
If you are reading this, you are probably familiar with creating fields, records, pages, components, and menus. With these objects alone, you can create working development projects. Simple ones, yes, but these objects are all you need for the most basic level of development. PeopleCode comes into play for those development projects requiring a little more control. For example, you know how to define the default of a field within the record definition. This means that a value is always placed in this field whenever it is empty. But what if you needed to have a default placed in a field based on a condition of another field? You cannot do this within the record definition, but you can by using PeopleCode. The PeopleCode capability enables you to set and control a lot of parameters and objects. To fully understand the PeopleCode system and develop with it, you first need to learn about how it works. PeopleCode is a visual language similar to Microsoft Access or Visual Basic. In fact, in PeopleTools version 8.1, the coding syntax has been changed to reflect the Visual Basic (called VB from here on) standard. This makes the PeopleCode language easier to use and learn for developers who already know VB or the Visual Basic for Applications (VBA) programming language. The first detail to learn about PeopleCode is not the language itself but how the code works within the framework of PeopleSoft. PeopleCode can be placed in events on the field definition in each record. PeopleCode can also, since PeopleSoft 8.1, be placed into events on fields within pages and components. Each event is a place of action that launches PeopleCode when certain processes take place on a page. Using events is a difficult concept to grasp at first and you might have to spend extra time to fully understand this process.

Understanding How PeopleCode Events Work
PeopleSoft comes with 17 events for PeopleCode. Each event has a specific function and control for which it is designed.

PeopleSoft Panel Processor
PeopleCode does not just run whenever it feels like it. Each event has a specific time when it runs within the PeopleSoft process. The PeopleSoft process is controlled by the internal PeopleTools program, which is called the PeopleSoft Panel Processor . The PeopleSoft Panel Processor is the control program within PeopleSoft that is monitoring the user's actions. This

Classification: Employee Personal

The search page is created online with the keys and alternate keys displayed for entry. the main page. RowSelect The page is now filled with data from the search page. The Panel Processor then looks at the menu selection to find the component connected with it. But this is only the beginning of what PeopleCode can do. on all rows of data within the page. After all these events run. but the processor is not yet ready for user input. FieldDefault FieldFormula RowInit Each one of these events runs. finally. and if no errors have occurred. SearchInit After this code is complete. Of course. the first event of PeopleCode activates. more PeopleCode may activate. If the user changes a field (modifies or deletes) or adds data to an empty field. or Correction). each row of data that is to be loaded onto the page is validated by the code contained in the next event. Upon clicking OK in this search panel. depending on the action of the user. but before the user can enter any data. A series of events must launch for each row of data already loaded into the page. Event Order To best understand the PeopleSoft Panel Processor. as requested from the menu by the user. Classification: Employee Personal . SearchSave If no error messages are encountered within the code. Before the data is actually loaded. such as the prompt values as defined in the record definition for this field. First. Data. the following PeopleCode events run. as selected from the search page. the next event becomes active. The search record keys. and list information are gathered from the search record that has been assigned to the component. Update/Display. Now. the user is able to interact with the search page to search records and select the one they wish to process. in order. The component contains the search record for the action in which the user has asked the system to run.program controls when the PeopleCode will activate as well as a lot of other things based on the user's actions. alternate keys. the standard PeopleSoft record edits must pass first. Update/Display All. consider the process of starting and running a page to see when all the types of events are going to run. is now opened. the page is open for entry by the user. the user selects from the menu to run a specific page in a certain action (this action being Add. is then ready to be loaded into the page.

If the record definition you have is not used as a search record. providing examples of use including actual PeopleCode. Classification: Employee Personal . then code placed in here will never run. then the following PeopleCode events run for the row deleted and then for all the rows that are left within the level where the delete occurred. RowDelete FieldDefault FieldFormula The last step the user can take is to save the page. if the insert was done on level 2. you place the code in the correct event and therefore it runs at the appropriate time to perform the correct action. then the following PeopleCode events run for all the fields on the record that is within the level where the add was performed. You will also note that some events of PeopleCode are running a lot of the time.these are fully discussed in the "New to Version 8. changing data. Using PeopleCode Events This section teaches you about each event.1" section below. SaveEdit SavePreChg Workflow SavePostChg As you can see. Developers already familiar with PeopleCode will see the same events but there are some new things to learn as well . The PeopleCode events within the record definition on levels 0 or 1 are not activated. the PeopleCode events activate based on certain actions requested by the user. You need to understand the flow of the events so that when you have a function or code to add to the system. To better explain. as listed below. such as starting a page. or inserting new rows. then only the PeopleCode events on the record definitions contained within level 2 are activated. RowInsert FieldDefault FieldFormula If the user deletes a row of data on a level 1 through 3 scroll. You can place code in an incorrect event so that it runs too much²this will affect your system by slowing it down.FieldEdit FieldChange FieldDefault FieldForumla If the user inserts a new row of data on a page (only for occurs levels 1 through 3). SearchInit The code in the SearchInit event is needed only for records that will be used as search records. The save process runs another set of PeopleCode events.

this event is mostly used to set up counters or defaults from the operator preferences on the search panel. check_auto_num(BUSINESS_UNIT. you can place code here to do the validation of all the fields that must be filled in. &STATUS). check_status(BUSINESS_UNIT. 164. End-If. Classification: Employee Personal . For example: SetSearchEdit(BUSINESS_UNIT). End-If. If &AUTO_NUM = "N" And PO_ID = "NEXT" Then Error MsgGet(10200. This example turns on edits and system defaults for the Business Unit field in the search page. &AUTO_NUM). "Business Unit is a required field. For example: If None(BUSINESS_UNIT) Then Error MsgGet(9000. and is either Completed or Cancelled. 1."). SetSearchDefault(BUSINESS_UNIT). 3. 34. BUSINESS_UNIT). For example. This code does not cause any other PeopleCode category to activate. If &STATUS = "C" Or &STATUS = "X" Then Error MsgGet(10200."). If None(&AUTO_NUM) Then Error MsgGet(10000. Because you cannot specify the required fields on a search record (the record definition's required attribute is for use only on the regular pages). "The specified PO exists. it simply sets up the information in the page object to be used in that specific field. End-If. PO_ID.").". "This business unit is not set up for purchase order auto numbering. "%1 is not a Purchasing business unit.Code placed in this event is typically used to set up default values on the search page. SearchSave This code also applies to the search page and is typically used to validate the search page to make sure all the required fields are filled in.

based on some information. if you have a panel with a level 1 that has 15 data rows that load. For example.PO = "Y" Then DERIVED. this code activates for all rows of data that are loaded into the buffer. that you can set some values into special fields. Finally. then the data is validated for specific conditions. an error message is displayed and the search page is not closed. If they are filled in.TXN_CURRENCY_SRC = "P". This example shows a little more about the capability of this event of code.End-If. the RowInit event will run 16 times: once for the level 0 (header information) and then 15 times for each row of data on level 1. the third Classification: Employee Personal . RowInit Now you have arrived at events that are used more often in development projects.EDITTABLE13 = "ITM_PURCH_FS". So it is not how many rows are visible on the page. The code in the RowInit event runs every time a new row of data loads into a page. This section activates code for each level and each data row. but how many rows are loaded into the data buffer that determines how many times this PeopleCode category activates.VCHR_PO_STD Then If All(PO_ID) Then VCHR_PANELS_WRK. although complex for now basically checks that certain fields are filled in. If an error condition exists. The first example shows. End-If. End-If. Gray(SCHED_NBR). The code here. You need to understand that even though on the page you can see only five rows of data. The second example shows that you can also set or change the prompts used. Gray(LINE_NBR). If INSTALLATION. These examples show different ways to use the RowInit event that are typically done. Consider the following 3 examples: If %PanelGroup = PANELGROUP. Gray(BUSINESS_UNIT_RECV). End-If.

unhide. gray (display-only). fill in the current panel with data based on some criteria you have set. If the field is not filled in. FieldChange The FieldChange event occurs under two circumstances: once when a field is changed. This example checks the values in a couple of fields and then. you are usually looking for some action to take place: jump to another panel. If. For the field change event. and verifications. UnhideScroll(RECORD. Else check_schedules(). You can also use the FieldChange event when you have a button on a panel. you can access any field on the page as is shown in this example. the code does not execute unless there is a net change (changing the value of a field to it's original value is not a net change) and the user moves out of the field or saves the page. then the code runs a function to get the information and place it in this field. for example. For example: If None(ITM_SETID) Then ITM_SETID = GetSetId("BUSINESS_UNIT". This is what makes button actions so powerful² they can perform all sorts of actions. or ungray (not display-only) fields based on the initialization. runs a different function. "MASTER_ITEM_TBL". The code you place for a button can be just about anything you want. then you should set that value in the record definition. field defaults can be coded. "").PO_LINE).example shows how you can override the settings on the page to hide. End-If.ITM_STATUS = "A" Then If PRICE_DT_TYPE = "P" And QTY_TYPE = "L" Then check_line(). End-If. controls. UnGray(GOTO_LINE_DTLS). Example: If VENDOR_ITM_VW1. you can set the default based on a condition check of some other field or value using code from the FieldDefault event. Classification: Employee Personal . When you have a button and it is pressed. In the FieldChange event. by contrast. you have a hard default that is always to be used. here you would place the code that you wish to activate when the button is pressed. but rather. or run a process. Here you can do very complex validation upon the field. This example checks whether the ITM_SETID field is filled in. Otherwise. you are not limited to using only the field from which the code is launched. FieldDefault In this event. based on their settings. BUSINESS_UNIT. This event works only to set defaults into fields where the logic is too complex to use the record definition. SEL_LINE_FLG = "Y". and the other when a button is pressed.

So you place FieldEdit code in the first field (the color field) that states that if the value is blue.PO_LINE). on level 1 in the panel. If you have validations for which you do not want to leave the field before a specific criteria or process is complete. assume that you have two fields on a panel. FieldEdit In the FieldEdit event. RECORD. If you do validate against another field. Because the user has not entered a value in the next field. &WHERE. To better explain this potential loop problem. is un-hidden (now visible on the panel). the scroll's data buffer is filled with data based on a selection criterion. the first field).PO_LINE.PO_ID. then you need to place code in FieldEdit. so be careful not to validate against another field that you cannot change. The FieldEdit event is where you should place validation that you want to occur within the page field entry process. the value is initialized as 0. but if you understand the FieldEdit process. The second field can be set to a number that represents the brightness of the color (that is. and the data buffer is emptied for this scroll (scroll flush). but this event gives you the ability to validate using multiple fields and conditions.LINES_SAVED = "N". you apply most of the field editing to validate information within a field. In this event. you will see how this will get you into trouble. LINE_NBR_TO. RECORD. whereas blue can have a brightness between 3 and 9. then the value of the second field must be between 1 and 5. Finally. The PeopleSoft Panel Processor then runs the FieldEdit code for the field that states that if the value is red (which is what the user entered). The scroll. This is also the event to apply messages from PeopleCode that will not crash the panel. The first field can be set to a value of Red or Blue only. Now red can have a brightness only between 1 and 5.BUSINESS_UNIT. then the value of the next field must be between 1 and 5. PO_HDR. PO_HDR. LINE_NBR_FROM. This meets the logic requirement. to warn or stop the process within the page. If All(LINE_NBR_TO) Then &WHERE = &WHERE | " and LINE_NBR <= :4". Therefore. you will be locked in a loop and you won't be able to leave this field. the action is based only on the field you are in. &WHERE = "where BUSINESS_UNIT = :1 and PO_ID = :2 and LINE_NBR >= :3". this FieldEdit code fails and Classification: Employee Personal . True). ScrollSelect(1. This example is from a button which. End-If. You already can do one simple validation using the prompts on a field as defined within the record definition. is going to fill in data based on some criteria.PO_LINE. The user enters Red into the first field and tabs out to the next field. ScrollFlush(RECORD. when pressed.

but the user is still allowed to continue. FieldFormula This event is typically reserved for custom-built functions. &UNIT_PRC_TOL). You have already learned about the flow of how PeopleCode activates from the PeopleSoft Panel Processor and that the process FieldFormula runs for all sorts of actions.UNIT_PRC_TOL. If you fail the validation. check_item(). You have to understand the capabilities of the system and how the rules will be applied. If a problem occurs. or it could be moved to the SaveEdit event (about which you have not learned yet). In this example. End-if. but they carry different levels of actions. With a warning message. If None(PO_HDR. on the other hand. issue an error message to the user stating the problem and do not allow the process to continue until it is resolved. &LINE. The following example shows how to use the FieldEdit to do complex validation with an error message.VENDOR_ID. Each is a message. does not offer the user a choice. then the user can never leave this field. then no messages are displayed. the best solution is to change the location where the validation code is placed. &SCHED. Consider the following example: Function update_sched() &CHANGED_SCHED = "N". There are two types of messages: warning and error. INV_ITEM_ID). The validation code should be placed in the Field Edit event of the brightness field. A warning message tells the user that they might not want to continue or to use this value in the field. A warning means that the value in this field is not normal. the user must stop and fix the problem. PO_HDR. "Vendor %1 is not set up for item %2.requires the user to input a value that will not fail. This is a simple explanation. You should not place any code in this category except custom-built functions. but it shows how you have to be careful when using FieldEdit code for validation using other fields.VENDOR_ID) Then Error MsgGet(10200. and neither is allowed to have a 0 value. 76. You should make sure that all decisions to error or warn are well documented in the technical documentation for your modification. a message must be called. UpdateValue(LINE_NBR. If you pass the validation. Classification: Employee Personal . PO_LINE_SHIP. the user can decide to stop and fix the issue or move on and ignore the message. Because you've allowed only red and blue.". The way that PeopleSoft will pass or fail a validation is by issuing a message. An error message .

RowDelete This event is used to activate code when a delete is performed for a row of data rather than for only a single field. Data. The developer. The process to show the pass or fail of the event is just like in the FieldEdit event. but when you add a new record (level 0) or a new Classification: Employee Personal . This is an advanced technique that will not be covered in this book. you will need to think more in terms of functions when writing code. RowInsert In the RowInsert event.UpdateValue(LINE_NBR. is validated through the RowInit event. you can apply this restriction as you need to or you can even change the criteria as the page is being created. can control whether a row of data can be deleted by checking for orphaned records or other required validations. &SCHED. pass a message. 109. If VOUCHER. The code here checks a field for a specific status. Due to this added complexity. This enables you to write business logic into functions that many programs can call so that you do not have to write the logic over and over in multiple PeopleCode categories. End-Function.1 in that you now have the ability to place code in new places.PCT_UNIT_PRC_TOL. then the delete process has passed the validation. If a certain status is set. you apply code to inserts of new data rows. thereby having your logic in only one place. Instead of copying the code into all these different places and events. The purpose of this code is to prevent deletes unless a specific criterion has been met. End-If. &PCT_UNIT_PRC_TOL). Writing more functions that you place into this event will save you time and effort in the long run. If the status is not set. a warning reports an issue to the user. By having more places²pages and components²in which to load PeopleCode. when using this code even. &LINE."). This is important to PeopleCode 8. PO_LINE_SHIP. the code will allow the deletion by not issuing any error or warning message. then the code prevents the deletion by issuing an error message. This delete can be on any level. If you do not issue any messages. you can create the one function and then call it from the other places. when loaded into the page. If you failed the validation. A function can take in multiple values and even send back values to the calling program. RowSelect This event is used to filter data loaded into a scroll level. This example shows a function that performs some actions. Most developers who want to restrict rows of data create a view to use on the page with the restriction in the SQL where clause. you need to remember that you may require the same code in multiple places or categories. By using this event. This category can also use the warning and error message commands: An error always fails. "You cannot delete a voucher line if the voucher has been posted.POST_STATUS_AP = "P" Then Error MsgGet(7030.

A final use for the SaveEdit event occurs when the user does not tab through every field so the FieldEdit code never activates.VCHR_BALANCE_AMT. you can prevent or just warn on a save when the validation is incorrect.row of information (level 1 through 3). but you might want the user to do all the input they can and then do a check just prior to the save. If you still need this validation. there is no RowInit to activate because it was not initiated into the panel. you will have to add it to SaveEdit to be sure that the code does run. VCHR_PANELS_WRK.FULL_SET_FLG = "Y" Then MERCHANDISE_AMT = VCHR_PANELS_WRK. "You must enter either a quantity on Voucher Line %1 when distributing by quantity. The process done here can be just about anything you think of. This is used for the final validation of the record. End-If.". you can do a lot of this validation in the FieldEdit event. This code checks a work record field for a specific status and then updates some fields using information in some other work record fields. As with the other edit events. If DISTRIB_MTHD_FLG = "Q" And None(QTY_VCHR) Then Error MsgGet(7030. If VCHR_PANELS_WRK. Else If None(MERCHANDISE_AMT) Then Classification: Employee Personal . You might also have to validate multiple fields as a unit. SaveEdit In the SaveEdit event. then the user is unable to save the panel. then the user can stop the save process and edit the problem or they can continue. Of course.LN_BALANCE_AMT = MERCHANDISE_AMT. If you warn. VOUCHER_LINE_NUM). The RowInsert can and should perform the up-front validations that you would have placed in RowInit for new data rows being added. no message means that you have passed the SaveEdit validation. This is another reason for looking at code that you could place into functions so that you do not end up copying the same code into multiple categories. It is hard to do this within FieldEdit. Or you can delete the line. If you prevent. from graying (display only) and hiding fields to doing complex logic for recalculating a total. you place code that validates on a save. The process is the same regardless of whether you're using warning or error messages. you might need to place the same code in the RowInit and RowInsert categories. 49. Usually. Note As you can see. so you can place the overall validation in this event instead.

is used mostly to update hidden fields that need to be changed or corrected based on user input just prior to saving.DESCR. This event enables you to do other processes and update other rows of data. DESCR). then you will receive an error: This panel has been updated by another user . Many developers will place SQLexec function calls in this category. You do not do updates within SaveEdit. CurrentRowNumber(). preventing the save of this panel. This is your last chance to make changes. This error message is telling you that something happened to the data between the time you retrieved the data and the time you saved it. assuming that the process will complete. &BUFFER_ROW. 49. since you do not want to update the header level field with every row insert or field change on the level 1. This enables you to put code in one place. It is not until you save the record that the database is updated. "You must enter either a merchandise amount on Voucher Line %1 when distributing by amount.where within the component. VOUCHER_LINE_NUM). The SavePreChange event. here is where you would make the code work. In your page. The PeopleSoft Panel Processor then tries to commit the rest of your changes and sees that someone else (yes. you can place code to change or update the data tables prior to the save being committed to the database. If any field of the record is on the component. You must be sure that the record you are going to update or insert is not any. the processor sees this as another user) has made a change. but these changes are loaded only into your panel buffers. You have to be aware that using SQL direct statements can lead you into trouble.Error MsgGet(7030. Once the save is started. So be extra careful when using SQL calls within the events. Someone else grabbed the information and changed it prior to your change committing it to the database. SavePreChange In the SavePreChange event. SQLexec function calls enable you to run a SQL statement directly so that you can update a related field that is not within the page. as this is only supposed to be looking for errors. Classification: Employee Personal . The problem occurred because of your SQLexec²it ran and made an update to the database. even though the SQLexec came from your process. an error message is issued. Or you can delete the line. this event occurs.". If you need to total a field in level 1 and place the information in a header record (level 0). End-If. so your panel is not allowed to save. the PeopleCode runs and does all its SaveEdit checks and then just prior to saving the information to the database. DISTRIB_LINE. For &BUFFER_ROW = 1 To &CURRENT_ROW UpdateValue(VOUCHER_ID. and it runs doing the work just prior to the save. End-If This code checks some values in the fields and then. you are making changes. if certain conditions exist.

VENDOR_PERSISTENCE = "O" Then &SETID = GetSetId("BUSINESS_UNIT". Workflow is beyond the scope of this book. You can see in this example how you are updating the vendor based on an action in the PO system. They are mentioned here so that you know about all the new places to locate PeopleCode. ""). VENDOR_ID) End-If. advanced tools that are not covered in this book. This is also where a lot of SQL execs are written and performed to update other necessary fields. you add code that you want to activate after the rows of data have been saved to the database. You need to put in specific code here that updates the workflow records and processes. the status is set to inactive so that you do not use them again. Note Application Engine and Business Components are specialized. but what happens when PeopleCode is encountered within the new areas such as pages and components? Well. This code loops through all the rows of a level 1 panel and updates a value in a lower-level scroll (level 2). &SETID. If %Mode = "A" and VENDOR.End-For. The process of PeopleCode running on the system has already been mentioned.1 With the release of PeopleTools 8. then the vendor status must be set back to inactive so that no further POs can be used. but no further mention will be made. Workflow The workflow event is for the specific use of workflow. After you use them on a PO . SavePostChange In the SavePostChange event. the Classification: Employee Personal . and Business Components. You are now able to place code not only within the record definition. BUSINESS_UNIT. This process is used on vendors that are set to one time use only. These new capabilities are explained in this section. New for Version 8. This code example shows that if the page is in Add mode and the vendor is set to a special persistence. SQLExec("Update ps_vendor set VENDOR_STATUS = 'I' where setid = :1 and vendor_id = :2". Application Engine. Code placed here could be line totals and other calculated fields. This means that you have more places to enter code to meet your development needs. PeopleSoft has made some major changes to the PeopleCode system. component.1. but you can also place code in the page. "VENDOR".

Within the component definition. when you are in the other panel. This is the only event available for the page. but now you have some new areas to run within each event. there was still a need to place code so that it runs only when a specific page is running. You would have had to retrieve a value for the page you are in to then see whether you wish to run the code. You now have access to many more events that run only when in a specific component. Now. you have access to the following events: ‡ SearchInit ‡ SearchSave ‡ RowInit Classification: Employee Personal . For example. the code will run. Now with the new capability in PeopleSoft 8. because if you include one field from a record. all the PeopleCode of the record loads into the page and runs. You might have a page that is usually used for this record and you hide this field until a specific action is done. Now you are only adding a new level of complexity to RowInit: first. This requirement to have code run when within a specific page is used all the time. The event here is a new name called Activate. you do not need to write code to retrieve the page name and then check whether you need to run this code. and finally the RowInit code in the component area runs. but this field does not exist on the page because it is for a whole different process.same overall order still applies. then you should place code in that page. then all the page code RowInit activates. when a scroll level has data loaded into it. Although it is a new name. Let's explore each new section of PeopleCode within the page and component. So the overall flow of the code running through the events stays the same. the code entered here is associated with the page itself.1. This way. PeopleCode in Pages Why would you place code in a page versus a record definition? If you have code for a RowInittype function that you wish to have run only when you are accessing a specific page. you can place code directly into the page so that it will activate only when the page is accessed. all the RowInit code runs from the record definition. reviewing why they would be used and what events are available. the RowInit code runs for each row of data. PeopleSoft tools developers created a new place to load PeopleCode within the component to solve this problem. PeopleCode in Components Because you could place code only in the Activate event within the panel. you can swap it for RowInit.

‡ RowSelect ‡ RowInsert ‡ RowDelete ‡ SaveEdit ‡ SavePreChange ‡ SavePostChange ‡ FieldChange ‡ FieldDefault ‡ PreBuild ‡ PostBuild ‡ SavePreChange ‡ SavePostChange ‡ Workflow ‡ FieldEdit As you can see from the list. Having this new capability enables you to enter code into the component so that the code will run only when this component is active. finally. you enter all the PeopleCode into the record and field definition area. This makes the PeopleCode easier to write and much more efficient. You can enter code against the component itself. records within the component. but now you can enter the code into the component. The order of the events and how they activate is not changed within the component. it gets a little more complex. even when using only one field on a page. Usually. PreBuild Classification: Employee Personal . Using the component PeopleCode events. Instead of having to write code to check what component you are in for every piece of PeopleCode you have in the record definition. Remembering the rule requiring all the PeopleCode of a record to be loaded. you can place just the right amount of code within the component PeopleCode events. let's see how you can save time and effort by using this new capability. fields within the component and. you have all the events²including two new ones: PreBuild and PostBuild.

Classification: Employee Personal . This is usually used to hide. unhide. or to set certain values in the component. or to set certain values in the component. This event runs right after the RowSelect event within the flow of PeopleCode. or ungray fields. PeopleCode within the component record gives you an opportunity to set variables that can be used later by PeopleCode located in other events. or ungray fields.The PreBuild event is specific to the component. PreBuild can also be used to validate data in the search page just as is done in the SearchSave event. unhide. this code runs after the component is built. This is typically used to hide. this code runs prior to the component being built. gray. The event can be thought of just like the RowInit event as the data is already loaded into the component. PostBuild The PostBuild event is specific to the component. This even runs right after the RowInit even in the PeopleCode flow. gray.