PeopleCode Developer's Guide
PeopleCode Developer's Guide
PeopleCode Developer's Guide
February 2013
PeopleTools 8.53: PeopleCode Developers Guide CDSKU pt853pbr0 Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Trademark Notice
Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners.
Warranty Disclaimer
The information contained herein is subject to change without notice and is not warranted to be error-free. If you find any errors, please report them to us in writing.
Contents
Preface..........................................................................................................................................................xi Understanding the PeopleSoft Online Help and PeopleBooks............................................................. xi PeopleSoft Hosted Documentation................................................................................................. xi Locally Installed Help..................................................................................................................... xi Downloadable PeopleBook PDF Files............................................................................................xi Common Help Documentation........................................................................................................xi Typographical Conventions............................................................................................................xii ISO Country and Currency Codes................................................................................................xiii Region and Industry Identifiers.................................................................................................... xiii Access to Oracle Support..............................................................................................................xiv Documentation Accessibility.........................................................................................................xiv Using and Managing the PeopleSoft Online Help.............................................................................. xiv PeopleTools Related Links.................................................................................................................. xiv Contact Us.............................................................................................................................................xv Follow Us.............................................................................................................................................. xv Chapter 1: Getting Started with PeopleCode......................................................................................... 17 Getting Started with PeopleCode......................................................................................................... 17 PeopleCode Overview...........................................................................................................................17 Creating PeopleCode Programs............................................................................................................ 18 Chapter 2: Understanding the PeopleCode Language...........................................................................21 Understanding the PeopleCode Language............................................................................................21 PeopleCode Language Structure...........................................................................................................21 Data Types.............................................................................................................................................21 Conventional Data Types............................................................................................................... 22 Object Data Types.......................................................................................................................... 23 Comments..............................................................................................................................................24 Statements..............................................................................................................................................25 Separators........................................................................................................................................26 Assignment Statements...................................................................................................................26 Language Constructs...................................................................................................................... 26 Branching Statements..................................................................................................................... 27 Conditional Loops.......................................................................................................................... 29 Functions............................................................................................................................................... 30 Supported Functions....................................................................................................................... 30 Function Definitions....................................................................................................................... 31 Function Declarations.....................................................................................................................31 Function Calls.................................................................................................................................31 Function Return Values.................................................................................................................. 32 Function Naming Conflicts............................................................................................................ 32 Expressions............................................................................................................................................33 Expression Fundamentals............................................................................................................... 33 Constants.........................................................................................................................................33 Functions as Expressions............................................................................................................... 35 System Variables.............................................................................................................................35 Metastrings......................................................................................................................................35 Record Field References................................................................................................................ 36 Definition Name References.......................................................................................................... 37
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
iii
Contents
PeopleCode Reserved Words......................................................................................................... 38 Variables................................................................................................................................................ 39 Supported Variable Types...............................................................................................................40 User-Defined Variables...................................................................................................................40 User-Defined Variable Declaration and Scope.............................................................................. 40 Variable Declaration....................................................................................................................... 41 User-Defined Variable Initialization.............................................................................................. 42 Restrictions on Variable Use.......................................................................................................... 43 Scope of Local Variables............................................................................................................... 43 Duration of Local Variables........................................................................................................... 44 Variables and Functions................................................................................................................. 45 Recursive Functions....................................................................................................................... 45 State of Shared Objects Using PeopleSoft Pure Internet Architecture.......................................... 45 Operators............................................................................................................................................... 46 Math Operators............................................................................................................................... 47 Operations on Dates and Times..................................................................................................... 47 String Concatenation...................................................................................................................... 48 @ Operator..................................................................................................................................... 48 Comparison Operators.................................................................................................................... 48 Boolean Operators.......................................................................................................................... 49 Chapter 3: Understanding Objects and Classes in PeopleCode........................................................... 51 Understanding Objects and Classes in PeopleCode............................................................................. 51 Classes and Objects.............................................................................................................................. 51 Classes.............................................................................................................................................51 Objects............................................................................................................................................ 52 Object Instantiation.........................................................................................................................52 Creating and Using Objects..................................................................................................................52 Instantiating Objects....................................................................................................................... 52 Changing Properties....................................................................................................................... 53 Invoking Methods...........................................................................................................................54 Copying Objects............................................................................................................................. 55 Assigning Objects................................................................................................................................. 55 Passing Objects..................................................................................................................................... 56 Chapter 4: Referencing Data in the Component Buffer........................................................................59 Referencing Data in the Component Buffer.........................................................................................59 Understanding Component Buffer Structure and Contents.................................................................. 59 Component Buffer Contents...........................................................................................................59 Rowsets and Scroll Areas.............................................................................................................. 61 Record Fields and the Component Buffer..................................................................................... 61 Specifying Data with Contextual References.......................................................................................62 Understanding Current Context......................................................................................................62 Using Contextual Row References................................................................................................ 64 Using Contextual Buffer Field References.................................................................................... 65 Specifying Data with References Using Scroll Path Syntax and Dot Notation................................... 67 Understanding Scroll Paths............................................................................................................ 67 Structuring Scroll Path Syntax in PeopleTools 7.5........................................................................67 Referencing Scroll Levels, Rows, and Buffer Fields.....................................................................70 Chapter 5: Accessing the Data Buffer..................................................................................................... 77 Accessing the Data Buffer....................................................................................................................77 Understanding Data Buffer Access...................................................................................................... 77 Data Buffer Access.........................................................................................................................77
iv
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Contents
Access Classes................................................................................................................................77 Data Buffer Model and Data Access Classes................................................................................ 78 Understanding Data Buffer Classes Examples.....................................................................................78 Employee Checklist Page Structure............................................................................................... 79 Object Creation Examples..............................................................................................................82 Data Buffer Hierarchy Examples................................................................................................... 89 Rowset Examples........................................................................................................................... 92 Hidden Work Scroll Example........................................................................................................ 93 Understanding Current Context............................................................................................................ 95 Accessing Secondary Component Buffer Data.................................................................................... 96 Instantiating Rowsets Using Non-Component Buffer Data................................................................. 96 Chapter 6: PeopleCode and the Component Processor.........................................................................99 PeopleCode and the Component Processor..........................................................................................99 Understanding the Component Processor.............................................................................................99 Events Outside the Component Processor Flow.................................................................................. 99 PeopleCode Program Triggers............................................................................................................ 100 Understanding PeopleCode Program Triggers.............................................................................100 Accessing PeopleCode Programs.................................................................................................101 Associating Execution Order of Events and PeopleCode............................................................102 Component Processor Behavior..........................................................................................................106 Component Processor Behavior from Page Start to Page Display.............................................. 106 Component Behavior Following User Actions in the Component.............................................. 107 Processing Sequences..........................................................................................................................109 Flow Charts...................................................................................................................................109 Default Processing........................................................................................................................110 Search Processing in Update Modes............................................................................................113 Search Processing in Add Modes................................................................................................ 116 Component Build Processing in Update Modes.......................................................................... 118 Row Select Processing................................................................................................................. 119 Component Build Processing in Add Modes...............................................................................122 Field Modification........................................................................................................................ 123 Row Insert Processing..................................................................................................................125 Row Delete Processing.................................................................................................................127 Buttons.......................................................................................................................................... 129 Prompts......................................................................................................................................... 129 Pop-Up Menu Display..................................................................................................................130 Selected Item Processing..............................................................................................................131 Save Processing............................................................................................................................ 131 PeopleSoft Pure Internet Architecture Processing Considerations.....................................................133 Deferred Processing Mode..................................................................................................................134 PeopleCode Events..............................................................................................................................137 Activate Event.............................................................................................................................. 138 FieldChange Event....................................................................................................................... 138 FieldDefault Event........................................................................................................................139 FieldEdit Event............................................................................................................................. 139 FieldFormula Event...................................................................................................................... 140 ItemSelected Event....................................................................................................................... 140 PostBuild Event............................................................................................................................ 140 PreBuild Event..............................................................................................................................141 PrePopup Event............................................................................................................................ 141 RowDelete Event..........................................................................................................................141
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Contents
RowInit Event...............................................................................................................................142 RowInsert Event........................................................................................................................... 143 RowSelect Event...........................................................................................................................145 SaveEdit Event............................................................................................................................. 145 SavePostChange Event................................................................................................................. 146 SavePreChange Event...................................................................................................................146 SearchInit Event........................................................................................................................... 147 SearchSave Event......................................................................................................................... 148 Workflow Event............................................................................................................................148 PeopleCode Execution in Pages with Multiple Scroll Areas............................................................. 149 Chapter 7: PeopleCode and PeopleSoft Pure Internet Architecture..................................................151 PeopleCode and PeopleSoft Pure Internet Architecture.....................................................................151 Considerations Using PeopleCode in PeopleSoft Pure Internet Architecture.................................... 151 Using PeopleCode with PeopleSoft Pure Internet Architecture.........................................................152 Using Internet Scripts...................................................................................................................152 Using the Field Object Style Property.........................................................................................152 Using the HTML Area................................................................................................................. 153 Using HTML Definitions and the GetHTMLText Function........................................................ 154 Using HTML Definitions and the GetJavaScriptURL Method................................................... 155 Using PeopleCode to Populate Key Fields in Search Dialog Boxes........................................... 155 Calling DLL Functions on the Application Server............................................................................ 156 Sample Cross-Platform External Test Function...........................................................................156 Updating the Installation and PSOPTIONS Tables............................................................................158 Chapter 8: Using Methods and Built-In Functions..............................................................................159 Using Methods and Built-In Functions.............................................................................................. 159 Understanding Restrictions on Method and Function Use.................................................................159 Think-Time Functions.................................................................................................................. 160 WinMessage and MessageBox Functions....................................................................................161 Program Execution with Fields Not in the Data Buffer.............................................................. 163 Errors and Warnings.....................................................................................................................163 DoSave Function.......................................................................................................................... 163 Record Class Database Methods..................................................................................................163 SQL Class Methods and Functions..............................................................................................164 Component Interface Restricted Functions.................................................................................. 164 SearchInit PeopleCode Function Restrictions..............................................................................165 CallAppEngine Function.............................................................................................................. 165 ReturnToServer Function..............................................................................................................165 GetPage Function......................................................................................................................... 166 GetGrid and GetAnalyticGrid Functions..................................................................................... 166 Publish Method.............................................................................................................................166 SyncRequest Method....................................................................................................................166 Implementing Modal Transfers...........................................................................................................166 Understanding Modal Transfers................................................................................................... 166 Implementing Modal Transfers.................................................................................................... 168 Implementing the Multi-Row Insert Feature...................................................................................... 169 Using the ImageReference Field........................................................................................................ 170 Inserting Rows Using PeopleCode..................................................................................................... 171 Using OLE Functions......................................................................................................................... 171 Understanding OLE Functions.....................................................................................................172 Using the Object Data Type.........................................................................................................172 Sharing a Single Object Instance................................................................................................. 172
vi
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Contents
Using the Exec and WinExec Functions......................................................................................173 Using the Select and SelectNew Methods......................................................................................... 173 Understanding the Select and SelectNew Methods..................................................................... 173 Using the Select Method..............................................................................................................174 Using Standalone Rowsets..................................................................................................................176 Understanding Standalone Rowsets............................................................................................. 176 Using the Fill Method.................................................................................................................. 177 Using the CopyTo Method...........................................................................................................177 Adding Child Rowsets................................................................................................................. 178 Using Standalone Rowsets to Write a File.................................................................................. 179 Using Standalone Rowsets to Read a File...................................................................................180 Using Errors and Warnings.................................................................................................................181 Using Error and Warning Syntax.................................................................................................182 Using Errors and Warnings in Edit Events..................................................................................182 Using Errors and Warnings in RowSelect Events....................................................................... 183 Using Errors and Warnings in RowDelete Events.......................................................................183 Using Errors and Warnings in Other Events............................................................................... 183 Using the RemoteCall Feature............................................................................................................183 Understanding RemoteCall Components..................................................................................... 184 Deciding Between RemoteCall and PeopleSoft Process Scheduler.............................................186 Modifying PeopleSoft Process Scheduler Programs to Run with RemoteCall............................187 Chapter 9: Using HTML Trees and the GenerateTree Function........................................................189 Using HTML Trees and the GenerateTree Function..........................................................................189 Using the GenerateTree Function....................................................................................................... 189 Understanding HTML Trees........................................................................................................ 189 Building HTML Tree Pages.........................................................................................................190 Using HTML Tree Rowset Records............................................................................................ 191 Using HTML Tree Actions (Events)........................................................................................... 194 Initializing HTML Trees.............................................................................................................. 194 Processing Events Passed from a Tree to an Application............................................................198 Adding Mouse-Over Ability to HTML Trees..............................................................................202 Adding Visual Selection Node Indicators....................................................................................203 Specifying Override Images.........................................................................................................203 Chapter 10: Working With File Attachments...................................................................................... 205 Working With File Attachments......................................................................................................... 205 Understanding the File Attachment Functions................................................................................... 205 PeopleCode Built-in File Attachment Functions......................................................................... 205 Understanding the File Attachment Architecture........................................................................ 208 Understanding File Attachment Storage Locations..................................................................... 212 Understanding URL Strings Versus URL Objects.......................................................................213 Developing Applications that Use File Attachment Functions.......................................................... 214 Application Development Process Overview.............................................................................. 214 Delivered Record Definitions.......................................................................................................215 Managing Entries in File Reference Tables.................................................................................218 Using the PeopleTools Test Utilities Page...................................................................................219 Application Development Considerations.......................................................................................... 220 File Name Considerations............................................................................................................ 220 Restrictions on Invoking Functions in Certain PeopleCode Events............................................ 221 Converting File Names for Files Uploaded by PutAttachment................................................... 221 Considerations When Using CopyAttachments........................................................................... 222 Application Deployment and System Configuration Considerations.................................................222
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
vii
Contents
File Attachment Functions in an Environment with Multiple Application Server Domains........222 Configuring the Web Server to Support Additional MIME Types.............................................. 223 Restricting the File Types That Can Be Uploaded or Downloaded.............................................224 Setting Up Virus Scanning...........................................................................................................224 Considerations When Attaching Text Files................................................................................. 227 File Attachment Chunk Size........................................................................................................ 227 Using the Copy File Attachments Page.......................................................................................228 Debugging File Attachment Problems................................................................................................228 Enabling Tracing on the Web Server or Application Server....................................................... 228 Problems with Transfers to and from FTP Sites......................................................................... 229 Attachments with non-ASCII File Names................................................................................... 230 Problems Uploading Files............................................................................................................ 231 Passing Error Messages to the End User.....................................................................................231 Chapter 11: Accessing PeopleCode and Events....................................................................................233 Accessing PeopleCode and Events.....................................................................................................233 Understanding PeopleCode Programs and Events............................................................................. 233 Understanding Automatic Backup of PeopleCode............................................................................. 234 Accessing PeopleCode in Application Designer................................................................................ 234 Accessing Record Field PeopleCode..................................................................................................237 Understanding Record Field PeopleCode.................................................................................... 237 Accessing Record Field PeopleCode from a Record Definition................................................. 238 Accessing Record Field PeopleCode from a Page Definition..................................................... 238 Accessing Component Record Field PeopleCode.............................................................................. 240 Understanding Component Record Field PeopleCode.................................................................240 Accessing Component Record Field PeopleCode........................................................................240 Accessing Component Record PeopleCode....................................................................................... 241 Understanding Component Record PeopleCode..........................................................................242 Accessing Component Record PeopleCode.................................................................................242 Accessing Component PeopleCode.................................................................................................... 242 Understanding Component PeopleCode.......................................................................................243 Accessing Component PeopleCode..............................................................................................243 Accessing Page PeopleCode............................................................................................................... 243 Understanding Page PeopleCode................................................................................................. 243 Accessing Page PeopleCode........................................................................................................ 243 Accessing Menu Item PeopleCode.....................................................................................................244 Understanding Menu Item PeopleCode....................................................................................... 244 Defining PeopleCode Pop-Up Menu Items................................................................................. 244 Accessing Menu Item PeopleCode.............................................................................................. 245 Copying PeopleCode with a Parent Definition.................................................................................. 245 Upgrading PeopleCode Programs.......................................................................................................245 Chapter 12: Using the PeopleCode Editor............................................................................................247 Using the PeopleCode Editor............................................................................................................. 247 Navigating Between PeopleCode Programs....................................................................................... 247 Understanding the PeopleCode Editor Window.......................................................................... 248 Navigating Between Programs Associated With a Definition and Its Children...........................249 Navigating Between Programs Associated With Events............................................................. 249 Using the PeopleCode Editor............................................................................................................. 250 Understanding the PeopleCode Editor......................................................................................... 251 Writing and Editing PeopleCode..................................................................................................251 Find and Replace Dialogs............................................................................................................ 252 Go To Dialog................................................................................................................................253
viii
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Contents
Validate Syntax Utility................................................................................................................. 253 Formatting Code Automatically...................................................................................................254 Using Drag-and-Drop Editing...................................................................................................... 254 Accessing PeopleCode External Functions..................................................................................254 Accessing PeopleCode Application Packages and Application Classes......................................255 Accessing Definitions and Associated PeopleCode.....................................................................257 Accessing Help............................................................................................................................. 257 Setting Up Help............................................................................................................................258 Changing Colors in the PeopleCode Editor.................................................................................258 Selecting a Font for the PeopleCode Editor................................................................................ 258 Changing Word Wrap in the PeopleCode Editor.........................................................................259 Using the PeopleCode Event Properties...................................................................................... 261 Generating PeopleCode Using Drag-and-Drop.................................................................................. 261 Generating References to Definitions.......................................................................................... 261 Generating PeopleCode for a Business Interlink......................................................................... 262 Generating PeopleCode for a Component Interface.................................................................... 262 Generating PeopleCode for a File Layout................................................................................... 263 Chapter 13: Using the SQL Editor........................................................................................................ 265 Using the SQL Editor......................................................................................................................... 265 Understanding the SQL Editor Window............................................................................................ 265 Accessing SQL Definition Properties.................................................................................................266 Accessing the SQL Editor.................................................................................................................. 267 Creating SQL Definitions.............................................................................................................267 Creating Dynamic View or SQL View Records.......................................................................... 269 Accessing the SQL Editor from Application Engine Programs.................................................. 270 Using the SQL Editor......................................................................................................................... 271 Chapter 14: Creating Application Packages and Classes....................................................................273 Creating Application Packages and Classes.......................................................................................273 Understanding Application Packages................................................................................................. 273 Creating Application Packages........................................................................................................... 274 Understanding Package Names.................................................................................................... 274 Creating Application Package Definitions...................................................................................275 Using the Application Package Editor............................................................................................... 276 Editing Application Classes................................................................................................................277 Chapter 15: Debugging Your Application.............................................................................................279 Debugging Your Application.............................................................................................................. 279 Understanding the PeopleCode Debugger..........................................................................................279 Accessing the PeopleCode Debugger.................................................................................................279 Using PeopleCode Debugger Features............................................................................................... 281 Visible Current Line of Execution............................................................................................... 282 Visible Breakpoints.......................................................................................................................282 Hover Inspect................................................................................................................................283 Single Debugger........................................................................................................................... 283 Variables Panes............................................................................................................................. 284 Call Stack Pane............................................................................................................................ 287 Setting Values for Variables and Properties.................................................................................289 General Debugging Tips.............................................................................................................. 290 Using PeopleCode Debugger Options................................................................................................ 292 Setting Up the Debugging Environment............................................................................................ 296 Compiling All PeopleCode Programs at Once...................................................................................296 Setting PeopleCode Debugger Log Options.......................................................................................297
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
ix
Contents
Interpreting the PeopleCode Debugger Log File............................................................................... 299 Log File Contents......................................................................................................................... 300 Other Items in the Log File......................................................................................................... 300 Using Application Logging................................................................................................................ 301 Setting the Application Log Fence in the Configuration File......................................................302 Using the Log Fence with PeopleSoft Analytic Calculation Engine........................................... 302 Using the Find In Feature...................................................................................................................302 Finding References to Application Packages and Classes................................................................. 306 Prerequisites.................................................................................................................................. 306 Finding Definition References..................................................................................................... 307 Using Cross-Reference Reports..........................................................................................................308 Chapter 16: Improving Your PeopleCode.............................................................................................311 Improving Your PeopleCode.............................................................................................................. 311 Reducing Trips to the Server..............................................................................................................311 Counting Server Trips.................................................................................................................. 312 Using Deferred Mode...................................................................................................................312 Hiding and Disabling Fields........................................................................................................ 313 Using the Refresh Button.............................................................................................................313 Updating Totals and Balances......................................................................................................313 Using Warning Messages............................................................................................................. 314 Using the Fastest Algorithm........................................................................................................ 314 Using Better Coding Techniques for Improved Performance............................................................ 314 Running a SQL Trace.................................................................................................................. 315 Optimizing SQL........................................................................................................................... 315 Using the GetNextNumberWithGaps Function............................................................................315 Consolidating PeopleCode Programs........................................................................................... 315 Moving PeopleCode to a Component or Page Definition........................................................... 315 Sending Messages in the SavePostChange Event........................................................................316 Using Metadata and the RowsetCache Class...............................................................................316 Setting MaxCacheMemory...........................................................................................................316 Writing More Efficient Code..............................................................................................................316 Writing More Efficient Code Examples...................................................................................... 320 Preventing SQL Injection................................................................................................................... 323 Appendix A: PeopleCode Editor Short Cut Keys................................................................................ 325 PeopleCode Editor Short Cut Keys.................................................................................................... 325 Short Cut Keys in the PeopleCode Editor......................................................................................... 325
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Preface
Understanding the PeopleSoft Online Help and PeopleBooks
The PeopleSoft Online Help is a website that enables you to view all help content for PeopleSoft Applications and PeopleTools. The help provides standard navigation and full-text searching, as well as context-sensitive online help for PeopleSoft users.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
xi
Preface
Most product lines provide a set of application fundamentals help topics that discuss essential information about the setup and design of your system. This information applies to many or all applications in the PeopleSoft product line. Whether you are implementing a single application, some combination of applications within the product line, or the entire product line, you should be familiar with the contents of the appropriate application fundamentals help. They provide the starting points for fundamental implementation tasks. In addition, the PeopleTools: PeopleSoft Applications User's Guide introduces you to the various elements of the PeopleSoft Pure Internet Architecture. It also explains how to use the navigational hierarchy, components, and pages to perform basic functions as you navigate through the system. While your application or implementation may differ, the topics in this users guide provide general information about using PeopleSoft Applications.
Typographical Conventions
The following table describes the typographical conventions that are used in the online help.
Typographical Convention Bold Description Highlights PeopleCode function names, business function names, event names, system function names, method names, language constructs, and PeopleCode reserved words that must be included literally in the function call. Highlights field values, emphasis, and PeopleSoft or other book-length publication titles. In PeopleCode syntax, italic items are placeholders for arguments that your program must supply. Italics also highlight references to words or letters, as in the following example: Enter the letter O. Key+Key Indicates a key combination action. For example, a plus sign (+) between keys means that you must hold down the first key while you press the second key. For Alt+W, hold down the Alt key while you press the W key. Highlights a PeopleCode program or other code example. Indicate that the preceding item or series can be repeated any number of times in PeopleCode syntax. Indicate a choice between two options in PeopleCode syntax. Options are separated by a pipe ( | ). Indicate optional items in PeopleCode syntax.
Italics
xii
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Preface
Description When placed before a parameter in PeopleCode syntax, an ampersand indicates that the parameter is an already instantiated object. Ampersands also precede all PeopleCode variables.
This continuation character has been inserted at the end of a line of code that has been wrapped at the page margin. The code should be viewed or entered as a single, continuous line of code without the continuation character.
Region Identifiers
Regions are identified by the region name. The following region identifiers may appear in the PeopleSoft Online Help: Asia Pacific Europe Latin America North America
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
xiii
Preface
Industry Identifiers
Industries are identified by the industry name or by an abbreviation for that industry. The following industry identifiers may appear in the PeopleSoft Online Help: USF (U.S. Federal) E&G (Education and Government)
Documentation Accessibility
For information about Oracle's commitment to accessibility, visit the Oracle Accessibility Program website at http://www.oracle.com/pls/topic/lookup?ctx=acc&id=docacc.
xiv
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Preface
Contact Us
Send us your suggestions Please include release numbers for the PeopleTools and applications that you are using.
Follow Us
Get the latest PeopleSoft updates on Facebook. Follow PeopleSoft on Twitter@PeopleSoft_Info.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
xv
Chapter 1
PeopleCode Overview
This section provides an overview of the product documentation available for the PeopleCode language, which is split into three documents: PeopleTools: PeopleCode API Reference This document contains information about certain application classes delivered with Oracle's PeopleTools, as well as specifics about each class's methods and properties. PeopleTools: PeopleCode Developer's Guide This document, the document that you are currently reading, provides conceptual information on the PeopleCode language, how PeopleCode interacts with the component buffer, how to develop PeopleCode programs, and a number of other specialized topics. PeopleTools: PeopleCode Language Reference This document contains information about PeopleCode built-in functions, meta-SQL, system variables, and meta-HTML. The initial topics in this document, PeopleTools: PeopleCode Developer's Guide, provide conceptual information on the PeopleCode language, including: PeopleCode resembles other programming languages. However, many aspects are unique to the language and the PeopleTools environment. To learn more about the language, see PeopleCode Language Structure. PeopleCode is an object-oriented language. To learn about objects and how they're used in PeopleCode, see Classes and Objects. The component buffer is the area in memory that stores data for the currently active component. Which fields are loaded into the component buffer, as well as how to access them, is covered in Understanding Component Buffer Structure and Contents.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
17
Chapter 1
The system uses a data buffer as well as the component buffer. The data buffer is used to store data added from sources other than the component, such as from a Application Engine program, an application message, and so on. For information about this buffer, see Understanding Data Buffer Access. All PeopleCode is associated with a definition and an event. The events run in a particular order from the Component Processor. To learn more about the Component Processor and the standard event set, see Understanding the Component Processor. You should take into account certain considerations when creating applications to be used in the PeopleSoft Pure Internet Architecture. These include how to make your code more efficient when running on the internet, as well as considerations when using specific definitions. See PeopleSoft Pure Internet Architecture Processing Considerations. There are restrictions on using some of the functions and methods in the PeopleCode language, as well as considerations for others, like using standalone rowsets and the OLE functions. These are covered in Functions. PeopleCode has a tremendous amount of specialized functionality, such as: Using the GenerateTree function to create a tree in your application. Viewing, adding, and deleting files.
See Using the GenerateTree Function. See Understanding the File Attachment Functions .
See Understanding the SQL Editor Window. See Creating Application Packages.
18 Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 1
After you have created your program, you must run it. Often, that involves fixing any errors that you find. The PeopleCode debugger is an integrated part of PeopleSoft Application Designer, and it has many useful tools for determining where code errors are occurring. All the functionality is described in Debugging your Application. See Understanding the PeopleCode Debugger. After your PeopleCode program is running, you may want to either improve its performance or the user experience. Techniques for doing this are discussed in Improving Your PeopleCode. SeeUnderstanding PeopleCode Programs and Events .
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
19
Chapter 2
Data Types
Conventional data types include number, date, string. Use them for basic computing. Object data types instantiate objects from PeopleTools classes. The appropriate use of each data type is demonstrated where the documentation discusses PeopleCode that uses that data type. Declare variables before you use them. This section discusses:
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
21
Chapter 2
Related Links
Variables
22
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 2
Operations (other than division) are done using integer arithmetic if the operands are both integers and the destination is an integer, even if the variable is declared as the Number type. The destination is considered to be an integer if one of the following is True: The destination is an assignment to an integer variable or parameter. The destination is an array subscript. The destination is the right-hand operand of a comparison and the left-hand operand is an integer. The destination is a when-expression part of an evaluate statement, and the expression evaluated at the start of the evaluate statement is an integer. The destination is a for-loop initial, limit, or step expression and the control variable of the for-loop is an integer.
Division (the / operator) is never performed using integer arithmetic. It is always performed using the floating-decimal-point arithmetic, even if the result variable is declared as an Integer type. Follow these recommendations for assigning types to numbers: Use Number for most application data values. Use Integer when you are counting items, such as rows in a rowset. Use Float only when you are tuning the code for performance (after it is already working). In addition, you should only use the Float type when you are certain that the resulting loss of precision will not affect the application and that the increase in the speed of the computation makes a difference to the transaction. In general, few applications should use the Float type.
PeopleCode includes these display data types: AnalyticGrid Chart Gantt Grid
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
23
Chapter 2
PeopleCode includes these internet script data types: Cookie Request Response
PeopleCode includes numerous miscellaneous data typesfor example, Array, Chart, Exception, File, Message, XmlDoc, among many others.
All other ApiObject data type objects (such as all the PortalRegistry classes) must be declared as Local.
Comments
Use comments to explain, preferably in language comprehensible to anyone reading your program, what your code does. Comments also enable you to differentiate between PeopleCode delivered with the product and PeopleCode that you add or change. This differentiation helps in your analysis for debugging and upgrades. Note: Use comments to place a unique identifier marking any changes or enhancements that you have made to a PeopleSoft application. This marker makes it possible for you to search for all the changes you have made, which is particularly helpful when you are upgrading a database. You insert comments into PeopleCode in these ways: You can surround comments with /* at the beginning and */ at the end. You can use a REM (remark) statement for commenting.
24
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 2
Put a semicolon at the end of a REM comment. If you do not, everything up to the end of the next statement is treated as part of the comment. You can surround commented text with <* at the start and *> at the end. Use this type of comment to enclose one set of comments within another set. You generally use this when you are testing code and want to comment out a section that already contains comments. Warning! In application classes, you will see the use of /+ +/ style comments. Do not use these in your PeopleCode. These annotations are generated by the compiler. If you use them, they are removed by the system the next time you validate, compile, or save your PeopleCode. They are used to provide signature information on application class methods and properties, and they are regenerated each time the compiler compiles your application class PeopleCode. Instead, use the standard commenting mechanisms listed above. Note: Commented text cannot exceed a maximum of 16383 characters. The following code sample shows comment formatting:
<* this program is no longer valid commenting out entire thing REM This is an example of commenting PeopleCode; /* ----- Logic for Compensation Change ----- */ /* Recalculate compensation change for next row. Next row is based on prior value of EFFDT. */ calc_next_compchg(&OLDDT, EFFSEQ, 0); /* Recalculate compensation change for current row and next row. Next row is based on new value of EFFDT. */ calc_comp_change(EFFDT, EFFSEQ, COMP_FREQUENCY, COMPRATE, CHANGE_AMT, CHANGE_PCT); calc_next_compchg(EFFDT, EFFSEQ, 0); *>
Note: All text between the <* and *> comment markers is scanned. If you have mismatched quotation marks, invalid assignments, and so on, you may receive an error when using this type of comment.
Statements
A statement can be a declaration, an assignment, a program construct (such as a Break statement or a conditional loop), or a subroutine call. This section discusses: Separators. Assignment statements. Language constructs.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
25
Chapter 2
Separators
PeopleCode statements are generally terminated with a semicolon. The PeopleCode language accepts semicolons even if they are not required, such as after the last statement completed within an If statement. This functionality enables you to consistently add semicolons after each statement. Extra spaces are ignored. They are removed by the PeopleCode Editor when you save the code.
Assignment Statements
The assignment statement is the most basic type of statement in PeopleCode. It consists of an equal sign with a variable name on the left and an expression on the right:
variableName = expression;
The expression on the right is evaluated, and the result is placed in the variable named on the left. Depending on the data types involved, the assignment is passed either by value or by reference.
Assignment by Value
In most types of assignments, the result of the right-hand expression is assigned to the variable as a newly created value, in the variable's own allocated memory area. Subsequent changes to the value of that variable have no effect on any other data.
Assignment by Reference
When both sides of an assignment statement are object variables, the result of the assignment is not to create a copy of the object in a unique memory location and assign it to the variable. Instead, the variable points to the object's memory location. Additional variables can point to the same object location. For example, both &AN and &AN2 are arrays of type Number. Assigning &AN2 to &AN does not assign a copy of &AN2 to &AN. Both array objects point to the same information in memory.
Local array of number &AN, &AN2; Local number &NUM; &AN = CreateArray(100, 200, 300); &AN2 = &AN; &NUM = &AN[1];
In the code example, &AN2 and &AN point to the same object: an array of three numbers. If you were to change the value of &AN[2] to 500 and then reference the value of &AN2[2], you would get 500, not 300. On the other hand, assigning &NUM to the first element in &AN (100) is not an object assignment. It is an assignment by value. If you changed &AN[1] to 500, then &NUM remains 200. Note: In PeopleCode, the equal sign can function as either an assignment operator or a comparison operator, depending on context.
Language Constructs
PeopleCode language constructs include:
26 Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 2
Branching structures: If and Evaluate. Loops and conditional loops: For, Repeat, and While. Break, Continue, and Exit statements loop control and terminating programs. The Return statement for returning from functions. Variable and function declaration statements: Global, Local, and Component for variables, and Declare Function for functions. The Function statement for defining functions. Class definition statements. Try, Catch, and Throw statements for error handling.
Functions as Subroutines
PeopleCode, like C, does not have subroutines as we generally refer to them. PeopleCode subroutines are the subset of PeopleCode functions only that are defined to return no value or to return a value optionally. Calling a subroutine is the same as calling a function with no return value:
function_name([param_list]);
Related Links
Branching Statements Functions "Function (PeopleTools 8.53: PeopleCode Language Reference)" "Declare Function (PeopleTools 8.53: PeopleCode Language Reference)" "CreateException (PeopleTools 8.53: PeopleCode Language Reference)" "try (PeopleTools 8.53: PeopleCode Language Reference)"
Branching Statements
Branching statements control program flow based on evaluation of conditional expressions.
This statement evaluates the Boolean expression condition. If condition is True, then the If statement executes the statements in statement_list_1. If condition is False, then the program executes the statements in the Else clause; if there is no Else clause, the program continues to the next statement.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
27
Chapter 2
Evaluate Statement
Use the Evaluate statement to check multiple conditions. Its syntax is:
Evaluate left_termWhen [relop_1] right_term_1 [statement_list] . . . When [relop_n] right_term_n [statement_list] [When-other [statement_list]] End-evaluate;
The Evaluate statement takes an expression, left_term, and compares it to compatible expressions (right_term) using the relational operators (relop) in a sequence of When clauses. If relop is omitted, then the equal sign is assumed. If the result of the comparison is True, the program executes the statements in the When clause, and then moves on to evaluate the comparison in the following When clause. The program executes the statements in all of the When clauses for which the comparison evaluates to True. If none of the When comparisons evaluates to True, the program executes the statement in the When-other clause, if one is provided. For example, the following Evaluate statement executes only the first When clause. &USE_FREQUENCY in the following example can only have one of three string values:
evaluate &USE_FREQUENCY when = "never" PROD_USE_FREQ = 0; when = "sometimes" PROD_USE_FREQ = 1; when = "frequently" PROD_USE_FREQ = 2; when-other Error "Unexpected value assigned to &USE_FREQUENCY." end-evaluate;
To end the Evaluate statement after the execution of a When clause, you can add a Break statement at the end of the clause, as in the following example:
evaluate &USE_FREQUENCY when = "never" PROD_USE_FREQ = 0; Break; when = "sometimes" PROD_USE_FREQ = 1; Break; when = "frequently" PROD_USE_FREQ = 2; Break; when-other Error "Unexpected value assigned to &USE_FREQUENCY." end-evaluate;
In rare cases, you may want to make it possible for more than one When clause to execute, as shown in the following example:
evaluate &PURCHASE_AMT when >= 100000 BASE_DISCOUNT = "Y"; when >= 250000 SPECIAL_SERVICES = "Y"; when >= 1000000 MUST_GROVEL = "Y"; end-evaluate;
28
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 2
For Statement
The For statement repeats a sequence of statements a specified number of times. Its syntax is:
For count = expression1 to expression2 [Step i];statement_listEnd-for;
The For statement initializes the value of count to expression1, and then increments count by i each time after it executes the statements in statement_list. The program continues in this loop until count is equal to expression2. If the Step clause is omitted, then i equals one. To count backwards from a higher value to a lower value, use a negative value for i. You can exit a For loop using a Break statement. The following example demonstrates the For statement:
&MAX = 10; for &COUNT = 1 to &MAX; WinMessage("Executing statement list, count = " | &COUNT); end-for;
Related Links
"If (PeopleTools 8.53: PeopleCode Language Reference)" "Evaluate (PeopleTools 8.53: PeopleCode Language Reference)" "For (PeopleTools 8.53: PeopleCode Language Reference)"
Conditional Loops
Conditional loops, Repeat and While, repeat a sequence of statements, evaluating a conditional expression each time through the loop. The loop terminates when the condition evaluates to True. You can exit from a conditional loop using a Break statement. If the Break statement is in a loop embedded in another loop, the break applies only to the inside loop.
Repeat Statement
The syntax of the Repeat statement is:
Repeat statement_listUntil logical_expression;
The Repeat statement executes the statements in statement_list once, and then evaluates logical_expression. If logical_expression is False, the sequence of statements is repeated until logical_expression is True.
While Statement
The syntax of the While statement is:
While logical_expressionstatement_listEnd-while;
The While statement evaluates logical_expression before executing the statements in statement_list. It continues to repeat the sequence of statements until logical_expression evaluates to False.
Related Links
"Repeat (PeopleTools 8.53: PeopleCode Language Reference)" "While (PeopleTools 8.53: PeopleCode Language Reference)"
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
29
Chapter 2
Functions
This section discusses: Supported functions. Function definitions. Function declarations. Function calls. Function return values. Function naming conflicts.
Related Links
Classes and Objects Functions "Function (PeopleTools 8.53: PeopleCode Language Reference)" "Declare Function (PeopleTools 8.53: PeopleCode Language Reference)"
Supported Functions
PeopleCode supports the following types of functions: Built-in: The standard set of PeopleCode functions. These can be called without being declared. Internal: Functions that are defined (using the Function statement) within the PeopleCode program in which they are called. External PeopleCode: PeopleCode functions defined outside the calling program. These are generally contained in record definitions that serve as function libraries. External non-PeopleCode: Functions stored in external (C-callable) libraries.
Note: PeopleSoft Analytic Calculation Engine provides its own set of built-in functions. See "Understanding the Analytic Model Definition Creation Process (PeopleTools 8.53: Analytic Calculation Engine)". In addition, PeopleCode supports methods. The main differences between a built-in function and a method are: A built-in function, in your code, is on a line by itself, and it does not (generally) have any dependencies. You do not have to instantiate an object before you can use the function. A method can only be executed by an object (using dot notation).
30
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 2
Function Definitions
PeopleCode functions can be defined in any PeopleCode program. Function definitions must be placed at the top of the program, along with any variable and external function declarations. The syntax for a PeopleCode function definition is as follows:
Function name[(paramlist)] [Returns data_type] [statements] End-function
By convention, PeopleCode programs are stored in records whose names begin in FUNCLIB_, and they are always attached to the FieldFormula event. Note: Application classes can provide an alternative, and sometimes cleaner, mechanism for separating functionality than the functions stored in function libraries.
Related Links
"Function (PeopleTools 8.53: PeopleCode Language Reference)" "Application Classes General Structure (PeopleTools 8.53: PeopleCode API Reference)"
Function Declarations
If you call an external function from a PeopleCode program, you must declare the function at the top of the program. The syntax of the function declaration varies, depending on whether the external function is written in PeopleCode or compiled in a dynamic link library. The following is an example of a function declaration of a function that is in another FUNCLIB record definition:
Declare Function UpdatePSLOCK PeopleCode FUNCLIB_NODES.MSGNODENAME FieldFormula;
Related Links
Function Calls
Functions are called with this syntax:
function_name([param_list])
The optional parameter list (param_list) is a list of expressions, separated by commas, that the function expects you to supply. If a parameter is listed in the function definition, then it is required when the function is called. You can check the values of parameters that get passed to functions at runtime in the Parameter window of the PeopleCode debugger.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
31
Chapter 2
If the return value is required, then the function must be called as an expression, for example:
&RESULT = Product(&RAISE_PERCENT, .01, EMPL_SALARY);
If the function has an optional return value, it can be called as a subroutine. If the function has no return value, it must be called as a subroutine:
WinMessage(64, "I can't do that, " | &OPER_NICKNAME | ".");
Parameters are always passed to internal and external PeopleCode functions by reference. If the function is supposed to change the data the caller passes, you must also pass in a variable. Built-in function parameters can be passed by reference or by value, depending on the function. External C function parameters can be passed by value or by reference, depending on the declaration and type.
Related Links
The following example checks the return value and returns a message saying whether it succeeded:
if DeleteRow(RECORD.BUS_EXPENSE_PER, &L1_ROW, RECORD.BUS_EXPENSE_DTL, &L2_ROW) then WinMessage("Row deleted."); else WinMessage("Sorry -- couldn't delete that row."); end-if;
32
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 2
who maintain your code, because if they miss the warning message in the Validate tab, they might assume the built-in function is being called when it is not.
Expressions
This section discusses: Expression fundamentals. Constants. Functions as expressions. System variables. Metastrings. Record field references. Definition name references. PeopleCode reserved words.
Related Links
Variables
Expression Fundamentals
Expressions evaluate to values of PeopleCode data types. A simple PeopleCode expression can consist of a constant, a temporary variable, a system variable, a record field reference, or a function call. Simple expressions can be modified by unary operators (such as a negative sign or logical NOT), or combined into compound expressions using binary operators (such a plus sign or logical AND). Definition name references evaluate to strings equal to the name of a PeopleTools definition, such as a record or page. They enable you to refer to definitions without using string literals, which are difficult to maintain. Metastrings (also called meta-SQL) are special expressions used within SQL string literals. At runtime, the metastrings expand into the appropriate SQL for the current database platform.
Constants
PeopleCode supports numeric, string, and Boolean constants, as well as user-defined constants. It also supports the constant Null, which indicates an object reference that does not refer to a valid object. Note: You can express Date, DateTime, and Time values by converting from String and Number constants using the Date, Date3, DateTime6, DateTimeValue, DateValue, Time3, TimePart, and the TimeValue functions. You can also format a DateTime value as text using FormatDateTime.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
33
Chapter 2
Numeric Constants
Numeric constants can be any decimal number. Some examples are: 7 0.8725 -172.0036
String Constants
String constants can be delimited by using either single (') or double (") quotation marks. If a quotation mark occurs as part of a string, the string can be surrounded by the other delimiter type. As an alternative, you can include the delimiter twice. Some examples are: "This is a string constant." 'So is this.' 'She said, "This is a string constant."' "She said, ""This is a string constant."""
Use the following code to include a literal quotation mark as part of your string:
&cDblQuote = '"'; /* singlequote doublequote singlequote */
The following also produces a string with two double quotation marks in it:
&cDblQuote = """"; /* dquote dquote dquote dquote */
You can also directly embed the doubled double quotation mark in strings, such as:
&sImage = Char(10) | '<IMG SRC="%IMAGE(' | &pImageName | ')"';
Strings must be contained on a single line. If you need to create a multi-line string, you must use concatenation to connect the lines to be a single sting. For example, one method to do this is:
&string = "Line 1" | Char(10) | "Line 2" | Char(10);
Boolean Constants
Boolean constants represent a truth value. The two possible values are True and False.
Null Constant
Null constants represent an object reference value that does not refer to a valid object. This means that calling a method on the object or trying to get or set a property of it fails. The Null constant is just the keyword Null.
User-Defined Constants
You can define constants at the start of a PeopleCode program. Then you can use the declared constant anywhere that the corresponding value would be allowed. Constants can be defined as numbers, strings, or Boolean values. User-defined constants can only be declared as Local.
34
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 2
Related Links
"PeopleCode Built-in Functions and Language Constructs (PeopleTools 8.53: PeopleCode Language Reference)"
Functions as Expressions
You can use any function that returns a value as an expression. The function can be used on the right side of an assignment statement, passed as a parameter to another function, or combined with other expressions to form a compound expression.
Related Links
Functions
System Variables
System variables are preceded by a percent (%) symbol whenever they appear in a program. Use these variables to get the current date and time, or to get information about the user, the current language, the current record, page, or component, and more.
Related Links
"Understanding System Variables (PeopleTools 8.53: PeopleCode Language Reference)" "System Variables Reference (PeopleTools 8.53: PeopleCode Language Reference)"
Metastrings
Metastrings are special SQL expressions. The metastrings, also called meta-SQL, are preceded with a percent (%) symbol, and can be included directly in string literals. They expand at runtime into an appropriate substring for the current database platform. Metastrings are used in or with: SQLExec. Scroll buffer functions (ScrollSelect and its relatives). PeopleSoft Application Designer to construct dynamic views. Some rowset object methods (Select, SelectNew, Fill, and so on). SQL objects. Application Engine. Some record class methods (Insert, Update, and so on).
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
35
Chapter 2
COBOL.
Related Links
"SQLExec (PeopleTools 8.53: PeopleCode Language Reference)" "ScrollSelect (PeopleTools 8.53: PeopleCode Language Reference)" "Understanding Meta-SQL (PeopleTools 8.53: PeopleCode Language Reference)"
You must supply the recordname only if the record field and your PeopleCode program are in different record definitions. For example, suppose that in a database for veterinarians you have two records, PET_OWNER and PET. A program in the record definition PET_OWNER must refer to the PET_BREED record field in the PET record definition as PET.PET_BREED. However, a program in the PET record definition can refer to this same record field more directly as PET_BREED. If the program is in the PET_BREED record field itself, it can refer to this record field using the caret (^) symbol. The PeopleCode Editor replaces the caret symbol with the actual record field name. You can also use object dot notation to refer to record fields, for example:
&FIELD = GetRecord(RECORD.PET_OWNER).GetField(FIELD.PET_BREED);
36
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 2
In these cases, the definition name reference evaluates to a string literal. Using the definition name reference instead of a string literal enables PeopleTools to maintain the code if the definition name changes. If you use the definition name reference, and the name of the definition changes, the change automatically ripples through the code, so you do not have to change it or maintain it. In the PeopleCode Editor, if you place your cursor over any definition name reference and right-click, you can select View Definition to open the definition. In addition, for most definitions, if you specify a definition that was not created in PeopleSoft Application Designer, you receive an error message when you try to save your program.
The second solution is a commonly used workaround in cases where the definition name contains illegal characters. If you use this notation, the definition name reference is not treated as a string literal: PeopleTools maintains the reference the same way as it does other definition name references. Note: If your definition name begins with a number, you must enclose the name in quotation marks when you use it in a definition name reference. For example, CompIntfc."1_DISCPLIN_ACTN".
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
37
Chapter 2
PANEL
38
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 2
Common Usage Used with the deprecated DoModalPanelGroup function. Note: Use the DoModalComponent function and the COMPONENT reserved word instead.
Used with transfers and modal transfers, as well as generating URLs. Used in functions and methods to designate a record. Used in functions and methods to designate a rowset.
The name of the scroll area in the page. This name is always equal to the primary record of the scroll. Used with SQL definitions. Used with style sheets. Used with file attachment functions.
Variables
This section discusses. Supported variable types. User-defined variables. User-defined variable declaration and scope. Variable declaration. User-defined variable initialization. Restrictions on variable use. Scope of local variables. Duration of local variables. Variables and functions. Recursive functions. State of shared objects using PeopleSoft Pure Internet Architecture.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
39
Chapter 2
Related Links
System Variables
System variables
User-Defined Variables
A user-defined variable can hold the contents of a record field for program code clarity. For example, you may give a variable a more descriptive name than a record field, based on the context of the program. If the record field is from another record, you may assign it to a temporary variable rather than always using the record field reference. This makes it easier to enter the program, and can also make the program easier to read. Also, if you find yourself calling the same function repeatedly to get a value, you may be able to avoid some processing by calling the function once and placing the result in a variable.
40
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 2
Variable declarations are usually placed above the main body of a PeopleCode program (along with function declarations and definitions). The exception is the Local declaration, which you can use within a function or the main section of a program. You can declare variables as any of the PeopleCode data types. If a variable is declared as an Any data type, or if a variable is not declared, PeopleTools uses an appropriate data type based on context. Note: Declare a variable as an explicit data type unless the variable will hold a value of an unknown data type. Global variables can be accessed from different components and applications, including an Application Engine program. A global variable must be declared, however, in each PeopleCode program where its used. Use global variables rarely, because they are difficult to maintain. Global variables are not available to a portal or applications on separate databases. Component variables remain defined and keep their values while any page in the component in which they are defined remains active. Similar to a global variable, a component variable must be declared in each PeopleCode program where it is used. Component variables act the same as global variables when an Application Engine program is called from a page (using CallAppEngine). Component variables remain defined after a TransferPage, DoModal, or DoModalComponent function. However, variables declared as Component do not remain defined after using the Transfer function, whether you are transferring within the same component or not. Local variables declared at the top of a PeopleCode program (or within the main, that is, non-function, part of a program) remain in scope for the life of that PeopleCode program. Local variables declared within a function are valid to the end of the function and not beyond. You can check the values of Local, Global, and Component variables at runtime in the different variable windows of the PeopleCode debugger. Local variables declared within a function appear in the Function Parameters window.
Variable Declaration
Declare variables before you use them. If you do not declare a variable, it is automatically declared with the scope Local and the data type Any. You receive a warning message in the Validation tab of the
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
41
Chapter 2
PeopleSoft Application Designer output window for every variable that is not declared when you save the PeopleCode program, as shown in the following example: Image: Validation tab with auto-declared variables The following image shows the validation tab with auto-declared variables.
If you declared all the variables, you can use these values to ensure you do not have misspellings. For example, if you declared a variable as &END_DATE and then accidentally spell it as &EDN_DATE, the new variable appears on the Validate tab when you save the program. Another reason to declare variables is for the design-time checking. If you declare a variable of one data type and then assign to it a value of a different type, the PeopleCode Editor catches that assignment as a design-time error when you try to save the program. With an undeclared variable, the assignment error does not appear until runtime. The following example produces a design-time error when you try to save the program:
Local Field &DATE; &DATE = GetRecord(RECORD.DERIVED_HR);
In addition, if you declare variables, the Find Object Reference feature finds embedded definitions. For example, suppose you wanted to find all occurrences of the field DEPT_ID. If you have not declared &MyRecord as a record, Find Object References does not find the following reference of the field DEPT_ID:
&MyRecord.DEPT_ID.Visible = False;
This method is available only for variables with the scope of Local. Though you can declare more than one variable on a single line, you can only initialize one variable on a line. The following code creates a syntax error when you try to save the program:
Local Number &N1, &N2 = 5;
You cannot declare a variable, then initialize it in a second declaration statement. The following produces a duplicate declaration error when you try to save the program:
Global Number &N1; ...
42
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 2
/* Duplicate definition. */
If you do not initialize variables, either when you declare them or before you use them, strings are initialized as Null strings, dates and times as Null, and numbers as zero.
The following ApiObject data type objects can be declared as Global: Session PSMessages collection PSMessage All tree classes (trees, tree structures, nodes, levels, and so on) Query classes
All other ApiObject data type objects (such as all the PortalRegistry classes) must be declared as Local.
See Recursive Functions. A program-local variable can be affected by statements anywhere in the program. For example, suppose RECORD_A.FIELD_A.FieldFormula has two functions, FUNC_1 and FUNC_2, and both modify a local variable named &TEMP. They could affect each other, as they both use the same variable name in the same PeopleCode program. If, however, FUNC_3 is defined in RECORD_B_FIELD_B.FieldFormula and makes reference to &TEMP, it is not the same &TEMP as in RECORD_A.FIELD_A.FieldFormula. This difference becomes important when FUNC_1 calls FUNC_3. Technically, both functions exist at the same time, one inside the other, but &TEMP is a different variable for each of them. However, if FUNC_1 calls FUNC_2, then &TEMP is the same variable for both.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
43
Chapter 2
44
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 2
Recursive Functions
PeopleCode supports True recursive functions. A function can call itself, and each possibly recursive call of the function has its own independent copy of the parameters and function-local variables. When writing recursive functions, be careful about passing variables as parameters, because PeopleCode implements such calls by reference. This means that if you call a function such as:
Function Func(&n as Number) &n = 3; End-Function; local &x = 5; Func(&x);
After the call to Func(&x), &x has the value 3, not 5. If the call was Func(Value(&x)), after the call &x is still 5.
In general, the global state of the object is restored. If the object has not been destroyed from the global state, the global state of the object is used for local references; otherwise, the local state is used for local references. Here is an example:
Global array of number &Global_Array;
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
45
Chapter 2
Local array of number &Local_Array: &Global_Array = CreateArray(1, 2, 3); &Local_Array = &Global_Array DoModal(Page.PAGENAME, "", -1, -1, 1, Record.SHAREDREC, 1); /* return to here */ &Local_Array[1] = -1; &Global_Array[2] = -2; WinMessage(&Local_Array is " | &Local_Array.Join()); WinMessage(&Global_Array is " | &Global_Array.Join());
The following program, program 2, is located on the modal page the user is transferred to:
Global array of number &Global_Array; &Global_Array[3] = -3;
If program 2 is run, the output is the following: &Local_Array is -1, -2, -3 &Global_Array is -1, -2, -3 However, if program 3 is run, thereby destroying the original global state, the output is the following: &Local_Array is -1, 2, 3 &Global_Array is 1, -2, -3
Related Links
PeopleTools 8.53: PeopleCode Language Reference PeopleTools 8.53: PeopleCode Developers Guide
Operators
PeopleCode expressions can be modified and combined using math, string, comparison, and Boolean operators. This section discusses: Math operators. Operations on dates and times. String concatenation. @ operator. Comparison operators. Boolean operators.
46
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 2
Math Operators
PeopleCode uses standard mathematical operators: + Add Subtract (or unary negative sign) * Multiply / Divide ** Exponential Exponentiation occurs before multiplication and division; multiplication and division occur before addition and subtraction. Otherwise, math expressions are evaluated from left to right. You can use parentheses to force the order of operator precedence. The minus sign can also, of course, be used as a negation operator, as in the following expressions:
-10 - &NUM - Product(&PERCENT_CUT, .01, SALARY)
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
47
Chapter 2
String Concatenation
The string concatenation operator ( | ) is used to combine strings. For example, assuming &OPER_NICKNAME is Dave, the following statement sets &RETORT to I cant do that, Dave.
&RETORT = "I can't do that, " | &OPER_NICKNAME | "."
The concatenation operator automatically converts its operands to strings. This conversion makes it easy to write statements that display mixed data types. For example:
&DAYS_LEFT = &CHRISTMAS - %Date; WinMessage("Today is " | %Date | ". Only " | &DAYS_LEFT | " shopping days left!");
@ Operator
The @ operator converts a string storing a definition reference into the definition. This is useful, for example, if you want to store definition references in the database as strings and retrieve them for use in PeopleCode; or if you want to obtain a definition reference in the form of a string from the operator using the Prompt function. To take a simple example, if the record field EMPLID is currently equal to 8001, the following expression evaluates to 8001:
@"EMPLID"
The following example uses the @ operator to convert strings storing a record reference and a record field reference:
&STR1 = "RECORD.BUS_EXPENSE_PER"; &STR2 = "BUS_EXPENSE_DTL.EMPLID"; &STR3 = FetchValue(@(&STR1), CurrentRowNumber(1), @(&STR2), 1); WinMessage(&STR3, 64);
Note: String literals that reference definitions are not maintained by PeopleTools. If you store definition references as strings, then convert them with the @ operator in the code, this creates maintenance problems whenever definition names change. The following function takes a rowset and a record, passed in from another program, and performs some processing. The GetRecord method does not take a variable for the record, however, you can dereference the record name using the @ symbol. Because the record name is never hard-coded as a string, if the record name changes, this code does not have to change.
Function Get_My_Row(&PASSED_ROWSET, &PASSED_RECORD) For &ROWSET_ROW = 1 To &PASSED_ROWSET.RowCount &UNDERLYINGREC = "RECORD." | &PASSED_ROWSET.DBRecordName; &ROW_RECORD = &PASSED_ROWSET.GetRow(&ROWSET_ROW).GetRecord(@&UNDERLYINGREC); /* Do other processing */ End-For; End-Function;
Comparison Operators
Comparison operators compare two expressions of the same data type. The result of the comparison is a Boolean value. The following table summarizes these operators:
48
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 2
Meaning Equal Not equal Not equal Less than Less than or equal to Greater than Greater than or equal to
You can precede any of the comparison operators with the word Not, for example: Not= Not< Not>=
Expressions formed with comparison operators form logical terms that can be combined using Boolean operators. String comparisons are case-sensitive. You can use the Upper or Lower built-in functions to do a caseinsensitive comparison.
Related Links
"Lower (PeopleTools 8.53: PeopleCode Language Reference)" "Upper (PeopleTools 8.53: PeopleCode Language Reference)"
Boolean Operators
The logical operators AND, OR, and NOT are used to combine Boolean expressions. The following table shows the results of combining two Boolean expressions with AND and OR operators:
Expression 1 False False True False False Operator AND AND AND OR OR Expression 2 False True True False True Result False False True False True
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
49
Chapter 2
Expression 1 True
Operator OR
Expression 2 True
Result True
The NOT operator negates Boolean expressions, changing a True value to False and a False value to True. In complex logical expressions using the operations AND, OR, and NOT, NOT takes the highest precedence, AND is next, and OR is lowest. Use parentheses to override precedence. (Generally, it is a good idea to use parentheses in logical expressions anyway, because it makes them easier to decipher.) If used on the right side of an assignment statement, Boolean expressions must be enclosed in parentheses. The following are examples of statements containing Boolean expressions:
&FLAG = (Not (&FLAG)); /* toggles a Boolean */ if ((&HAS_FLEAS or &HAS_TICKS) and SOAP_QTY <= MIN_SOAP_QTY) then SOAP_QTY = SOAP_QTY + OrderFleaSoap(SOAP_ORDER_QTY); end-if;
50
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 3
Classes
A class is the formal definition of an object and acts as a template from which an instance of an object is created at runtime. The class defines the properties of the object and the methods used to control the objects behavior. PeopleSoft delivers predefined classes, such as Array, File, Field, SQL, and so on. You can create your own classes using the Application class. You can also extend the functionality of the existing classes using the Application class.
Related Links
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
51
Chapter 3
Objects
An object represents a unique instance of a data structure defined by the template provided by its class. Each object has its own values for the variables belonging to its class and responds to methods defined by that class. This is the same for classes provided by PeopleSoft and for classes you create yourself. After an object has been created (instantiated) from a class, you can change its properties. A property is an attribute of an object. Properties define: Object characteristics, such as name or value. The state of an object, such as deleted or changed.
Some properties are read-only and cannot be set, such as Name or Author. Other properties can be set, such as Value or Label. Objects are different from other data structures. They include code (in the form of methods), not just static data. A method is a procedure or routine, associated with one or more classes, that acts on an object. An analogy to illustrate the difference between an object and its class is the difference between a car and the blue Citroen with license plate number TS5800B. A class is a general category, while the object is a specific instance of that class. Each car comes with standard characteristics, such as four wheels, an engine, or brakes, that define the class and are the template from which the individual car is created. You can change the properties of an individual car by personalizing it with bumper stickers or racing stripes, which is like changing the Name or Visible property of an object. The model and date that the car is created are similar to read-only properties because you cannot alter them. A tune-up acts on the individual car and changes its behavior, much as a method acts on an object.
Object Instantiation
A class is the blueprint for something, like a bicycle, a car, or a data structure. An object is the actual thing that is built using that class (or blueprint.) From the blueprint for a bicycle, you can build a specific mountain bike with 23 gears and tight suspension. From the blueprint of a data structure class, you build a specific instance of that class. Instantiation is the term for building that copy, or an instance, of a class.
Instantiating Objects
Generally you instantiate objects (create them from their classes) using built-in functions or methods of other objects. Some objects are instantiated from data already existing in the data buffer. Think about this kind of object instantiation as taking a chunk of data from the buffer, encapsulating it in code (methods
52 Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 3
and properties), manipulating it, then freeing the references. Some objects can be instantiated from a previously created definition, such as a page or file layout definition, instead of from data. The following example creates a field object:
Local field &MyField &MyField = GetField();
Get functions, which include functions such as GetField, GetRecord, and so on, generally provide access to data that already exists, whether in the data buffers or from an existing definition. Create functions, which include functions such as CreateObject, CreateArray, CreateRecord, generally create defined objects that do not yet exist in the data buffer. Create functions create only a buffer structure. They do not populate it with data. For example, the following function returns a record object for a record that already exists in the component buffer:
&REC = GetRecord();
The following example creates a standalone record. However, there is no data in &REC2. The specified record definition must be created previously, but the record does not have to exist in either the component or data buffer:
&REC2 = CreateRecord(EMP_CHKLST_ITM);
Objects with no built-in functions can only be instantiated from a session object (such as tree classes, component interfaces, and so on). For most of these classes, when you use a Get function, all you get is an identifier for the object. To fully instantiate the object, you must use an Open method.
Related Links
Changing Properties
To set or get characteristics of an object, or to determine the state of an object, you must access its properties through dot notation syntax. Follow the reference to the object with a period, followed by the property, and assign it a value. The format is generally as follows:
Object.Property = Value
You can return information about an object by returning the value of one of its properties. In the following example, &X is a variable that is assigned the value found in the field &MYFIELD:
&X = &MYFIELD.Value
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
53
Chapter 3
Invoking Methods
You also use dot notation to execute methods. Follow the reference to the object with a period, then with the method name and any parameters the method takes. The format is generally:
Object.method();
You can string methods and property values together into one statement. The following example strings together the GetField method with the Name property:
If &REC_BASE.GetField(&R).Name = &REC_RELLANG.GetField(&J).Name Then
Some methods return a Boolean value: True if the method executes successfully; False if it does not. The following method compares all like-named fields of the current record object with the specified record. This method returns as True if all like-named fields have the same value:
If &MYRECORD.CompareFields(&OTHERRECORD) Then
Other methods return a reference to an object. The GetCurrEffRow method returns a row object:
&MYROW = &MYROWSET.GetCurrEffRow();
Some methods do not return anything. Each method's documentation indicates what it returns. Many objects have default methods. Instead of entering the name of the method explicitly, you can use that method's parameters. Objects with default methods are composite objects; that is, they contain additional objects within them. The default method is generally the method used to get the lower-level object. A good example of a composite object is a record object. Record definitions are composed of field definitions. The default method for a record object is GetField. The following lines of code are equivalent:
&FIELD = &RECORD.GetField(FIELD.EMPLID); &FIELD = &RECORD.EMPLID;
Note: If the field youre accessing has the same name as a record property (such as NAME) you cannot use the shortcut method for accessing the field. You must use the GetField method. Another example of default methods concerns rowsets and rows. Rowsets are made up of rows, so the default method for a rowset is GetRow. The two specified lines of code are equivalent: They both get the fifth row of the rowset:
&ROWSET = GetRowSet(); /*the next two lines of code are equivalent */ &ROW = &ROWSET.GetRow(5); &ROW = &ROWSET(5);
The following example illustrates the long way of enabling the Name field on a second-level scroll area (the code is executing on the first-level scroll area):
GetRowset(SCROLL.EMPLOYEE_CHECKLIST).GetRow(1). GetRecord(EMPL_CHKLST_ITM).GetField(FIELD.NAME).Enabled = True;
Using default methods enables you to shorten the previous code to the following:
GetRowset(SCROLL.EMPLOYEE_CHECKLIST)(1).EMPL_CHKLST_ITM.NAME.
54
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 3
Enabled = True;
Expressions of the form class.name.property or class.name.method(..) are converted to a corresponding object. For example, the code &temp = RECORD.JOB.IsChanged; is evaluated as if it were &temp = GetRecord(RECORD.JOB).IsChanged;. Furthermore, the code JOB.EMPLID.Visible = False; is evaluated as if it were GetField(JOB.EMPLID).Visible = False;.
Copying Objects
Many of the classes delivered with PeopleTools have some sort of copy method, such as the rowset class CopyTo, the tree class Copy, and so on. Unless specifically identified (such as the message class CopyRowsetDelta) all copy methods use the current data of the object. This may be different than the original data values if the object was retrieved from the database and the values in it have been changed either by an end-user or a PeopleCode program.
Assigning Objects
When you assign one object to another, you do not create a copy of the object, but only make a copy of the reference. In the following example, &A1 and &A2 refer to the same object. The assignment of &A1 to &A2 does not allocate any database memory or copy any part of the original object. It makes &A2 refer to the same object to which &A1 refers.
Local Array of Number &A1, &A2; &A1 = CreateArray(2, 4, 6, 8, 10);
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
55
Chapter 3
&A2 = &A1;
Image: Representation of two arrays The following diagram shows how references of two arrays point to the same object.
Image: Representation of two arrays with same content If the next statement is &A2[5] = 12;, then &A1[5] also equals 12, as shown in the following diagram:
&NUM is of data type Number, which is not an object type. If you later change the value of &NUM in the program, you will nott change the element in the array.
Passing Objects
All PeopleCode objects can be passed as function parameters. You can pass complex data structures between PeopleCode functions (as opposed to passing long lists of fields). If a function is passed an object, the function works on the actual object, not on a copy of the object. In the following simple example, a reference to the Visible property is passed, not the value of Visible. This enables the MyPeopleCodeFunction either to get or set the value of the Visible property:
MyPeopleCodeFunction(&MyField.Visible);
In the following example, the function Process_Rowset loops through every row and record in the rowset passed to it and executes an Update statement on each record in the rowset. This function can be called from any PeopleCode program and can process any rowset that is passed to it.
Local Rowset &RS; Local Record &REC;
56
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 3
Function Process_RowSet(&ROWSET as Rowset); For &I = 1 To &ROWSET.Rowcount For &J = 1 To &ROWSET.Recordcount &REC = &ROWSET.GetRow(&I).GetRecord(&J); &REC.Update(); End-For; End-For; End-Function; &RS = GetLevel0(); Process_RowSet(&RS);
The following function takes a rowset and a record passed in from another program. GetRecord does not take a variable for the record; however, you can use the @ symbol to dereference the record name.
Function Get_My_Row(&PASSED_ROWSET, &PASSED_RECORD) For &ROWSET_ROW = 1 To &PASSED_ROWSET.RowCount &UNDERLYINGREC = "RECORD." | &PASSED_ROWSET.DBRecordName; &ROW_RECORD = &PASSED_ROWSET.GetRow(&ROWSET_ROW).GetRecord(@&UNDERLYINGREC); /* Do other processing */ End-For; End-Function;
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
57
Chapter 4
Related Links
Specifying Data with References Using Scroll Path Syntax and Dot Notation
In addition to the built-in functions used to access the component buffer, PeopleCode provides enhanced access to structured data buffers using the object syntax. Use the object-oriented PeopleCode to resolve contextual ambiguities when you reference a nonprimary record field that appears on more than one scroll level in a component. As with built-in functions, object syntax provides for both relative and absolute references to component buffer data. See Classes and Objects.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
59
Chapter 4
The component buffer consists of rows of buffer fields that hold data for the records associated with page controls, including primary scroll records, related display records, derived/work records, and Translate table records. PeopleCode can reference buffer fields associated with page controls and other buffer fields from the primary scroll record and related display records. See Record Fields and the Component Buffer. Primary scroll records are the principal SQL tables or views associated with page scroll levels. A primary scroll record uniquely identifies a scroll level in the context of its page: each scroll level can have only one primary scroll record, and the same primary scroll record cannot occur on more than one scroll area at the same level of the page. Parent-child relations between primary scroll records determine the dependency structure of the scroll areas on the page. The primary record on a level one scroll area must be a child of the primary record on level zero, the primary record on a level two scroll area must be a child of the primary record on its enclosing level one scroll area, and the primary record on a level three scroll area must be a child of the primary record on its enclosing level two scroll area. Note: Level zero may have multiple records. The hierarchical relations among scroll areas, controlled by hierarchical relations among primary scroll records, enable the user and PeopleCode to drill down through the scroll hierarchy to access any buffer field, including related display, derived/work, and Translate table buffer fields, which occupy space on the same rows as the primary scroll record buffer fields with which they are associated. For example, to access a page field on level two of a page, a user must: 1. Select a field on level one of the page. 2. Scroll to and select the field on level two of the page. Image: Scroll path to a buffer field The following diagram illustrates the scroll path taken by the user to a buffer field.
60
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 4
1. Specify a scroll area and row on scroll level one: this selects a subset of dependent rows on level two. 2. Specify a scroll area and row on scroll level two. 3. Specify the recordname.fieldname on the level two row. PeopleCode component buffer functions use a common scroll path syntax for locating scrolls, rows, and fields in multiple-scroll pages.
Related Links
Understanding Data Buffer Access "Understanding Rowset Class (PeopleTools 8.53: PeopleCode API Reference)" Classes and Objects
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
61
Chapter 4
Presence in Component Buffer If scroll level zero of a page contains only controls associated with primary scroll record fields that are search keys or alternate search keys, then only the search key and alternate search key fieldsave in the component buffer, not the entire record. The values for the fields come from the keylist, and the record cannot run RowInit PeopleCode. If level zero contains at least one record field from the primary scroll record that is not a search key or alternate search key, then all the record fields from the primary scroll record are available in the buffer. (For this reason, you may sometimes need to add one such record field at level zero of the page to make sure that all the record fields of the level-zero primary record can be referenced from PeopleCode.) The buffer contains the related display record field, plus any record fields from the related display record that are referenced by PeopleCode programs. You can reference any record field in a related display record. Only derived/work record fields associated with page controls are in the component buffer. Other record fields from the derived/work record cannot be referenced from PeopleCode. Only Translate table fields associated with page controls are available in the component buffer. Other fields from the Translate table cannot be referenced from PeopleCode.
Note: In RowSelect PeopleCode, you can refer only to record fields on the record that is currently being processed.
62
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 4
from PeopleCode, and which row of data is the current row on each scroll level at the time a PeopleCode program is executing. The current context comprises a subset of the buffer fields in the component buffer, determined by the row of data where a PeopleCode program is executing. The current context includes: All buffer fields in the row of data where the PeopleCode program is executing. All buffer fields in rows that are hierarchically superior to the row where the PeopleCode program is executing.
Image: Context of PeopleCode executing on a level two scroll area In the following diagram, all rows enclosed in dotted rectangles are part of the current context:
In the preceding diagram, a PeopleCode program is executing in a buffer field on row R3 on scroll level two. The rows in scroll level two are dependent on row R2 on scroll level one. The rows in scroll level one are dependent on the single row at scroll level zero. The current context consists of all the buffer fields at level two row R3, level one row R2, and level zero row R1. The rows in the current context on levels one and two are the current rows on their respective scroll areas. The single row on level zero is always current and is included in any current context. All rows other than the current rows and the level zero row are outside the current context. No current row can be determined on scroll areas below the one where the PeopleCode is executing.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
63
Chapter 4
With PeopleTools 8, contextual references work within the structure of a rowset object, and can include references to all field objects, record objects, row objects, and rowset objects in the current context.
In typical pages, this processing order is not significant; however, if the same record occurs on more than one level of a page, you should understand how the direct reference is resolved.
64
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 4
For example, you can use contextual row references with the RecordDeleted, RecordNew, and RecordChanged functions:
If RecordDeleted(RECORD.SOME_REC) Then...
With PeopleTools 8 object-oriented programming, a row can be referenced by specifying parent rows or rowsets of the current rowset:
If GetRowSet().ParentRowset.ParentRow.IsDeleted Then...
In early versions of PeopleTools, you could make contextual row references using a recordname.fieldname expression:
HideRow(SOME_REC.ANY_FIELD) If RecordDeleted(SOME_REC.ANY_FIELD) Then...
Related Links
With PeopleTools 8 object-oriented programming, a field object incorporates information about both the record field on which the buffer field is based and the page control with which the buffer field is associated. By referring to the field object, you either make a contextual buffer field reference or you change an interface attribute of the associated page control, depending on the object property you use. The following example has the same effect as a contextual buffer field reference:
/* Assigns value of a variable to a buffer field */ &MYFIELD.Value = &SOMEVAL;
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
65
Chapter 4
To explicitly reference the DERIVED_JS.CALC_1 buffer field on level one, use a component buffer function with a scroll path:
&VAL = FetchValue(SCROLL.level1_scrollname, CurrentRowNumber(1), DERIVED_JS.CALC_1);
The CurrentRowNumber function returns the current row on level one, or the parent row of the level two row where the PeopleCode program is executing.
Here rownum, because it is on level zero, is always equal to one. In the previous example of the DERIVED_JS.CALC_1 field, you would use this statement:
&VAL = FetchValue(DERIVED_JS.CALC_1, 1);
Note: Any change in a field objects value affects both the underlying record field and the value of any other field object oriented on the same record field. This behavior is the same as the behavior of contextual buffer field references that alter the field value.
Related Links
Specifying Data with References Using Scroll Path Syntax and Dot Notation
66
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 4
Specifying Data with References Using Scroll Path Syntax and Dot Notation
This section provides an overview of scroll paths and discusses how to: Structure scroll path syntax in PeopleTools 7.5. Reference scroll levels, rows, and buffer fields.
Related Links
If the target level (the level you want to reference) is one, you must supply only the RECORD.target_recname parameter. If the target scroll level is greater than one, you must provide scroll
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
67
Chapter 4
name and row level parameters for all hierarchically superior scroll levels, beginning at level one. The following table indicates the scroll path syntax for the three possible target scroll levels:
Target Level 1 2 3 Scroll Path Syntax
RECORD.target_recname RECORD.level1_recname, level1_row, RECORD.target_recname RECORD.level1_recname, level1_row, RECORD. level2_recname, level2_row, RECORD.target_ recname
If you are referring to a row or a buffer field, additional parameters are required after the scroll path. The following table describes the standard scroll path syntax parameters:
Syntax Parameters RECORD.level1_recname Description Specifies the name of a record associated with scroll level one, normally the primary scroll record. This parameter is required if the target scroll level is two or three. An integer that selects a row on scroll level one. This parameter is required if the target scroll level is two or three. Specifies the name of a record associated with scroll level two, normally the primary scroll record. This parameter is required if the target row is on scroll level three. An integer that selects a row on scroll level two. This parameter is required if the target row is on scroll level three. Specifies a record associated with the target scroll level, generally the primary scroll record. The scroll can be on level one, two, or three of the active page.
level1_row
RECORD.level2_recname
level2_row
RECORD.target_recname
68
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 4
RECORD.recordname is still permitted, and there is no requirement to use the SCROLL.scrollname alternative unless it is needed to avoid an ambiguous reference. The scrollname is the same as the scroll levels primary record name. The scroll name cannot be viewed or changed through the PeopleSoft Application Designer interface. Here is the complete scroll path syntax using SCROLL.scrollname expressions:
[SCROLL.level1_scrollname, level1_row, [SCROLL.level2_scrollname, level2_row, ]], SCR OLL.target_scrollname
The target scroll level in this construction is the scroll level that you want to specify. If the target level is one, you need to supply only the SCROLL.target_scrollname parameter. If the target scroll level is greater than one, you need to provide scroll name and row-level parameters for hierarchically superior scroll levels, beginning at level one. The following table indicates the scroll path syntax for the three possible target scroll levels:
Target Level 1 2 3 Scroll Path Syntax
SCROLL.target_scrollname SCROLL.level1_scrollname, level1_ row, SCROLL.target_scrollname SCROLL.level1_scrollname, level1_ row, SCROLL.level2_scrollname, level2_ row, SCROLL.target_scrollname
If the component you are referring to is a row or a buffer field, additional parameters are required after the scroll path. The following table describes the alternative scroll path syntax parameters:
Parameter SCROLL.level1_scrollname Description Specifies the name of the pages level-one scroll area. This is always the same as the name of the scroll levels primary scroll record. This parameter is required if the target scroll level is two or three. An integer that selects a row on scroll level one. This parameter is required if the target scroll level is two or three. Specifies the name of the pages level two scroll area. This is always the same as the name of the scroll levels primary scroll record. This parameter is required if the target row is on scroll level three. An integer that selects a row on scroll level two. This parameter is required if the target row is on scroll level three.
level1_row
SCROLL.level2_scrollname
level2_row
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
69
Chapter 4
Parameter SCROLL.target_scrollname
Description The scroll name of the target scroll level, which can be level one, two, or three of the active page.
Related Links
Example Function
HideScroll(scrollpath); HideRow(scrollpath, row_ number); FetchValue(scrollpath, row_ number, fieldname);
PeopleTools 8 provides an alternative to the scroll level, row, and field components in the form of the data buffer classes Rowset, Row, Record, and Field, which you reference using dot notation with object methods and properties. The following table demonstrates the syntax for instantiating and manipulating objects in the current context from these classes:
Target Object Rowset Row Record Field Example Instantiation
&MYROWSET = GetRowset(); &MYROW = GetRow(); &MYRECORD = GetRecord(); &MYFIELD = GetRecord(). fieldname;
Example Operation
&MYROWSET.Refresh(); &MYROW.CopyTo(&SOMEROW); &MYREC.CompareFields(&REC); &MYFIELD.Label = "Last Name";
The following sections provide examples of functions using scroll path syntax, which refer to an example page from a fictitious veterinary clinic database. The page has three scroll levels, shown in the following table:
Level 0 1 Scroll Name (Primary Scroll Record Name) VET OWNER
70
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 4
Level 2 3
The examples given for PeopleTools 8 object-oriented syntax assumes that the following initializing code was executed:
Local Rowset &VET_SCROLL = &OWNER_SCROLL &PET_SCROLL = &VISIT_SCROLL &VET_SCROLL, &OWNER_SCROLL, &PET_SCROLL, &VISIT_SCROLL; GetLevel0(); = &VET_SCROLL.GetRow(1).GetRowSet(SCROLL.OWNER); &OWNER_SCROLL.GetRow(2).GetRowSet(SCROLL.PET); = &PET_SCROLL.GetRow(2).GetRowSet(SCROLL.VISIT);
where scrollpath is
[RECORD.level1_recname, level1_row, [RECORD.level2_recname, level2_row,]] RECORD.targ et_recname
This hides the OWNER, PET, and VISIT scroll areas on the example page. In PeopleTools 8, the object-oriented version of this is:
&OWNER_SCROLL.HideAllRows();
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
71
Chapter 4
To hide scroll levels two and below, supply the primary record and row in scroll level one, and then the record identifying the target scroll area:
HideScroll(RECORD.OWNER, &L1ROW, RECORD.PET);
Image: Sample scroll path The following diagram shows the scroll path of this statement, assuming that the value of &L1ROW is 2:
Similarly, to hide the VISIT scroll area on level three, you specify rows on scroll levels one and two.
HideScroll(RECORD.OWNER, &L1ROW, RECORD.PET, &L2ROW, RECORD.VISIT);
To use the SCROLL.scrollname syntax, the previous example could be written as the following:
HideScroll(SCROLL.OWNER, &L1ROW, SCROLL.PET, &L2ROW, SCROLL.VISIT);
Referring to Rows
Referring to rows is the same as referring to scroll areas, except that you need to specify the row you want to select on the target scroll area. As an example, examine the HideRow function, which hides a specific row in the level three scroll area of the page. Here is the function syntax:
HideRow(scrollpath, target_row)
72
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 4
In PeopleTools 8, the object-oriented version of this for the OWNER rowset is:
&OWNER_SCROLL(&ROW_NUM).Visible = False;
On level two:
HideRow(RECORD.OWNER, &L1_ROW), RECORD.PET, &ROW_NUM);
In PeopleTools 8, the object-oriented version of this for the PET rowset is:
&PET_SCROLL(&ROW_NUM).Visible = False;
Image: Scroll path statement The following diagram indicates the scroll path of this statement, assuming that the value of &L1_ROW is 2 and that &ROW_NUM is equal to 2:
On level three:
HideRow(RECORD.OWNER, CurrentRowNumber(1), RECORD.PET, CurrentRowNumber(2), RECORD.VISIT, &ROW_NUM);
In PeopleTools 8, the object-oriented version of this for the VISIT rowset is:
&VISIT_SCROLL(&ROW_NUM).Visible = False;
Assume, for example, that record definitions in the veterinary database have the following fields that you want to reference:
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
73
Chapter 4
You could use the following examples to retrieve values on levels one, two, or three from a PeopleCode program executing on level zero. To fetch a value of the OWNER_NAME field on the current row of scroll area one:
&SOMENAME = FetchValue(RECORD.OWNER, &L1_ROW, OWNER.OWNER_NAME);
In PeopleTools 8, the object-oriented version of this for the OWNER rowset is:
&SOMENAME = &OWNER_SCROLL(&L1_ROW).OWNER.OWNER_NAME;
In PeopleTools 8, the object-oriented version of this for the PET rowset is:
&SOMEBREED = &PET_SCROLL(&L2_ROW).PET.PET_BREED;
Image: Scroll path to target field The following diagram indicates the scroll path to the target field, assuming that &L1_ROW equals 2, &L2_ROW equals 2, and field F3 is PET.PET_BREED.
74
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 4
Using CurrentRowNumber
The CurrentRowNumber function returns the current row, as determined by the current context, for a specific scroll level in the active page. CurrentRowNumber is often used to determine a value for the level1_row and level2_row parameters in scroll path constructions. Because current row numbers are determined by the current context, CurrentRowNumber cannot determine a current row on a scroll level outside the current context (a scroll level below the level where the PeopleCode program is currently executing). For example, you could use a statement like this to retrieve the value of a buffer field on level three of the PET_VISITS page, in a PeopleCode program executing on level two:
&VAL = FetchValue(RECORD.OWNER, CurrentRowNumber(1), RECORD.PET, CurrentRowNumber(2), RECORD.VISIT, &TARGETROW, VISIT_REASON);
Because the PeopleCode program is executing on level two, CurrentRowNumber can return values for levels one and two, but not three, because level three is outside of the current context and has no current row number.
A similar construct may be used in accessing other level two or level one scroll areas, such as work scroll areas. In these constructions, the ActiveRowCount function is often used to determine the upper bounds of the loop. When ActiveRowCount is used for this purpose, the loop goes through all of the active rows in the scroll (rows that have not been specified as deleted). If you use TotalRowCount to determine the upper bounds of the loop, the loop goes through all of the rows in the scroll area: first those that have not been specified as deleted, then those that have been specified as deleted.
Related Links
Structuring Scroll Path Syntax in PeopleTools 7.5 Understanding Current Context "CurrentRowNumber (PeopleTools 8.53: PeopleCode Language Reference)"
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
75
Chapter 5
Access Classes
The four data buffer classes are: Rowset, Row, Record, and Field. These four classes are the foundation for accessing component buffer data through the new object syntax. A field object, which is instantiated from the Field class, is a single instance of data within a record. It 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. It is based on a record definition. A record object consists of one to n fields.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
77
Chapter 5
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 area is a row. A row may have one to n child rowsets. For example, a row in a level two scroll area may have n level three 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 area is a rowset. You can also have a level zero rowset.
For component buffers, think of a rowset as a scroll area on a page that contains all of the data in that scroll area. A level zero rowset contains all the data for the entire component. You can use rowsets with application messages, file layouts, business interlinks, and other definitions in addition to components. A level zero rowset from a component buffer only contains one row: the keys that the user specifies to initiate that component. A level zero rowset from data that is not a component, such as a message or a file layout, might contain more than one level zero row. The following is basic PeopleCode that traverses through a two-level component buffer using dot notation syntax. Level zero is based on record QA_INVEST_HDR, and level one is based on record QA_INVEST_LN.
Local Rowset &HDR_ROWSET, &LINE_ROWSET; Local Record &HDR_REC, &LINE_REC; &HDR_ROWSET = GetLevel0(); For &I = 1 to &HDR_ROWSET.RowCount &HDR_REC = &HDR_ROWSET(&I).QA_INVEST_HDR; &EMPLID = &HDR_REC.EMPLID.Value; &LINE_ROWSET = &HDR_ROWSET(&I).GetRowset(1); For &J = 1 to &LINE_ROWSET.RowCount &LINE_REC = &LINE_ROWSET(&J).QA_INVEST_LN; &LINE_SUM = &LINE_SUM + &LINE_REC.AMOUNT.Value; End-For; End-For;
Each rowset is declared and instantiated. In general, your code is easier to read and maintain if you follow this practice.
78
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 5
Object creation examples. Data buffer hierarchy examples. Rowset examples. Hidden work scroll area example.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
79
Chapter 5
Another way of looking at the structure of a component is to use the Structure view. All the scroll areas are labeled, and the primary record is associated with each: Image: EMPLOYEE_CHECKLIST structure The following image explains EMPLOYEE_CHECKLIST structure of a component where in all the scroll areas are labeled, and the primary record is associated with each other.
In the example, the visible level one scroll area also has only one row. That row is made up of the following records: EMPL_CHECKLIST DERIVED_HR CHECKLIST_TBL PERSONAL_DATA
80
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 5
You can see which records are associated with a scroll area by looking at the Order view for a page: Image: EMPLOYEE_CHECKLIST page Order view showing records The following image is an example of EMPLOYEE_CHECKLIST page. This page shows the Order view of the records associated with a scroll area.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
81
Chapter 5
Image: EMPLOYEE_CHECKLIST rowsets and rows The level two rowset has three rows. Each row is made up of two records: the primary record, EMPL_CHKLST_ITM, and CHKLST_ITM_TBL, the record associated with the related display field DESCR. The following example shows the rowset:
Every record has fields associated with it, such as NAME, EMPLID and CHECKLIST_SEQ. These fields are associated with the record definitions; they are not the fields that appear on the page.
The level zero rowset contains all the rows, rowsets, records, and fields underneath it. If the level zero rowset is formed from component buffer data, then the level zero rowset has one row of data and that row contains all the child rowsets, which in turn contain rows of data that contain other child rowsets.
82
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 5
If the level zero rowset is formed from buffer data, such as from an application message, then the level zero rowset may contain more than one row of data. Each row of the level zero rowset contains all the child rowsets associated with that row, which in turn contain rows of data that contain other child rowsets. Use a level zero rowset when you want an absolute path to a lower-level object or to do some processing on the entire data buffer. For example, suppose you load all new data into the component buffers and want to redraw the page. You could use the following code:
/* Do processing to reload Component Buffers */ &LEVEL0 = GetLevel0(); &LEVEL0.Refresh();
Rowset Object
The following code instantiates a rowset object that references the rowset that contains the currently running PeopleCode program:
&ROWSET = GetRowset();
You might later use the &ROWSET variable and the ActiveRowCount property to iterate over all the rows of the rowset, to access a specific row (using the GetRow method), or to hide a child rowset (by setting the Visible property).
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
83
Chapter 5
The level one rowset contains all the level two rowsets. However, the level two rowsets can only be accessed using the different rows of the level one rowset. From the level zero or level one rowset, you can only access a level two rowset by using the level one rowset and the appropriate row. Image: Level two rowset from level one row For example, suppose your program is running on some field of row five of a level two scroll area, which is on row three of its level one scroll area. The resulting rowset contains all the rows of the level two scroll area that are under the row three of the level one scroll area. The rowset does not contain any data that is under any other level two scroll areas. The following diagram illustrates these results:
A further illustration uses an example from the Employee Checklist page. Suppose that one employee was associated with three different checklists: Foreign Loan Departure, Foreign Loan Arrival, and Foreign Loan Host. The checklist code field (CHECKLIST_CD) on the first
84
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 5
level of the page drives the entries on the second level. Each row in the level one rowset produces a different level two rowset. Image: EMPLOYEE_CHECKLIST Foreign Loan Departure checklist The Foreign Loan Departure checklist (000001) produces a checklist that contains such items as Briefing with Human Resources and Apply for Visas/Work permits, as shown in the following example:
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
85
Chapter 5
Image: EMPLOYEE_CHECKLIST Foreign Load Arrival Checklist he Foreign Loan Arrival checklist (0000004) produces a checklist that contains items such as Register at Consulate and Open New Foreign Bank Accounts, as shown in the following example:
Row Object
When you create a page, you put fields from different records onto the page. You can think of this as creating a type of pseudo-SQL join. The row returned from this pseudo-join is a row object. For example, the first level scroll area of the EMPLOYEE_CHECKLIST page contains the following fields, associated with these records:
Field CHECKLIST_DT CHECKLIST_CD COMMENTS DESCR NAME RESPONSIBLE_ID Record EMPL_CHECKLIST EMPL_CHECKLIST EMPL_CHECKLIST CHECKLIST_TBL PERSONAL_DATA EMPL_CHECKLIST
86
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 5
What goes into the Where clause is determined by the level zero of the page. For our example, the value is WHERE EMPLID=8001. When the component is opened, data is loaded into the component buffers. Any row returned by the pseudo-SQL statement is a level one row object. The following table shows a returned row:
CHECKLIST_ DT 12/03/98 CHECKLIST_ CD 000001 COMMENTS DESCR NAME RESPONSIBLE _ID 6602
Peppen, Jacques
Record Object
A record definition is a definition of what your underlying SQL database tables look like and how they process data. After you create record definitions, you build the underlying SQL tables that contain the application data that your users enter online in your production environment. When you create a record object using the CreateRecord function, you are creating an area in the data buffers that has the same structure as the record definition, but no data. When you instantiate a record object from the Record class using some variation of GetRecord, that record object references a single row of data in the SQL table. Note: The data in the record that you retrieve is based on the row, which is analogous to setting keys to return a unique record. The following code instantiates a record object for referencing the EMPL_CHECKLIST record of the specified row:
&REC = &ROW.GetRecord(RECORD.EMPL_CHECKLIST);
Using the short method, the following line of code is identical to the previous line:
&REC = &ROW.EMPL_CHECKLIST;
You might later use the &REC variable and the CopyFieldsTo property to copy all like-named fields from one record to another. In the following example, two row objects are created, the copy from row (COPYFRMROW) and the copy to row (COPYTROW). Using these rows, like-named fields are copied from CHECKLIST_ITEM to EMPL_CHKLST_ITM.
For &I = 1 To &ROWSET1.ActiveRowCount ©FRMROW = &ROWSET1.GetRow(&I); ©TROW = &RS2.GetRow(&I); ©FRMROW.CHECKLIST_ITEM.CopyFieldsTo(©TROW.EMPL_CHKLST_ITM); End-For;
A row may contain more than one record: in addition to the primary database record, you may have a related display record or a derived record. You can access these records as well. The level one rowset,
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
87
Chapter 5
&ROWSET1, is made up of many records. The following accesses two of them: EMPL_CHECKLIST and DERIVED_HR.
&REC1 = &ROW.EMPL_CHECKLIST; &REC2 = &ROW.DERIVED_HR;
Field Object
The following instantiates a field object, from the Field class, that is used to access a specific field in the record:
&FIELD = &REC.GetField(FIELD.CHECKLIST_CD);
Note: The data in the field that you retrieve is based on the record, which is in turn based on the row. You can also set the value of a field. Using the GetField function does not create a copy of the data from the component buffer. Setting the value or a property of the field object sets the actual component buffer field or property. See Assigning Objects. In the following example, the type of field is verified, and the value is replaced with the tangent of that value if it is a number
If &FIELD.Type <> "NUMBER" Then /* do error recording */ Else &FIELD.Value = Tan(&FIELD.Value); End-If;
88
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 5
Suppose you want to access the BRIEFING_STATUS field at level two of the following page: First, determine where your code is running. For this example, the code is starting at a field on a record at level zero. However, you do not always have to start at level zero. If you start with level zero, you must traverse the data hierarchy, through the level one rowset to the level two rowset, before you can access the record that contains the field.
Obtaining Rows
The next object to get is a row. As the following code is working with data that is loaded from a page, only one row is at level zero. However, if you have rowsets that are populated with data that is not based on component buffers (for example, an application message), you may have more than one row at level zero.
&LEVEL0_ROW = &LEVEL0(1);
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
89
Chapter 5
Obtaining Records
A row always contains a record, and it 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 are processing all the rows at level two, we just add code to the For loops of the previous example. 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;
Obtaining 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.
90
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 5
Because we are processing all the rows at the level one, we are just adding code to the For loops of the previous example. 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;
Using Shortcuts
Image: Rowset example The previous code is the long way of accessing this field. The following example uses shortcuts to access the field in one line of code. The following code assumes all rows are level one:
Code
&LEVEL0 = GetLevel0(); &LEVEL0_ROW = &LEVEL0(1); &LEVEL1 = &LEVEL0_ROW.GetRowset(SCROLL. EMPL_CHECKLIST); For &I = 1 to &LEVEL1.ActiveRowCount
Row Rowset
Row Record
ITM;
Field
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
91
Chapter 5
Rowset Examples
The following code example traverses up to four levels of rowsets and could easily be modified to do more. This example only processes the first record in every rowset. To process every record, set up another For loop (For &R = 1 to &LEVELX.RECORDCOUNT, and so on). Notice the use of the ChildCount function (to process all children rowsets within a rowset), ActiveRowCount, IsChanged, and dot notation. In the following example, ellipses indicate where application-specific code should go.
&Level0_ROWSET = GetLevel0(); For &A0 = 1 To &Level0_ROWSET.ActiveRowCount ... /***************************/ /* Process Level 1 Records */ /*-------------------------*/ If &Level0_ROWSET(&A0).ChildCount > 0 Then For &B1 = 1 To &Level0_ROWSET(&A0).ChildCount &LEVEL1_ROWSET = &Level0_ROWSET(&A0).GetRowset(&B1); For &A1 = 1 To &LEVEL1_ROWSET.ActiveRowCount If &LEVEL1_ROWSET(&A1).GetRecord(1).IsChanged Then ... /***************************/ /* Process Level 2 Records */ /*-------------------------*/ If &LEVEL1_ROWSET(&A1).ChildCount > 0 Then For &B2 = 1 To &LEVEL1_ROWSET(&A1).ChildCount &LEVEL2_ROWSET = &LEVEL1_ROWSET(&A1).GetRowset(&B2); For &A2 = 1 To &LEVEL2_ROWSET.ActiveRowCount If &LEVEL2_ROWSET(&A2).GetRecord(1).IsChanged Then ... /***************************/ /* Process Level 3 Records */ /*-------------------------*/ If &LEVEL2_ROWSET(&A2).ChildCount > 0 Then For &B3 = 1 To &LEVEL1_ROWSET(&A2).ChildCount &LEVEL3_ROWSET = &LEVEL2_ROWSET(&A2).GetRowset(&B3); For &A3 = 1 To &LEVEL3_ROWSET.ActiveRowCount If &LEVEL3_ROWSET(&A3).GetRecord(1).IsChanged Then ... End-If; /* A3 - IsChanged */ End-For; /* A3 - Loop */ End-For; /* B3 - Loop */ End-If; /* A2 - ChildCount > 0 */ /*--------------------------------*/ /* End of Process Level 3 Records */ /**********************************/ End-If; /* A2 - IsChanged */ End-For; /* A2 - Loop */ End-For; /* B2 - Loop */ End-If; /* A1 - ChildCount > 0 */ /*--------------------------------*/ /* End of Process Level 2 Records */ /**********************************/ End-If; /* A1 - IsChanged */ End-For; /* A1 - Loop */ End-For; /* B1 - Loop */ End-If; /* A0 - ChildCount > 0 */
92
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 5
The following example performs the same function as the previous code, only it uses the data buffer classes: 1. Flushes the rowset and hidden work scroll area (&RS1H). 2. Performs a Select statement on &RS1H based on the value of the CHECKLIST_CD field and the effective date. 3. Clears the level two rowset (&RS2).
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
93
Chapter 5
94
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 5
In this example, a PeopleCode program is running in a buffer field on the second row of the level one rowset. The following code returns a row object for the second row of the level one rowset, because that is the row that is the current context.
Local Row &ROW &ROW = GetRow();
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
95
Chapter 5
The following code returns the B2 level two rowset because of the current context:
Local Rowset &ROWSET2 &ROWSET2 = &ROW.GetRowset(SCROLL.EMPL_CHKLST_ITM);
This code does not return either the C2 or the A2 rowsets. It returns only the rowset associated with the second row of the level one rowset.
Related Links
Specifying Data with Contextual References "CreateRecord (PeopleTools 8.53: PeopleCode Language Reference)" "CreateRowset (PeopleTools 8.53: PeopleCode Language Reference)"
96
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 5
In an Application Engine program, the default state record is considered the primary record and the main record in context. You can access the default state record using the following:
&STATERECORD = GetRecord();
If you have more than one state record associated with an Application Engine program, you can access them the same way you would access other, nonprimary data records, by specifying the record name. For example:
&ALTSTATE = GetRecord(RECORD.AE_STATE_ALT);
Related Links
Using Standalone Rowsets PeopleTools 8.53: PeopleSoft Integration Broker PeopleTools 8.53: Application Engine
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
97
Chapter 6
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
99
Chapter 6
Related Links
PeopleTools 8.53: PeopleCode API Reference PeopleTools 8.53: PeopleCode API Reference "Specifying PeopleCode Actions (PeopleTools 8.53: Application Engine)" PeopleTools 8.53: Security Administration
Suppose a user changes the data in a page field, and then presses Tab to move out of the field. This user action initiates the FieldEdit PeopleCode event. The FieldEdit event affects only the field and row where the change took place. If a FieldEdit PeopleCode program is associated with that record field, the program is executed once. If you have two FieldEdit PeopleCode programs, one associated with the record field and a second associated with the component record field, both programs execute, but only on the specific field and row of data. The FieldEdit PeopleCode program associated with the first record field is initiated first, and then the FieldEdit PeopleCode program associated with the first component record field is initiated. By contrast, suppose a user has opened a component for updating. As part of building the component, the Component Processor initiates the RowInit event. This event triggers RowInit PeopleCode programs
100
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
on every record field on every row of data in the component. In a scroll area with multiple rows of data, every RowInit PeopleCode program is executed once for each row. In addition, if you have RowInit PeopleCode associated with both the record field and the component record, both programs are executed against every record field on every row of data in the component. The RowInit PeopleCode program associated with the first record field is initiated first, and then the RowInit PeopleCode program associated with the first component record is initiated. If you set the value of a field with the record field RowInit PeopleCode, and then reset the field with the component record RowInit PeopleCode, the second value appears to the user. When you develop with PeopleCode, you must consider when and where your programs are triggered during execution of the Component Processor flow. This section discusses how to: Access PeopleCode programs. Understand the execution order of events and PeopleCode.
Related Links
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
101
Chapter 6
Record Field Events FieldChange FieldDefault FieldEdit FieldFormula PrePopup RowDelete RowInit RowInsert RowSelect SaveEdit SavePostChg SavePreChg SearchInit SearchSave Workflow
Component Component Record Events Events RowDelete RowInit RowInsert RowSelect SaveEdit SavePostChg SavePreChg SeachInit SearchSave PostBuild PreBuild SavePostChg SavePreChg Workflow
Page Events
Menu Events
Activate
ItemSelected
The following table lists types of PeopleCode programs and where to access them in PeopleSoft Application Designer.
PeopleCode Programs Record field Component record field, component record, and component Menu item Page field Location in PeopleSoft Application Designer Record definitions and page definitions Component definitions Menu definitions Page definitions
102
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
surrounding your code with dozens of If %Component = statements). Records are more reusable, and code is more maintainable. For example, if you have start and end dates for a course, you would always want to make sure that the end date was after the start date. Your program to check the dates would go on the SaveEdit at the record field level. All similarly named component events are initiated after the like-named record event. The PeopleCode program associated with the record field event is initiated first, and then the PeopleCode program associated with the like-named component event is initiated. If you set the value of a field with the record field PeopleCode, and then reset the field with like-named component PeopleCode, the second value is displayed to the user.
Image: Flow of events and PeopleCode programs after a user changes a field The following diagram shows the flow of events and PeopleCode programs after a user changes a field.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
103
Chapter 6
104
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
Component.SavePostChange
Image: Flow of PeopleCode programs after SavePostChange event The following diagram shows the event flow of PeopleCode programs after SavePostChange event.
Note: SaveEdit does not fire for deleted rows, but SavePreChange, Workflow, and SavePostChange do.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
105
Chapter 6
Related Links
106
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
5. Displays the component and waits for user action. Image: Processing up to Page Display The following flowchart shows the behavior of a component processor from page start to page display at a high level:
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
107
Chapter 6
Description If a user edits a page field, then leaves the field, the Component Processor performs standard edits (such as checking the data type and checking for values out of range). If the contents of the field do not pass the standard system edits, the Component Processor redisplays the page with an error or warning message and changes the fields color to the system color for field edit errors, usually red. Until the user corrects the error, the Component Processor does not let the user save changes or navigate to another field. If the contents of the field pass the standard system edits, the system redisplays the page and waits for further action. See Field Modification.
Prompts
If a user clicks the prompt icon next to a field, a list of values for the prompt field appears. If the Allow Search Events for Prompt Dialogs checkbox is selected in the record field properties for the search key, the SearchInit event will trigger before the prompt dialog appears. If the user clicks the Look Up button the SearchSave event will trigger. If the end-user clicks the detail button next to a date field, a calendar appears. If the user clicks Return To Search, or presses Alt+2, a search page appears, enabling the user to enter an alternate search key or partial value. See Prompts, Search Processing in Update Modes.
If a user clicks the pop-up icon next to a field, a pop-up menu appears. This can be a default pop-up menu or one that has been defined by the developer. If the user clicks the pop-up icon at the bottom of the page, the pop-up menu for the page appears. See Pop-Up Menu Display.
ItemSelected Processing
A user can select an item from a pop-up menu to execute a command. See Selected Item Processing.
Push Button
108
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
Description A user can direct the system to save a component by clicking Save or by pressing Alt+1. If any component data has been modified, the system also prompts the user to save a component when the Next or List button is clicked, or when a new action or component is selected. The Component Processor first validates the data in the component, and then updates the database with the changed component data. After the update, a SQL Commit command finalizes the changes. See Save Processing.
Processing Sequences
This section presents an overview of flow charts and discusses: Default processing. Search processing in update mode. Search processing in add mode. Component build processing in update mode. Row select processing. Component build processing in add mode. Field modification. Row insert processing. Row delete processing. Buttons. Prompts. Pop-up menu display. Selected item processing. Save processing.
Flow Charts
Actions and PeopleCode events can occur in various sequences within the Component Processors flow of execution. Flow charts represent each sequence. In a flow chart, different shapes and colors represent different concepts.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
109
Chapter 6
Most processing sequences correspond to high-level component processor behaviors. However, two important subsequences occur only in the context of a larger sequence. These subsequences are: Default processing, which occurs in a number of different contexts. Row select processing, which most commonly occurs as a part of component build in any of the update action modes. Row select processing also occurs when a ScrollSelect or related function is executed to load data into a scroll area. See Component Processor Behavior, Default ProcessingDefault Processing. Note: Variations may occur in processing sequences, particularly when a PeopleCode function within a processing sequence initiates another processing sequence. For example, if a row of data is inserted or deleted programmatically during the component build sequence, a row insert or row delete sequence is initiated. Also note that components that run in deferred mode behave differently. See Deferred Processing Mode.
Default Processing
In default processing, any blank fields in the component are set to their default values. You can specify the default value either in the record field properties or in FieldDefault PeopleCode. If no default value is specified, the field is left blank. Note: In PeopleSoft Pure Internet Architecture, if a user changes a field, but there is nothing to cause a trip to the server on that field, default processing and FieldFormula PeopleCode do not run. They only run when another event causes a trip to the server. Default processing is relatively complex. The following two sections describe how default processing works on the level of the individual field, and how default processing works in the broader context of the component.
110
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
111
Chapter 6
112
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
5. If any field is still blank and any other field in the component has changed, field-level default processing is repeated. Image: Default processing on component level The following flowchart explains the logic of Default processing on component level.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
113
Chapter 6
For example, the following program in SearchInit PeopleCode on the component search key record field EMPLID sets the search key page field to the users employee ID, makes the page field unavailable for entry, and enables the user to modify the users own data in the component:
EMPLID = %EmployeeId; &Field = GetField(EMPLID).Enabled = False; AllowEmplIdChg(True);
Note: Generally, the system search processing displays the search page. You can use the SearchInit event, and the SetSearchDialogBehavior function, to set the behavior of the search page before it is displayed. If SetSearchDialogBehavior is set to Force display, the dialog box is displayed even if all required keys have been provided. You can also set SetSearchDialogBehavior to skip if possible. In addition, you can force search processing to always occur by selecting Force Search Processing in the component definition properties in PeopleSoft Application Designer. 2. The search page and prompt list appear, in which the user can enter search keys or select an advanced search to enter alternate search keys. Note: Normally, the values in the search page are not set to default values. However, if the SearchDefault function was executed in SearchInit PeopleCode for any of the search key or alternate search fields, those fields in the dialog box are set to their system default values. No other default processing occurs (that is, the FieldDefault event is not initiated). 3. The user enters a value or partial value in the search page, and then clicks Search. 4. The SearchSave PeopleCode event is initiated, which triggers any SearchSave PeopleCode associated with the record field or the component search record, on the search keys or alternate search keys in the search record. This enables you to validate the user entry in the search page by testing the value in the search record field in PeopleCode and, if necessary, issuing an error or warning. If an error is executed in SearchSave, the user is sent back to the search page. If a warning is executed, the user can click OK to continue or click Cancel to return to the search page and enter new values. If partial values are entered, such that the Component Processor can select multiple rows, then the prompt list dialog box is filled, and the user can select a value. If key values from the search page are blank, or if the system cannot select any data based on the user entry in the search page, the system displays a message and redisplays the search page. If the values entered produce a unique value, the prompt list is not filled. Instead, the user is taken directly to the page. Note: Normally, no system edits are applied when the user changes a field in the search page. However, if the SearchEdit property is executed for specific search page fields in SearchInit PeopleCode, the system edits are applied to those fields after the user changes a field and either leaves the field or clicks Search. In addition, the SearchEdit property can also be set in metadata for the record field definition. If the user entry in the field fails the system edits, the system displays a message, highlights the field in question, and returns the user to the dialog box. The FieldEdit and SaveEdit PeopleCode events are not initiated. The SearchSave event is not initiated after values are selected from the search list. To validate data entered in the search page, use the Component PreBuild event. 5. The Component Processor buffers the search key values.
114
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
If the user then opens another component while this component is active, the Component Processor uses the same search key values and bypasses the search page. Image: Search processing logic in update mode The following flowchart shows this logic. (It does not show the effects of executing the SearchDefault and SearchEdit Field class properties.)
Note: You can use the IsSearchDialog built-in function to create PeopleCode that runs only during search processing. To create processes that run only in a specific action mode, use the %Mode system variable. This could be useful in code that is part of a library function and that is invoked in places other than from the search page. It could also be used in PeopleCode associated with a record field that appears in pages and in the search page.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
115
Chapter 6
Related Links
"SetSearchDialogBehavior (PeopleTools 8.53: PeopleCode Language Reference)" "SearchDefault (PeopleTools 8.53: PeopleCode API Reference)" "%Mode (PeopleTools 8.53: PeopleCode Language Reference)"
116
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
See Search Processing in Update Modes. Image: Search processing logic in add and data-entry modes The following flowchart diagram shows the logic of Search processing in add and data-entry modes.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
117
Chapter 6
Note: You can use the IsSearchDialog function to create PeopleCode that runs only during search processing. To create processes that run only in a specific action mode, use the %Mode system variable. This could be useful in code that is part of a library function and that is invoked in places other than from the search page. It could also be used in PeopleCode associated with a record field that appears in pages and in the search page.
Related Links
"IsSearchDialog (PeopleTools 8.53: PeopleCode Language Reference)" "%Mode (PeopleTools 8.53: PeopleCode Language Reference)"
118
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
7. Displays the component and waits for end-user action. Image: Component build processing in update modes The following flowchart shows the logic of Component build processing in update modes.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
119
Chapter 6
1. The Component Processor checks for more rows to add to the component. 2. The Component Processor initiates the RowSelect event, which triggers any RowSelect PeopleCode associated with the record field or component record. This enables PeopleCode to filter rows using the StopFetching and DiscardRow functions. StopFetching causes the system to add the current row to the component, and then to stop adding rows to the component. DiscardRow filters out a current row, and then continues the row select process. 3. If neither the StopFetching nor DiscardRow function is called, the Component Processor adds the rows to the page and checks for the next row. The process continues until there are no more rows to add to the component buffers. If both StopFetching and DiscardRow are called, the current row is not added to the page, and no more rows are added to the page.
120
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
Note: In RowSelect PeopleCode, you can refer only to record fields on the record that is currently being processed, because the buffers are in the process of being populated. This means that the data might not be present. Image: RowSelect processing logic The following flowchart shows the logic of RowSelect processing in a Page.
Related Links
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
121
Chapter 6
122
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
Field Modification
The field modification processing sequence occurs after a user does any of the following: Changes the contents of a field, and then leaves the field. Changes the state of a radio button or check box. Clicks a command button.
In this sequence, the following actions occur: 1. The Component Processor performs standard system edits. To reduce trips to the server, some processing must be done locally on the machine where the browser is located, while some is performed on the server. Standard system edits can be done either in the browser, utilizing local JavaScript code, or on the application server. The following table outlines where these system edits are done.
System Edits Checking data type Formatting Updating current or history record Effective date Effective date or sequence New effective date in range Duplicate key Location of Execution Browser Application server or browser Application server Application server Application server Application server Application server
Current level is not effective-dated but one of its child Application server scroll areas is Required field Date range Prompt table Translate table Yes/no table Browser Browser Application server Browser Depends on the field type. Browser if the field is a check box. Application server if the field is an edit box and the values are Y or N.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
123
Chapter 6
Note: Default processing for the field can be done in the browser only if the default value is specified as a constant in the record field properties. If the field contains a default, these defaults occur only upon component initialization. Then, if a user replaces a default value with a blank, the field is not initialized again. The required fields check is not performed on derived work fields when you press Tab to move out of a field. If the data fails the system edits, the Component Processor displays an error message and highlights the field in the system color for errors (usually red). 2. If the field passes the system edits, Component Processor initiates the FieldEdit PeopleCode event, which triggers any FieldEdit PeopleCode associated with the record field or the component record field. This enables you to perform additional data validation in PeopleCode. If an Error statement is called in any FieldEdit PeopleCode, the Component Processor treats the error as it does a system edit failure; a message is displayed, and the field is highlighted. If a Warning statement is executed in any FieldEdit PeopleCode, a warning message appears, alerting the user to a possible problem, but the system accepts the change to the field. 3. If the field change is accepted, the Component Processor writes the change to the component buffer, then initiates the FieldChange event, which triggers any FieldChange PeopleCode associated with the record field or the component record field. This event enables you to add processes other than validation initiated by the changed field value, such as changes to page appearance or recalculation of values in other page fields. An Error or Warning statement in any FieldChange PeopleCode causes a runtime error. Important! Do not use Error or Warning statements in FieldChange PeopleCode. All data validation should be performed in FieldEdit PeopleCode. After FieldChange processing, Component Processor runs default processing on all page fields, then redisplays the page. If the user has changed the field value to a blank, or if SetDefault or a related
124
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
function is executed, and the changed field has a default value specified in the record field definition or any FieldDefault PeopleCode, the field is initialized again to the default value. Image: Logic of field modification processing The following flowchart shows the logic of field modification processing in a Page.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
125
Chapter 6
In either case, the Component Processor performs these actions: 1. Inserts a new row of data into the active scroll area. If the scroll area has a dependent scroll area, the system inserts a single new row into the blank scroll area, and the system continues until it reaches the lowest-level scroll area. 2. Initiates the RowInsert PeopleCode event, which triggers any RowInsert PeopleCode associated with the record field or the component record. This event processes fields only on the inserted row and any dependent rows that were inserted on lower-level scroll areas. 3. Runs default processing on all component fields. Normally this affects only the inserted row fields and fields on dependent rows, because other rows already have undergone default processing. 4. Initiates the RowInit PeopleCode event, which triggers any RowInit PeopleCode associated with the record field or the component record. This event affects fields only on the inserted row and any dependent rows that were inserted. 5. Redisplays the page and waits for user action.
126
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
Important! Do not use Error or Warning statements in RowInsert PeopleCode. All data validation should be performed in FieldEdit or SaveEdit PeopleCode. Image: Logic of row insert processing The following flowchart shows the logic of row insert processing where in a PeopleCode RowInsert function or a InsertRow method requests a row insert.
Note: If none of the data fields in the new row are changed after the row has been inserted (either programmatically or by the user), the new row is not inserted into the database when the page is saved.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
127
Chapter 6
In either case, these actions occur: 1. The Component Processor initiates the RowDelete PeopleCode event, which triggers RowDelete PeopleCode associated with the record field or the component record. This event processes fields on the deleted row and any dependent child scroll areas. RowDelete PeopleCode enables you to check for conditions and control whether a user can delete the row. An Error statement displays a message and prevents the user from deleting the row. A Warning statement displays a message alerting the user about possible consequences of the deletion, but permits deletion of the row. 2. If the deletion is rejected, the page is redisplayed after the error message. 3. If the deletion is accepted, the row, and any child scroll areas dependent on the row, are flagged as deleted. The row no longer appears in the page, but it is not physically deleted from the buffer and can be accessed by PeopleCode all the way through the SavePostChange event (note, however, that SaveEdit PeopleCode is not run on deleted rows). 4. The Component Processor runs default processing on all component fields. 5. The Component Processor redisplays the page and waits for a user action
128
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
Note: PeopleCode programs are triggered on rows flagged as deleted in SavePreChange and SavePostChange PeopleCode. Use the IsDeleted row class property to test whether a row has been flagged as deleted. You can also access rows flagged as deleted by looping through the rows of a scroll area using a For loop delimited by the value returned by the RowCount rowset property. Image: Logic of row delete processing The following flowchart shows the logic of row delete processing.
Related Links
"IsDeleted (PeopleTools 8.53: PeopleCode API Reference)" "RowCount (PeopleTools 8.53: PeopleCode API Reference)" "For (PeopleTools 8.53: PeopleCode Language Reference)"
Buttons
When a user presses a button, this initiates the same processing as changing a field. Typically, PeopleCode programs started by button are placed in the FieldChange event.
Related Links
Field Modification
Prompts
If the Allow Search Events for Prompt Dialogs checkbox is selected for the Record Field properties for a search key on a prompt table record, the search processing events are enabled for that field. When the
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
129
Chapter 6
user selects the prompt icon, the SearchInit event for that field executes before the search dialog displays. When the user selects the Look Up button on a prompt dialog the SearchSave event for the field executes. Search event processing on prompt dialogs can affect performance. Oracle recommends that you limit the use of search events in prompt dialogs to simple tasks such as showing and hiding fields or character manipulation. Do not use the search events on prompt dialogs for complex functions such as AddKeyListItem, ClearKeyList, ClearSearchDefault, ClearSearchEdit, IsSearchDialog, SetSearchDefault, SetSearchDialogBehavior, or SetSearchEdit, and so on. By default, Allow Search Events for Prompt Dialogs is off, in which case no PeopleCode event is initiated as a result of prompts. No PeopleCode events are initiated as a result of the user returning to the search page or displaying a calendar. This process is controlled automatically by the system. Note: When the value of a field is changed using a prompt, the standard field modification processing occurs.
Related Links
"Setting Record Field Use Properties (PeopleTools 8.53: PeopleSoft Application Designer Developer's Guide)" Field Modification Search Processing in Update Modes
130
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
operate on that pop-up menu resides in the record field that is attached to the first column in the grid. It does not matter if the first field is visible or hidden. Image: Logic of PrePopup even processing The following flowchart shows the logic of PrePopup event processing, which enables the user to disable, check, or hide menu items in the pop-up menu.
Save Processing
A user can direct the system to save a component by clicking Save or by pressing Alt+1. An application can prompt the user to save a component when the Next or List button is clicked, or when a new action or component is selected. If the user clicks Save after being prompted, save processing begins. The following actions occur in save processing:
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
131
Chapter 6
1. The Component Processor initiates the SaveEdit PeopleCode event, which triggers any SaveEdit PeopleCode associated with a record field or a component record. This enables you to cross-validate page fields before saving, checking consistency among the page field values. An Error statement in SaveEdit PeopleCode displays a message and then redisplays the page, stopping the save. A Warning statement enables the user to cancel save processing by clicking Cancel, or to continue with save processing by clicking OK. 2. The Component Processor initiates the SavePreChange event, which triggers any SavePreChange PeopleCode associated with a record field, a component record, or a component. SavePreChange PeopleCode enables you to process data after validation and before the database is updated. 3. The Component Processor initiates the Workflow event, which triggers any Workflow PeopleCode associated with a record field or a component. Workflow PeopleCode should be used only for workflow-related processing (TriggerBusinessEvent and related functions). 4. The Component Processor updates the database with the changed component data, performing any necessary SQL Insert, Update, and Delete statements. 5. The Component Processor initiates the SavePostChange PeopleCode event, which triggers any SavePostChange PeopleCode associated with a record field, a component record, or a component. You can use SavePostChange PeopleCode for processing that must occur after the database update, such as updates to other database tables not in the component buffer. 6. The Component Processor issues a SQL Commit statement to the database server. 7. The Component Processor redisplays the component.
132
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
Important! Never use an Error or Warning statement in any save processing event other than SaveEdit. Perform all component data validation in SaveEdit. Image: Logic of save processing The following flow chart shows the logic of save processing sequence.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
133
Chapter 6
If a user changes a field that field has nothing to cause a trip to the server, then default processing and FieldFormula PeopleCode do not run. These processes only run when another event causes a trip to the server. Other fields that depend on the first field using FieldFormula or default PeopleCode are not updated until the next time a server trip occurs.
In applications that run on the PeopleSoft portal, external, dynamic link information must be placed in RowInit PeopleCode. If it is placed in FieldChange PeopleCode, it will not work.
134
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
Clicking a list (performing a search). Clicking a process button. Deferred processing mode affects the appearance of pages in significant ways. For example, related processing is not done when the user presses Tab to move out of a field. Avoid related fields for components that use this mode.
2. Drop-down list box values are static while the page appears in the browser. Drop-down list box values are generated on the application server when generating the HTML for the page. If translate values are used to populate the drop-down list box, and the current record contains an effective date, that date is static while the page is displayed. This means the drop-down list box values may become out of date. If prompt table values are used to populate the drop-down list box, the high-order key field values for the prompt table are static while the page is displayed. This means the drop-down list box values may become out of date. Avoid interdependencies in drop-down lists used on pages executed in deferred mode, because the lists may quickly become out of date. 3. No field modification processing is done during prompt button processing. When the user clicks a prompt button, a trip is made to the application server (if values were not already downloaded) to select the search results from the database and to generate the HTML for the prompt dialog box. During this trip to the application server, field modification processing for the field being prompted is not performed, because this may cause an error message for another field on the page, and this error may confuse the user. When deferred changes are made to other fields, field modification processing for these fields is done before prompting. The field modification for the prompted field is done after returning from the prompt page. While the system displays the page, the high-order key field values for the prompt table should be static or not require field modification processing. Display-only drop-down list box, radio button, and check box fields do not require field modification processing. Field values that do not require field modification processing are temporarily written to the component buffer, without any field modification processing being performed on them, including FieldEdit and FieldChange PeopleCode. The system restores the original state of the page processor before returning to the browser. 4. Field modification processing executes in field layout order. The entire field modification processing sequence executes in field layout order for each field. If a field passes the system edits and FieldEdit PeopleCode, the field value is written to the component buffer. If an error occurs, field modification processing stops, and the system generates new HTML for the page, with the field in error highlighted and sent to the browser. 5. PeopleCode dependencies between fields on the page do not work as expected. Avoid PeopleCode dependencies between fields on pages displayed in deferred processing mode. Also, avoid FieldChange PeopleCode that changes the display.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
135
Chapter 6
The following are examples of PeopleCode dependencies between fields on the page and the application server's action. In the following examples, field A comes before field B, which comes before field C. Field A has FieldChange PeopleCode that hides field B or it makes unavailable for entry. The value in field B of the page that was submitted from the browser is discarded. Field B has FieldChange PeopleCode that hides field A or makes it unavailable for entry. The change made by the user for field A, if any, remains in the component buffer. Field A has FieldChange PeopleCode that changes the value in the component buffer for field B. If the value in field B of the page that was submitted from the browser passes the system edits and FieldEdit PeopleCode, it is written to the component buffer, overriding the change made by field As FieldChange PeopleCode. Field B has FieldChange PeopleCode that changes the value in the component buffer for field A. The change made by field Bs FieldChange PeopleCode overrides the change made by the user to field A, if any. Field A has FieldChange PeopleCode that unhides field B or makes it available for entry. Field B has the value that was already in the component buffer. If the user requests a different page or finishes, the user may not have the opportunity to enter a value into field B, and therefore the value may not be correct. Field B has FieldChange PeopleCode that changes the value in the component buffer for field A, but field C has FieldChange PeopleCode that hides field B or makes it unavailable for entry. The change made by field Bs FieldChange PeopleCode, a field that is now hidden or unavailable for entry, overrides the change made by the user to field A, if any. Avoid such dependencies by moving FieldChange PeopleCode logic from individual fields to save processing for the component or FieldChange PeopleCode on a PeopleCode command button. 6. Not all buttons cause field modification processing to execute. External links, list (search), and process buttons do not cause field modification processing to execute. 7. You can use a PeopleCode command button to cause field modification processing to execute. An application can include a button for the sole purpose of causing field modification processing to execute. The result is a new page showing any display changes that resulted from field modification processing. In addition, if the user clicks the Refresh button, or presses Alt + 0, deferred processing is executed. Note: The Refresh button does not refresh the page from the database. It simply causes a server trip so any deferred PeopleCode changes get processed. If the page has no deferred changes or the deferred changes do not cause any errors or other changes on the page, it may appear to the user as if nothing happened.
136
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
PeopleCode Events
This section discusses: Activate event. FieldChange event. FieldDefault event. FieldEdit event. FieldFormula event. ItemSelected event. PostBuild event. PreBuild event. PrePopup event. RowDelete event. RowInit event. RowInsert event. RowSelect event. SaveEdit event. SavePostChange event. SavePreChange event. SearchInit event. SearchSave event. Workflow event.
Note: The term PeopleCode type is still frequently used, but it does not fit into the PeopleTools objectbased, event-driven metaphor. The term PeopleCode event should now be used instead. However, its often convenient to qualify a class of PeopleCode programs triggered by a specific event with the event name; for example, PeopleCode programs associated with the RowInit events are collectively referred to as RowInit PeopleCode.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
137
Chapter 6
Activate Event
The Activate event is initiated each time that a page is activated, including when a page is first displayed by a user, or if a user presses Tab between different pages in a component. Each page has its own Activate event. Activate PeopleCode associated with a popup page execut after the page activate event for the main page. When fields on the main page change and trigger updates on the popup page the page activate event for the popup page is executed. The Activate event segregates PeopleCode that is related to a specific page from the rest of the applications PeopleCode. Place PeopleCode related to page display or page processing, such as enabling a field or hiding a scroll area, in this event. Also, you can use this event for security validation: if an user does not have clearance to view a page in a component, you would put the code for hiding the page in this event. Note: PeopleSoft builds a page grid one row at a time. Because the Grid class applies to a complete grid, you cannot attach PeopleCode that uses the Grid class to events that occur before the grid is built; the earliest event you can use is the Activate event. The Activate event is not associated with a specific row and record at the point of execution. This means you cannot use functions such as GetRecord, GetRow, and so on, which rely on context, without specifying more context. Activate PeopleCode can only be associated with pages. This event is valid only for pages that are defined as standard or secondary. This event is not supported for subpages. Note: If your application uses the MessageBox built-in function in the Activate event with a message from the message catalog that's defined as type Error, Warning or Cancel, all component processing stops with an error message to that effect. If the message has a type of Message, processing does not stop.
Related Links
Component Build Processing in Update Modes Component Build Processing in Add Modes
FieldChange Event
Use FieldChange PeopleCode to recalculate page field values, change the appearance of page controls, or perform other processing that results from a field change other than data validation. To validate the contents of the field, use the FieldEdit event. See FieldEdit Event. The FieldChange event applies to the field and row that just changed. FieldChange PeopleCode is often paired with RowInit PeopleCode. In these RowInit/FieldChange pairs, the RowInit PeopleCode checks values in the component and initializes the state or value of page controls accordingly. FieldChange PeopleCode then rechecks the values in the component during page execution and resets the state or value of page controls. To take a simple example, suppose you have a derived/work field called PRODUCT, the value of which is always the product of page field A and page field B. When the component is initialized, you would
138
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
use RowInit PeopleCode to initialize PRODUCT equal to A B when the component starts up or when a new row is inserted. You could then attach FieldChange PeopleCode programs to both A and B which also set PRODUCT equal to A B. Whenever a user changes the value of either A or B, PRODUCT is recalculated. FieldChange PeopleCode can be associated with record fields and component record fields.
Related Links
Field Modification
FieldDefault Event
The FieldDefault PeopleCode event enables you to programmatically set fields to default values when they are initially displayed. This event is initiated on all page fields as part of many different processes; however, it triggers PeopleCode programs only when the following conditions are all True: The page field is still blank after applying any default value specified in the record field properties. This is True if there is no default specified, if a null value is specified, or if a 0 is specified for a numeric field. The field has a FieldDefault PeopleCode program.
In practice, FieldDefault PeopleCode normally sets fields by default when new data is being added to the component; that is, in Add mode and when a new row is inserted into a scroll area. If a field value is changed, whether through PeopleCode or by a user, the IsChanged property for the row is set to True. The exception to this is when a change is done in the FieldDefault or FieldFormula events. If a value is set in FieldDefault or FieldFormula, the row is not marked as changed. At save time, all newly inserted and changed rows are written to the database. All newly inserted but not changed rows are not written to the database. You must attach FieldDefault PeopleCode to the field where the default value is being populated. Note: An error or warning issued from FieldDefault PeopleCode causes a runtime error. FieldDefault PeopleCode can be associated with record fields and component record fields.
Related Links
Default Processing
FieldEdit Event
Use FieldEdit PeopleCode to validate the contents of a field, supplementing standard system edits. If the data does not pass the validation, the PeopleCode program should display a message using the Error statement, which redisplays the page, displaying an error message and turning the field red. To permit the field edit but alert the user to a possible problem, use a Warning statement instead of an Error statement. A Warning statement displays a warning dialog box with OK and Explain buttons. It permits field contents to be changed and continues processing as usual after the user clicks OK.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
139
Chapter 6
If the validation must check for consistency across page fields, then use SaveEdit PeopleCode instead of FieldEdit. The FieldEdit event applies to the field and row that just changed. FieldEdit PeopleCode can be associated with record fields and component record fields.
Related Links
Field Modification
FieldFormula Event
The FieldFormula event is not currently used. Because FieldFormula PeopleCode initiates in many different contexts and triggers PeopleCode on every field on every row in the component buffer, it can seriously degrade application performance. Use RowInit and FieldChange events rather than FieldFormula. If a field value is changed, whether through PeopleCode or by a user, the IsChanged property for the row is usually set to True. However, if a value is set in FieldDefault or FieldFormula, the row is not marked as changed. At save time, all newly inserted and changed rows are written to the database. All newly inserted but not changed rows are not written to the database. Note: In PeopleSoft Pure Internet Architecture, if a user changes a field but that field has nothing to cause a trip to the server, then default processing and FieldFormula PeopleCode do not run. They only run when another event causes a trip to the server. As a matter of convention, FieldFormula is now often used in FUNCLIB_ (function library) record definitions to store shared functions. However, you can store shared functions in any PeopleCode event. FieldFormula PeopleCode is only associated with record fields.
ItemSelected Event
The ItemSelected event is initiated whenever a user selects a menu item from a pop-up menu. In pop-up menus, ItemSelected PeopleCode executes in the context of the page field from where the pop-up menu is attached, which means that you can freely reference and change page fields, just as you could from a button. Note: This event, and all its associated PeopleCode, does not initiate if run from a component interface. ItemSelected PeopleCode is only associated with pop-up menu items.
Related Links
PostBuild Event
The PostBuild event is initiated after all the other component build events have been initiated. This event is often used to hide or unhide pages. It is also used to set component variables.
140 Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
PreBuild Event
The PreBuild event is initiated before the rest of the component build events. This event is often used to hide or unhide pages. It is also used to set component variables. Note: If a PreBuild PeopleCode program issues an error or warning, the user is returned to the search page. If the search record has no keys, a blank component page appears. Also use the PreBuild event to validate data entered in a search page after a prompt list is displayed. For example, after a user selects key values on a search, the PreBuild PeopleCode program runs, catches the error condition, and issues an error message. The user receives and acknowledges the error message. The component is canceled (because of the error), and the user is returned to the search page. PreBuild PeopleCode is only associated with components.
PrePopup Event
The PrePopup event is initiated just before the display of a pop-up menu. You can use PrePopup PeopleCode to control the appearance of the pop-up menu. Note: This event, and all its associated PeopleCode, does not initiate if run from a component interface. PrePopup PeopleCode can be associated with record fields and component record fields.
Related Links
RowDelete Event
The RowDelete event is initiated whenever a user attempts to delete a row of data from a page scroll area. Use RowDelete PeopleCode to prevent the deletion of a row (using an Error or Warning statement) or to perform any other processing contingent on row deletion. For example, you could have a page field called Total on scroll area level zero whose value is the sum of all the Extension page fields on scroll area level one. If the user deleted a row on scroll area level one, you could use RowDelete PeopleCode to recalculate the value of the Total field. The RowDelete event triggers PeopleCode on any field on the row of data that is being flagged as deleted. Note: RowDelete does not trigger programs on derived/work records. RowDelete PeopleCode can be associated with record fields and component records.
Chapter 6
Related Links
RowInit Event
The RowInit event is initiated the first time that the Component Processor encounters a row of data. Use it to set the initial state of component controls during component build processing and row insert processing. The RowInit event also occurs after a Select or SelectAll Rowset method, or a ScrollSelect or related function, is executed. Note: Generally, if none of the fields in the new row are changed after the row is inserted (either by a user pressing Alt+7 or programmatically) when the page is saved, the new row is not inserted into the database. However, if the ChangeOnInit rowset class property is set to False, you can set values for fields a new row in RowInsert or RowInit PeopleCode, and the row will not be saved. RowInit is not field-specific. It triggers PeopleCode on all fields and on all rows in the component buffer. Do not use Error or Warning statements in RowInit PeopleCode. They cause a runtime error. RowInit PeopleCode is often paired with FieldChange PeopleCode. In these RowInit/FieldChange pairs, the RowInit PeopleCode checks values in the component and initializes the state or value of page controls accordingly. FieldChange PeopleCode then rechecks the values in the component during page execution and resets the state or value of page controls. For a simple example, suppose you have a derived/work field called PRODUCT, the value of which is always the product of page field A and page field B. When the component is initialized, use RowInit PeopleCode to initialize PRODUCT equal to A B when the component starts up or when a new row is inserted. You could then attach FieldChange PeopleCode programs to both A and B, which also sets PRODUCT equal to A B. Whenever a user changes the value of either A or B, PRODUCT is recalculated. RowInit PeopleCode can be associated with record fields and component records.
RowInit Exceptions
In certain rare circumstances, the Component Processor does not run RowInit PeopleCode for some record fields. The Component Processor runs RowInit PeopleCode when it loads the record from the database. However, in some cases, the record can be initialized entirely from the keys for the component. When this happens, RowInit PeopleCode is not run. For RowInit to not run, the following must all be True: The record is at level zero. Every record field that is present in the data buffers is also present in the keys for the component. The Component Processor determines if the field is required by the component. In practice, this usually means that the field is associated with a page field, possibly hidden, for some page of the component. It could also mean that the field is referenced by some PeopleCode program that is attached to an event on some other field of the component.
142
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
RowInit not running is not considered to be an error. The purpose of RowInit PeopleCode is to complete initialization of data on the row after it has been read from the database. Because the data in this special circumstance is coming from the keylist, it was already initialized correctly by whatever processing produced the keylist. More general initialization of the component should be done in PostBuild PeopleCode, not RowInit.
Related Links
Component Build Processing in Add Modes "ChangeOnInit (PeopleTools 8.53: PeopleCode API Reference)"
RowInsert Event
When a user adds a row of data, the Component Processor generates a RowInsert event. You should use RowInsert PeopleCode for processing specific to the insertion of new rows. Do not put PeopleCode in RowInsert that already exists in RowInit, because a RowInit event always initiates after the RowInsert event, which will cause your code to be run twice. Note: Generally, if none of the fields in the new row are changed after the row has been inserted (either by a user pressing Alt+7 or programmatically), when the page is saved, the new row is not inserted into the database. However, if the ChangeOnInit rowset class property is set to False, you can set values for fields a new row in RowInsert or RowInit PeopleCode, and the row won't be saved. The RowInsert event triggers PeopleCode on any field on the inserted row of data. Do not use a warning or error in RowInsert.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
143
Chapter 6
You can prevent a user from inserting rows into a scroll area by selecting the No Row Insert check box in the scroll bars page field properties, as shown in the following illustration. However, you cannot prevent row insertion conditionally. Image: Setting row insert properties in page field properties for a scroll bar This example illustrates the fields and controls on the Setting row insert properties in page field properties for a scroll bar. You can find definitions for the fields and controls later on this page.
Note: RowInsert does not trigger PeopleCode on derived/work fields. RowInsert PeopleCode can be associated with record fields and component records.
Related Links
144
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
RowSelect Event
The RowSelect event is initiated at the beginning of the component build process in any of the update action modes (Update, Update/Display All, Correction). RowSelect PeopleCode is used to filter out rows of data as they are being read into the component buffer. This event also occurs after a ScrollSelect or related function is executed. A DiscardRow function in RowSelect PeopleCode causes the Component Processor to skip the current row of data and continue to process other rows. A StopFetching statement causes the Component Processor to accept the current row of data, and then stop reading additional rows. If both statements are executed, the program skips the current row of data, and then stops reading additional rows. PeopleSoft applications rarely use RowSelect, because it's inefficient to filter out rows of data after they've already been selected. Instead, screen out rows of data using search record views and effectivedated tables, which filter out the rows before they're selected. You could also use a ScrollSelect or related function to programmatically select rows of data into the component buffer. In previous versions of PeopleTools, the Warning and Error statements were used instead of DiscardRow and StopFetching. Warning and Error statements still work as before in RowSelect, but their use is discouraged. Note: In RowSelect PeopleCode, you can refer to record fields only on the record that is currently being processed. This event, and all its associated PeopleCode, does not initiate if run from a component interface. RowSelect PeopleCode can be associated with record fields and component records.
Related Links
SaveEdit Event
The SaveEdit event is initiated whenever a user attempts to save the component. You can use SaveEdit PeopleCode to validate the consistency of data in component fields. Whenever a validation involves more than one component field, you should use SaveEdit PeopleCode. If a validation involves only one page field, use FieldEdit PeopleCode. SaveEdit is not field-specific. It triggers associated PeopleCode on every row of data in the component buffers except rows flagged as deleted. An Error statement in SaveEdit PeopleCode displays a message and redisplays the component without saving data. A Warning statement enables the user to click OK and save the data, or to click Cancel and return to the component without saving. Use the SetCursorPos function to set the cursor position to a specific page field following a warning or error in SaveEdit, to show the user the field (or at least one of the fields) that is causing the problem. Make sure to call SetCursorPos before the error or warning, because these may terminate the PeopleCode program. SaveEdit PeopleCode can be associated with record fields and components.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
145
Chapter 6
Related Links
SavePostChange Event
After the Component Processor updates the database, it initiates the SavePostChange event. You can use SavePostChange PeopleCode to update tables not in your component using the SQLExec built-in function. An error or warning in SavePostChange PeopleCode causes a runtime error. Avoid errors and warnings in this event. The system issues a SQL Commit statement after SavePostChange PeopleCode completes successfully. If you are executing Workflow PeopleCode, keep in mind that if the Workflow PeopleCode fails, SavePostChange PeopleCode is not executed. If your component has both Workflow and SavePostChange PeopleCode, consider moving the SavePostChange PeopleCode to SavePreChange or Workflow. If you are doing messaging, your Publish PeopleCode should go into this event. SavePostChange does not execute if there is an error during the save. For example, if there is a data conflict error because another user updated the same data at the same time, SavePostChange does not execute. Important! Never issue a SQL Commit or Rollback statement manually from within a SQLExec function. Let the Component Processor issue these SQL commands. SavePostChange PeopleCode can be associated with record fields, components, and component records.
Related Links
SavePreChange Event
The SavePreChange event is initiated after SaveEdit completes without errors. SavePreChange PeopleCode provides one final opportunity to manipulate data before the system updates the database; for instance, you could use SavePreChange PeopleCode to set sequential high-level keys. If SavePreChange runs successfully, a Workflow event is generated, and then the Component Processor issues appropriate Insert, Update, or Delete SQL statements. SavePreChange PeopleCode is not field-specific: it triggers PeopleCode on all fields and on all rows of data in the component buffer. SavePreChange PeopleCode can be associated with record fields, components, and component records.
Related Links
Save Processing
146
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
SearchInit Event
The SearchInit event is generated just before a search, add, or data-entry dialog box is displayed. SearchInit triggers associated PeopleCode in the search key fields of the search record. This enables you to control processing before a user enters values for search keys in the dialog box. In some cases, you may want to set the value of the search dialog fields programmatically. For example, the following program in SearchInit PeopleCode on the component search key record field EMPLID sets the search key page field to the users employee ID, makes the page field unavailable for entry, and enables the user to modify the users own data in the component:
EMPLID = %EmployeeId; Gray (EMPLID); AllowEmplIdChg(True);
You can activate system defaults and system edits in the search page by calling SetSeachDefault and SetSearchEdit in SearchInit PeopleCode. You can also control the behavior of the search page, either forcing it to appear even if all the required keys have been provided, or by skipping it if possible, with the SetSeachDialogBehavior function. You can also force search processing to always occur by selecting the Force Search Processing check box in the component properties in PeopleSoft Application Designer. Note: This event, and all its associated PeopleCode, does not initiate if run from a component interface. SearchInit PeopleCode can be associated with record fields on search records and prompt table records and on component search records and component prompt table records.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
147
Chapter 6
Related Links
Prompts "SetSearchDefault (PeopleTools 8.53: PeopleCode Language Reference)" Search Processing in Update Modes Search Processing in Add Modes
SearchSave Event
SearchSave PeopleCode is executed for all search key fields on a search, add, or data-entry dialog box after a user clicks Search. This enables you to control processing after search key values are entered, but before the search based on these keys is executed. A typical use of this feature is to provide cross-field edits for selecting a minimum set of key information. This event is also used to force a user to enter a value in at least one field, even if its a partial value, to help narrow a search for tables with many rows. Note: SearchSave is not initiated when values are selected from the search list. To validate data entered in the search page, use the Component PreBuild event. You can use Error and Warning statements in SearchSave PeopleCode to send the user back to the search page if the user entry does not pass validations implemented in the PeopleCode. Note: This event, and all its associated PeopleCode, is not initiated if run from a component interface. SearchSave PeopleCode can be associated with record fields and component search records. Note: Do not use the %Menu system variable in this event. You may get unexpected results.
Related Links
Workflow Event
Workflow PeopleCode executes immediately after the SavePreChange event and before the database update that precedes the SavePostChange event. The Workflow event segregates PeopleCode related to workflow from the rest of the applications PeopleCode. Only PeopleCode related to workflow (such as TriggerBusinessEvent) should be in workflow programs. Your program should deal with the Workflow event only after any SavePreChange processing is complete.
148
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 6
Workflow PeopleCode is not field-specific: it triggers PeopleCode on all fields and on all rows of data in the component buffer. WorkFlow PeopleCode can be associated with record fields and components.
Related Links
Related Links
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
149
Chapter 7
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
151
Chapter 7
Each trip to the server results in the page being completely refreshed on the browser, which may cause the display to flicker. It can also slow down your application. Deferred processing mode results in better performance.
Related Links
Related Links
152
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 7
Image: Field with PSHYPERLINK style The following examples show the fields with different styles:
Image: Field with PSIMAGE style The below mentioned is an image of a field with PSIMAGE style.
Related Links
PeopleTools 8.53: PeopleSoft Application Designer Developer's Guide PeopleTools 8.53: PeopleCode API Reference
The following code is in the FieldChange event of a button. It populates an HTML area (associated with the record field CHART_DATA.HTMLAREA) with a simple list.
Local Field &HTMLField; &HTMLField = GetRecord(Record.CHART_DATA).HTMLAREA; &HTMLField.Value = "<ul><li>Item one</li><li>Item two</li></ul>";
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
153
Chapter 7
The following code populates an HTML area (associated with the record DERIVED_HTML and the field HTMLAREA) with the output of the GenerateTree function:
DERIVED_HTML.HTMLAREA = GenerateTree(&TREECTL);
The following tags are unsupported by the HTML area control: Body Frame Frameset Form Head HTML Meta Title
Related Links
Using the GenerateTree Function PeopleTools 8.53: PeopleSoft Application Designer Developer's Guide
This HTML is saved to an HTML definition called TABLE_HTML. This code is in the RowInit event of the record field associated with the HTML area control:
Local Field &HTMLField; &HTMLField = GetField(); &string = GetHTMLText(HTML.TABLE_HTML); &HTMLField.Value = &string;
154
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 7
This code produces the following: Image: HTML definition example This example illustrates the fields and controls on the HTML definition example. You can find definitions for the fields and controls later on this page.
Related Links
Related Links
"GetJavaScriptURL (PeopleTools 8.53: PeopleCode API Reference)" PeopleTools 8.53: PeopleSoft Application Designer Developer's Guide
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
155
Chapter 7
For all the other PeopleTools-supported UNIX platforms, the functions from the UNIX shared libraries can be used directly. To maintain backward compatibility, the interface functions are also supported on these UNIX platforms. In the following sample test program, the interface function is compiled only when compiling for the specified non-Windows environments.
/* * Simple test function for calling from PeopleCode. * This is passed two strings, a file name and a message. * It creates the specified file and writes the message * to it. */ #include <stdlib.h> #include <stdio.h> #include <string.h>
156
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 7
#ifdef _WINDOWS #define DLLEXPORT __declspec(dllexport) #define LINKAGE __stdcall #else #define DLLEXPORT #define LINKAGE #endif DLLEXPORT int LINKAGE LogMsg(char * fname, char * msg); /******************************************************** * PeopleCode External call test function. * * * * Parameters are two strings (filename and message) * * Result is 0 if error, 1 if OK * * * * * * To call this function, the following PeopleCode is * * used * * * * Declare Function LogMsg Library "testdll" * * (string, string) * * Returns integer; * * * * &res = LogMsg("\temp\test.log", "This is a test"); * * * ********************************************************/ DLLEXPORT int LINKAGE LogMsg(char * fname, char * msg) { FILE *fp; fp = fopen(fname, "a"); if (fp == NULL) return 0; fprintf(fp, "%s\n", msg); fclose(fp); return 1; /* append */
#ifndef _WINDOWS /******************************************************** * Interface function. * * * * This is not needed for Windows.... * * * ********************************************************/ #include #include "pcmext.h" "assert.h"
/* This interface function is required only for the following platforms: - HP-UX Itanium - Solaris x86_64 - z/Linux */ void LogMsg_intf(int nParam, void ** ppParams, EXTPARAMDESC * pDesc) { int rc; /* Some error checking */ assert(nParam == 2); assert(pDesc[0].eExtType == EXTTYPE_STRING && pDesc[1].eExtType == EXTTYPE_STRING && pDesc[2].eExtType == EXTTYPE_INT); rc = LogMsg((char *)ppParams[0],
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
157
Chapter 7
158
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 8
Related Links
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
159
Chapter 8
SearchInit PeopleCode function restrictions. CallAppEngine function. ReturnToServer function. GetPage function. GetGrid function. Publish method. SyncRequest method.
Think-Time Functions
Think-time functions suspend processing either until the user has taken some action (such as clicking a button in a message box) or until an external process has run to completion (for example, a remote process). Avoid think-time functions in the following PeopleCode events: SavePreChange. Workflow. RowSelect. SavePostChange. Any PeopleCode event that executes as a result of a ScrollSelect, ScrollSelectNew, RowScrollSelect, or RowScrollSelectNew function call. Any PeopleCode event that executes as a result of a Rowset class Select or SelectNew method.
Violation of this rule can result in application failure. The following are think-time functions: Calls to an external DLL. DoCancel. DoModal and DoModalComponent. Exec (this is think-time only when synchronous). File attachment functions AddAttachment, DetachAttachment, MAddAttachment, and ViewAttachment. CropImage and InsertImage. Object functions, such as CreateObject, ObjectDoMethod, ObjectSetProperty, and ObjectGetProperty (these are think-time only when the object requires user action). Prompt.
160
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 8
RemoteCall. RevalidatePassword. WinExec (think-time only when synchronous). WinMessage and MessageBox (depending on the style parameter).
Note: The WinMessage function is supported for compatibility with previous releases of PeopleTools. New applications should use MessageBox instead. If the style parameter specifies more than one button, the function behaves as a think-time function and is subject to the same restrictions as other think-time functions (that is, it should never be used from SavePreChange through SavePostChange PeopleCode, or in RowSelect). If the style parameter specifies a single button (that is, the OK button), then the function can be called in any PeopleCode event. Note: In the Microsoft Windows client, MessageBox dialog boxes include an Explain button to display more detailed information stored in the message catalog. The presence of the Explain button has no bearing on whether a message box behaves as a think-time function. The style parameter is optional in WinMessage. If style is omitted, WinMessage displays OK and Cancel buttons, which causes the function to behave as a think-time function. To avoid this situation, always pass an appropriate value in the WinMessage style parameter. The following table shows the values that can be passed in the style parameter. To calculate the value to pass, make one selection from each category in the table, then add the selections.
Category Buttons Buttons Value 0 1 Constant %MsgStyle_OK %MsgStyle_OKCancel Meaning The message box contains one button: OK. The message box contains two buttons: OK and Cancel.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
161
Chapter 8
Category Buttons
Value 2
Meaning The message box contains three buttons: Abort, Retry, and Ignore. The message box contains three buttons: Yes, No, and Cancel. The message box contains two buttons: Yes and No. The message box contains two buttons: Retry and Cancel.
Buttons
Buttons Buttons
4 5
%MsgStyle_YesNo %MsgStyle_RetryCancel
Note: The following values for style can only be used in the Microsoft Windows client. They have no affect in PeopleSoft Pure Internet Architecture.
Category Default Button Default Button Default Button Icon Icon Icon Value 0 256 512 0 16 32 Constant %MsgDefault_First %MsgDefault_Second %MsgDefault_Third %MsgIcon_None %MsgIcon_Error %MsgIcon_Query Meaning The first button is the default. The second button is the default. The third button is the default. None A stop-sign icon appears in the message box. A question-mark icon appears in the message box. An exclamation-point icon appears in the message box. An icon consisting of a lowercase letter i in a circle appears in the message box.
Icon
48
%MsgIcon_Warning
Icon
64
%MsgIcon_Info
Related Links
162
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 8
After the call to the invalid field, execution skips to the next top-level statement. Top-level statements are not nested inside other statements. The start of a PeopleCode program is a top-level statement. Nesting begins with the first conditional statement (such as While or If) or the first function call. For example, if your code is executing in a function and inside an If then end-if statement, and it runs into the skip conditions, the next statement executed is the one after the End-if statement, still inside the function.
Related Links
"Warning (PeopleTools 8.53: PeopleCode Language Reference)" "Error (PeopleTools 8.53: PeopleCode Language Reference)"
DoSave Function
DoSave can be used in the following PeopleCode events only: FieldEdit, FieldChange, or ItemSelected (for menu items in popup menus only).
Related Links
Only use these methods in the following events (events that allow database updates):
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
163
Chapter 8
Related Links
164
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 8
When executed using a component interface, these functions do nothing and return a default value. In addition, using the Transfer function terminates the current PeopleCode program. For the unsupported functions, you should put a condition around them, testing whether theres an existing Component Interface.
If %ComponentName Then /* process is being called from a Component Interface */ /* do CI specific processing */ Else /* do regular processing */ . . . End-if;
Related Links
CallAppEngine Function
Use the CallAppEngine function only in events that allow database updates, because, generally, if you are calling Application Engine, you intend to perform database updates. This category of events includes the following PeopleCode events: SavePreChange (Page) SavePostChange (Page) Workflow FieldChange
CallAppEngine cannot be used in a Application Engine PeopleCode action. If you need to access one Application Engine program from another Application Engine program, use the CallSection action.
Related Links
ReturnToServer Function
The ReturnToServer function returns a value from a PeopleCode application messaging program to the publication or subscription server. You would use this in either your publication or subscription routing code, not in one of the standard Component Processor events.
Related Links
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
165
Chapter 8
GetPage Function
The GetPage function cannot be used until after the Component Processor has loaded the page. You should not use this function in an event prior to the PostBuild event.
Related Links
PeopleTools 8.53: PeopleCode Developers Guide "GetPage (PeopleTools 8.53: PeopleCode Language Reference)"
Related Links
PeopleTools 8.53: PeopleCode Developers Guide "GetGrid (PeopleTools 8.53: PeopleCode Language Reference)" PeopleTools 8.53: PeopleCode API Reference
Publish Method
If you are using PeopleSoft Integration Broker, your sending PeopleCode should go in the SavePostChange event, for either the record or the component.
Related Links
SyncRequest Method
If you are using PeopleSoft Integration Broker, your SyncRequest PeopleCode should go in the SavePostChange event, for either the record or the component.
Related Links
166
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 8
Modal transfers provide some control over the order in which the user fills in pages, which is useful where data in the originating component can be derived from data entered by the user into the modal component. Limit use of this feature, as it forces users to complete interaction with the modal page before returning to the main component. Note: Modal transfers cannot be initiated from SearchInit PeopleCode. A modal component resembles a Microsoft Windows modal dialog box. It displays three buttons: OK, Cancel, and Apply. No toolbars or windows are available while the modal component has the focus. The OK button saves changes to the modal component and returns the user to the originating component. The Apply button saves changes to the modal component without returning to the originating component. The Cancel button returns the user to the originating component without saving changes to the modal component. Modal components are generally smaller than the page from which they are invoked. Remember that OK and Cancel buttons are added at runtime, thus increasing the size of the pages. The originating component and the modal component share record fields in a derived/work record called a shared work record. The derived/work fields of this record provide the two components with an area in memory where they can share data. Edit boxes in both components are associated with the same derived/ work field, so that changes made to this field in the originating component are reflected in the modal component, and vice versa. The following diagram illustrates this shared memory: Image: Edit boxes on the originating and modal components share the same data The following diagram explains that the Edit boxes on the originating and modal components share the same data.
Edit boxes associated with the same derived/work fields must be placed at level zero in both the originating component and the modal component. You can use the shared fields to: Pass values assigned to the search keys in the modal component search record. If these fields are missing or invalid, the search page appears, enabling the user to enter search keys. Pass other values from the originating component to the modal component.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
167
Chapter 8
Pass values back from the modal component to the originating component.
You also might assign these values in the same program where DoModalComponent is called. 5. Add PeopleCode to access and change the derived/work fields in the modal component.
168
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 8
No PeopleCode is required to pass search key values during the search. However, if other data has been passed to the modal component, you may need PeopleCode to access and use the data. You may also need to assign new values to the shared fields so that they can be used by the originating component. It is possible that the component was accessed through the menu system and not through a modal transfer. To write PeopleCode that runs only in the component when it is running modally, use the IsModalComponent function:
If IsModalComponent() Then /* PeopleCode for modal execution only. End-If */
6. Add PeopleCode to access changed derived/work fields in the originating component. If the modal component has altered the data in the shared work fields, you can write PeopleCode to access and use the data after DoModalComponent has executed. Note: You can use the EndModalComponent function as a programmatic implementation of the OK and Cancel buttons.
Related Links
"DoModalComponent (PeopleTools 8.53: PeopleCode Language Reference)" "IsModal (PeopleTools 8.53: PeopleCode Language Reference)" "EndModalComponent (PeopleTools 8.53: PeopleCode Language Reference)"
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
169
Chapter 8
3. Add ChangeOnInit PeopleCode. Setting the ChangeOnInit property for a rowset to False enables PeopleCode to modify data in the rowset during RowInit and RowInsert events without flagging the rows as changed. This ensures that only user changes cause the affected row to be saved. Note: Each rowset that is referenced by a grid or scroll area with the multi-row feature enabled should have the ChangeOnInit property for the rowset set to False. This includes lower-level rowsets. In addition, this property must be set prior to any RowInsert or RowInit PeopleCode for the affected row. 4. Empty rows at save. After a transaction is saved, any empty rows are discarded before the page is redisplayed to the user. An empty row means that the user did not access the data because PeopleCode or record defaults may have been used to initialize the row for the initial display. Note: PeopleCode save processing (SaveEdit and SavePreChange) PeopleCode executes for all rows in the buffer (including the empty ones). Therefore, SaveEdit and SavePreChange PeopleCode should be coded so that it is executed only if the field contains data, or if the row properties IsNew and IsChanged are both True. An alternative method is adding PeopleCode in the first save program in the component, to explicitly delete any row based on the IsNew and IsChanged properties. If you choose this method, then rows should be deleted from the bottom of the data buffer to the top (last row first).
Related Links
170
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 8
Related Links
Related Links
"Insert (PeopleTools 8.53: PeopleCode API Reference)" PeopleTools 8.53: PeopleCode API Reference
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
171
Chapter 8
Related Links
Chapter 8
The Exec function, unlike WinExec and the OLE functions, is not Microsoft Windows-specific. You can run it on an application server to call an executable on the application server platform, which in PeopleTools release 7 and later can be either Windows NT or UNIX. Important! If you use the WinExec function with its synchronous option, the PeopleCode program (and the PeopleSoft application) remain paused until the called program is complete. If you start a program that waits for user input, such as Notepad, the application appears to hang until the user closes the called program. The synchronous option also imposes limits on the PeopleCode.
Related Links
"Exec (PeopleTools 8.53: PeopleCode Language Reference)" "WinExec (PeopleTools 8.53: PeopleCode Language Reference)"
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
173
Chapter 8
a level two rowset could be the child rowset of a level one rowset. The data contained in a child rowset depends on the row of the parent rowset. When a rowset is selected into, any autoselected child rowsets are also read. The child rowsets are read using a Where clause that filters the rows according to the Where clause used for the parent rowset, using a Subselect. The Select method automatically places child rowsets in the rowset object executing the method under the correct parent row. If it cannot match a child rowset to a parent row, an error occurs. The Select method also accepts an optional SQL string that can contain a Where clause restricting the number of rows selected into the scroll area. The SQL string can also contain an Order By clause, enabling you to sort the rows. The Select and SelectNew methods generate an SQL Select statement at runtime, based on the fields in the select record and the Where clause passed to them in the function call. This gives Select and SelectNew a significant advantage over the SQLExec function: they enable you to change the structure of the select record without affecting the PeopleCode program, unless the field affected is referred to in the Where clause string. This can make the application easier to maintain. Also, if you use one of the meta-SQL constructs or shortcuts in the Where clause, such as %KeyEqual or %List, even if a field has changed, you do not have to change your code. Unlike the ScrollSelect functions, neither Select or SelectNew allow you to operate in turbo mode. Note: In addition to these methods, the SelectByKey record class method enables you to select into a record object. If youre only interested in selecting a single row of data, consider this method instead.
Related Links
The first scrollname must be a child rowset of the rowset object executing the method, the second scrollname must be a child of the first child, and so on. This syntax does the following: Specifies an optional child rowset into which to read the selected rows. Specifies the select record from which to select rows. Passes a string containing a SQL Where clause to restrict the selection of rows or an Order By clause to sort the rows, or both.
174
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 8
If the rowset executing the method is a level zero rowset, and you specify the Select method without specifying any child rowsets with paramlist,, the method reads only a single row, because only one row is allowed at level zero. Note: For developers familiar with previous releases of PeopleCode: In this situation, the Select method is acting like the RowScrollSelect function. If you specify a child rowset in paramlist, the Select method selects from a SQL table or view specified by selrecord into the child rowset specified in paramlist, under the appropriate row of the rowset executing the method. In the following example, rows are selected into a child rowset BUS_EXPENSE_DTL, matching levelone keys, and with the charge amount equal to or exceeding 200, sorting by that amount:
Local Record &REC_EXP; Local Rowset &BUS_EXPENSE_PER; &REC_EXP = GetRecord(RECORD.BUSINESS_EXPENSE_PER; &BUS_EXPENSE_PER = GetRowset(SCROLL.BUS_EXPSNESE_PER); &BUS_EXPENSE_PER.Select(SCROLL.BUS_EXPENSE_DTL, RECORD.BUS_EXPENSE_DTL, "WHERE %KeyEqual(:1) AND EXPENSE_AMT >= 200 ORDER BY EXPENSE_AMT", &REC_EXP);
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
175
Chapter 8
Related Links
176
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 8
Note: Standalone rowsets are not connected to the Component Processor, so there are no database updates when they are manipulated. Delete and insert actions on these types of rowsets are not automatically applied at save time. As with any PeopleTools object, the scope of standalone rowsets can be Local, Global, or Component. Consider the following code:
Local Rowset &MYRS; &MYRS = CreateRowset(RECORD.SOMEREC);
This code creates a rowset with SOMEREC as the level zero record. The rowset is unpopulated. Functionally, it is the same as an array of rows.
Use the Fill method with standalone rowsets, created using the CreateRowset function. Do not use Fill with component buffer rowsets.
After running the previous code segment, &MYRS2 contains that same data as &MYRS1. Both &MYRS1 and &MYRS2 were built using like-named records. To use the CopyTo method where there are no like-named records, you must specify the source and destination records. The following code copies only like-named fields:
Local Rowset &MYRS1, MYRS2; Local String &EMPLID; &MYRS1 = CreateRowset(RECORD.SOMEREC1); &MYRS2 = CreateRowset(RECORD.SOMEREC2);
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
177
Chapter 8
To add a child rowset, suppose the following records describe a relationship. The structure is made up of three records: PERSONAL_DATA BUS_EXPENSE_PER BUS_EXPENSE_DTL
To build rowsets with child rowsets, use code like the following:
Local Rowset &rsBusExp, &rsBusExpPer, &rsBusExpDtl; &rsBusExpDtl = CreateRowset(Record.BUS_EXPENSE_DTL); &rsBusExpPer = CreateRowset(Record.BUS_EXPENSE_PER, &rsBusExpDtl); &rsBusExp = CreateRowset(Record.PERSONAL_DATA, &rsBusExpPer);
Another variation is
&rsBusExp = CreateRowset(Record.PERSONAL_DATA, CreateRowset(Record.BUS_EXPENSE_PER, CreateRowset(Record.BUS_EXPENSE_DTL)));
178
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 8
The following example writes a file using a file layout that contains parent-child records:
Local Local Local Local File &MYFILE; Rowset &rsBusExp, &rsBusExpPer, &rsBusExpDtl; Record &rBusExp, &rBusExpPer, &rBusExpDtl; SQL &SQL1, &SQL2, &SQL3;
&rBusExp = CreateRecord(Record.PERSONAL_DATA); &rBusExpPer = CreateRecord(Record.BUS_EXPENSE_PER); &rBusExpDtl = CreateRecord(Record.BUS_EXPENSE_DTL); &rsBusExp = CreateRowset(Record.PERSONAL_DATA, CreateRowset(Record.BUS_EXPENSE_PER, CreateRowset(Record.BUS_EXPENSE_DTL))); &rsBusExpPer = &rsBusExp.GetRow(1).GetRowset(1); &MYFILE = GetFile("c:\temp\BUS_EXP.out", "W", %FilePath_Absolute); &MYFILE.SetFileLayout(FileLayout.BUS_EXP_OUT); &EMPLID = "8001"; &SQL1 = CreateSQL("%selectall(:1) where EMPLID = :2", &rBusExp, &EMPLID); &SQL2 = CreateSQL("%selectall(:1) where EMPLID = :2", &rBusExpPer, &EMPLID); While &SQL1.Fetch(&rBusExp) &rBusExp.CopyFieldsTo(&rsBusExp.GetRow(1).PERSONAL_DATA); &I = 1; While &SQL2.Fetch(&rBusExpPer) &rBusExpPer.CopyFieldsTo(&rsBusExpPer(&I).BUS_EXPENSE_PER); &J = 1; &SQL3 = CreateSQL("%selectall(:1) where EMPLID = :2 and EXPENSE_PERIOD_DT = :3", &rBusExpDtl, &EMPLID,
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
179
Chapter 8
&rsBusExpPer(&I).BUS_EXPENSE_PER.EXPENSE_PERIOD_DT.Value); &rsBusExpDtl = &rsBusExpPer.GetRow(&I).GetRowset(1); While &SQL3.Fetch(&rBusExpDtl) &rBusExpDtl.CopyFieldsTo(&rsBusExpDtl(&J).BUS_EXPENSE_DTL); &rsBusExpDtl.InsertRow(&J); &J = &J + 1; End-While; &rsBusExpPer.InsertRow(&I); &I = &I + 1; End-While; &MYFILE.WriteRowset(&rsBusExp); End-While; &MYFILE.Close();
10100 10100 10100 00001 00001 10100 10100 10100 00001 00001 00001 00001 00001 00001 00001 00001
Related Links
&rBusExp = CreateRecord(Record.PERSONAL_DATA); &rBusExpPer = CreateRecord(Record.BUS_EXPENSE_PER); &rBusExpDtl = CreateRecord(Record.BUS_EXPENSE_DTL); &rsBusExp = CreateRowset(Record.PERSONAL_DATA, CreateRowset(Record.BUS_EXPENSE_PER, CreateRowset(Record.BUS_EXPENSE_DTL))); &MYFILE = GetFile("c:\temp\BUS_EXP.out", "R", %FilePath_Absolute); &MYFILE.SetFileLayout(FileLayout.BUS_EXP_OUT); &SQL1 = CreateSQL("%Insert(:1)");
180
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 8
&rsBusExp = &MYFILE.ReadRowset(); While &rsBusExp <> Null; &rsBusExp.GetRow(1).PERSONAL_DATA.CopyFieldsTo(&rBusExp); &rsBusExpPer = &rsBusExp.GetRow(1).GetRowset(1); For &I = 1 To &rsBusExpPer.ActiveRowCount &rsBusExpPer(&I).BUS_EXPENSE_PER.CopyFieldsTo(&rBusExpPer); &rBusExpPer.ExecuteEdits(%Edit_Required); If &rBusExpPer.IsEditError Then For &K = 1 To &rBusExpPer.FieldCount &MYFIELD = &rBusExpPer.GetField(&K); If &MYFIELD.EditError Then &MSGNUM = &MYFIELD.MessageNumber; &MSGSET = &MYFIELD.MessageSetNumber; End-If; End-For; Else &SQL1.Execute(&rBusExpPer); &rsBusExpDtl = &rsBusExpPer.GetRow(&I).GetRowset(1); For &J = 1 To &rsBusExpDtl.ActiveRowCount &rsBusExpDtl(&J).BUS_EXPENSE_DTL.CopyFieldsTo(&rBusExpDtl); &rBusExpDtl.ExecuteEdits(%Edit_Required); If &rBusExpDtl.IsEditError Then For &K = 1 To &rBusExpDtl.FieldCount &MYFIELD = &rBusExpDtl.GetField(&K); If &MYFIELD.EditError Then &MSGNUM = &MYFIELD.MessageNumber; &MSGSET = &MYFIELD.MessageSetNumber; End-If; End-For; Else &SQL1.Execute(&rBusExpDtl); End-If; End-For; End-If; End-For; &rsBusExp = &MYFILE.ReadRowset(); End-While; &MYFILE.Close();
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
181
Chapter 8
182
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 8
Related Links
PeopleTools 8.53: PeopleCode Developers Guide "DiscardRow (PeopleTools 8.53: PeopleCode Language Reference)" "StopFetching (PeopleTools 8.53: PeopleCode Language Reference)"
Related Links
"Warning (PeopleTools 8.53: PeopleCode Language Reference)" "Error (PeopleTools 8.53: PeopleCode Language Reference)"
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
183
Chapter 8
Decide between RemoteCall and PeopleSoft Process Scheduler. Modify PeopleSoft Process Scheduler programs to run with RemoteCall.
Related Links
184
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 8
Oracle Tuxedo. Oracle Tuxedo is a message-based transaction monitor for distributed applications. No direct Oracle Tuxedo calls need to be implemented in PeopleCode or remote programs.
PeopleCode Programs
You can execute the RemoteCall function from PeopleCode associated with any Component Processor event except SavePostChange, SavePreChange, Workflow, RowSelect, or in any PeopleCode event resulting from a ScrollSelect or related function call. However, remote programs that change data should not be run as part of a SaveEdit process, because the remote program may complete successfully even though an error occurs later in the save process. To call a remote program that changes data, use FieldChange PeopleCode in a record field associated with a command button, or from a pop-up menu item. Do not use RemoteCall if you expect the remote program to return a large amount of data to the client, because data is passed back only through the parameters of the PeopleCode API. Authorization to run a remote program is like authorization to run a PeopleCode program. Because a remote program is started from PeopleCode, the user has authorization to use the page that executes the PeopleCode. The remote program runs in a different unit of work from the page. A commit is issued by PeopleTools if needed on the client before RemoteCall is called. This means that, by default, the remote program does not know about any database changes unless the page is saved before the program is called. After the remote program starts, it runs to completion and commits or ends before returning to the page. In this way, the remote program and the page do not have locking contention. To ensure that the save has actually been done, use the DoSaveNow built-in function. When using RemoteCall to execute a COBOL program, two types of errors can occur: PeopleTools errors. An error might occur in in the application server domain while processing the remote call. These are treated as hard errors by PeopleCode. An error message box appears, and that PeopleCode program is terminated. In the case of a PeopleTools error, the remote program always either returns a code of zero or terminates with a message due to a system error. Application-specific errors. Any error information specific to the remote application must be passed back in regular data variables, and the application can process these in an application-specific way. If you have a status code on which the application depends, you should initialize it to an invalid value to be sure the COBOL program does return the status code. Because the remote program is executed synchronously, users receive an hourglass icon and cannot do anything in the current window until the remote program completes. They could move to another window and do processing there, or they could open another PeopleSoft window. They cannot cancel the remote program after it starts. If the program does not terminate in a timely fashion (as determined by the RemoteCall timeout set with PeopleSoft Configuration Manager), RemoteCall attempts to terminate the process and returns an error indicating that the program was terminated.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
185
Chapter 8
186
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 8
Use RemoteCall for synchronous processes that complete quickly (transaction processing types of processes).
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
187
Chapter 9
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
189
Chapter 9
To use this function, you must set up a page for displaying the data and populate a standalone rowset with the data to be displayed. Image: HTML tree example The following example shows an HTML tree. This is used to display data in tree format using GenerateTree function.
The positional links at the top of the page (First, Previous, Next, Last, Left, Right) enable the user to navigate around the tree. These links are automatically generated as part of the execution of GenerateTree. When a node is collapsed, a plus sign appears on the node icon, and the node's children are hidden. When a node is expanded, all child nodes appear, and the icon displays a minus sign. Icons without a plus or minus sign are terminal nodes, which have no children and cannot be expanded or collapsed.
Note: The edit box should be invisible, but not display-only. An invisible edit box cannot be seen by the user, but it still has a buffer that can be written to. Page fields that have been specified as invisible do not need to be marked as Modifiable from HTML unless they are located on a page that is not active when GenerateTree is called. For example, if your application calls GenerateTree from one page and then saves the result in a field that is displayed by an HTML area on another page in the component, the associated event field must be marked both Invisible and Modifiable from HTML.
190
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 9
Events are sent to the application from the HTML tree using the invisible field. The events are processed by FieldChange PeopleCode that is attached to the invisible field. This is an example page for an HTML tree: Image: Example of PeopleSoft Application Designer HTML tree page This example illustrates the fields and controls on the Example of PeopleSoft Application Designer HTML tree page. You can find definitions for the fields and controls later on this page.
The large area that is selected in the example is the HTML area that displays the HTML tree. The HTML area is attached to the DERIVED_HTML.HTMLAREA field for this example. The white edit box is the invisible field used to pass events from the HTML tree to the application. It is attached to the DERIVED_HTML.TREECTLEVENT field for this example. The edit box must have a page field name. In this example, the page field name is TREECTLEVENT.
The header record is the level zero record of the HTML tree rowset. It contains options for the HTML tree, such as the name of the collapsed node image, the height of the images, the number of pixels to indent each node, and so on.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
191
Chapter 9
The node record is the level one record of the HTML tree rowset. It contains the tree data and information about the data, such as the dynamic range leaf, the level, and so on. The level one scroll area contains a row for each node or leaf in the tree data. To store additional application data with each node in the tree, you can incorporate the TREECTL_NDE_SBR into a record of your definition and use your record to define the HTML tree rowset. For example, you might want to store application key values with each node record, so that when a user selects a node, you have the data you need to perform the action that you want. This table describes the relevant fields in TREECTL_HDR_SBR:
Field PAGE_NAME PAGE_FIELD_NAME PAGE_SIZE Description Name of the page that contains the HTML area and the invisible field used to process the HTML tree events. Page field name of the invisible field used to process the HTML tree events. Number of nodes or leaves to send to the browser at a time. Set to 0 to send all visible nodes or leaves to the browser. The default value is 0. Number of levels to display on the browser at a time. The default value is 8. Collapsed node image name. The default value is PT_ TREE_COLLAPSED. Expanded node image name. The default value is PT_ TREE_EXPANDED. End node image name. The default value is PT_TREE_ END_NODE. Leaf image name. The default value is PT_TREE_ LEAF. Image width in pixels. All four images need to be the same width. The default value is 15 pixels. Image height in pixels. All four images need to be the same height. The default value is 12 pixels. Number of pixels to indent each level. The default value is 20 pixels. Version of the HTML tree. The default value is 812. Used with the DESCR_IMAGE field in the TREECTL _HDR_SBR record.
192
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 9
STYLECLASSNAME PARENT_FLAG
TREE_LEVEL_NUM LEVEL_OFFSET
DESCR_IMAGE
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
193
Chapter 9
Related Links
In your application, you can check for the following user actions:
Event Tn Description Expand or collapse the node, whichever is the opposite of the previous state. N is the row number of the node in the TREECTL_NODE rowset. Expand the node, but load the children first. The children are loaded in PeopleCode, and then the event is passed to GenerateTree so that the HTML can be generated with the node expanded. N is the row number of the node in the TREECTL_NODE rowset. Display the first page. Display the previous page. Display the next page. Display the last page. Move the display left one level. Move the display to the right one level. Select the node or leaf. N is the row number of the node or leaf in the TREECTL_NODE rowset.
Xn
F P N L Q R Sn
194
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 9
The PostBuild PeopleCode Example program is an example of how to initialize the HTML tree using the Tree classes and load only the root node into the HTML tree rowset. The first time a user expands a node, the direct children of the node are loaded into the HTML tree rowset by the FieldChange PeopleCode Example program, shown in the following section. This chunking functionality enables the HTML tree to support trees of any size with good performance. You cannot simply copy either the PostBuild or FieldChange PeopleCode example programs into your application. You must modify them to make them work with your data. You must make these changes to the PostBuild PeopleCode to initialize HTML trees: 1. Set the PAGE_NAME and PAGE_FIELD_NAME fields. The PAGE_NAME field contains the name of the page that contains the HTML area and the invisible field that processes HTML tree events. The PAGE_FIELD_NAME field is the page field name of the invisible field that is used to process the HTML tree events. Note: The PAGE_FIELD_NAME field is the page field name of the invisible field, not the invisible field name. 2. Set tree-specific variables. The &SET_ID, &USERKEYVALUE, &TREE_NAME, &TREE_DT, and &BRANCH_NAME variables contain specific information about the tree. Set these values to the tree you want to open. In the example PeopleCode that follows, these varaibles are set as follows:
&SET_ID = PSTREEDEFN_VW.SETID; &USERKEYVALUE = ""; &TREE_NAME = PSTREEDEFN_VW.TREE_NAME; &TREE_DT = PSTREEDEFN_VW.EFFDT; &BRANCH_NAME = "";
3. Set the PAGE_SIZE field. If you do not want the page to expand vertically to display the tree, set the PAGE_SIZE to a number of rows that will fit inside the HTML area. If some vertical expansion is okay, but you do not want the page to get too large, set the PAGE_SIZE to whatever value you like. Set the PAGE_SIZE to 0 if you do not care how big the page gets. 4. Set the DISPLAY_LEVELS field to the number of levels that will fit inside the HTML area. If this field is set too large, wrapping may occur. Positional links at the top of the HTML area enable the user to navigate as the tree expands. 5. (Optional) Set the DISPLAY_OPTION field. The default for the DISPLAY_OPTION field is to display both the node name and the description. You can display just the node name or just the description. The values for this field are:
Field Value N D Description Display the name only. Display the description only.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
195
Chapter 9
Field Value B
6. (Optional) Set the STYLECLASSNAME field for the root node. The STYLECLASSNAME field controls the style of the link associated with a node or leaf. The default for the STYLECLASSNAME is PSHYPERLINK. If PSHYPERLINK is not the style you want to use, change this field value to the style you want. 7. Change the last line to assign the output of GenerateTree to the field attached to the HTML area that will display the tree. In the example that follows, the HTML area control is the DERIVED_HTML.HTMLAREA. You must specify the record and field name associated with the HTML area control on your page.
196
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 9
&REC.GetField(Field.EXPANDED_IMAGE).Value = "PT_TREE_EXPANDED"; &REC.GetField(Field.END_NODE_IMAGE).Value = "PT_TREE_END_NODE"; &REC.GetField(Field.LEAF_IMAGE).Value = "PT_TREE_LEAF"; &REC.GetField(Field.IMAGE_WIDTH).Value = 15; &REC.GetField(Field.IMAGE_HEIGHT).Value = 12; &REC.GetField(Field.INDENT_PIXELS).Value = 20; &SET_ID = PSTREEDEFN_VW.SETID; &USERKEYVALUE = ""; &TREE_NAME = PSTREEDEFN_VW.TREE_NAME; &TREE_DT = PSTREEDEFN_VW.EFFDT; &BRANCH_NAME = ""; &MYSESSION = %Session; &SRC_TREE = &MYSESSION.GetTree(); &RES = &SRC_TREE.OPEN(&SET_ID, &USERKEYVALUE, &TREE_NAME, &TREE_DT, &BRANCH_NAME, False); /* Just insert the root node into the &TREECTL Rowset. If the root node has children, set the &PARENT_FLAG to 'X', so that its children will be loaded on demand. */ &ROOT_NODE = &SRC_TREE.FindRoot(); If &ROOT_NODE.HasChildren Then &PARENT_FLAG = "X"; Else &PARENT_FLAG = "N"; End-If; &NODE_ROWSET = &TREECTL.GetRow(2).GetRowset(1); &NODE_ROWSET.InsertRow(1); &REC = &NODE_ROWSET.GetRow(2).GetRecord(1); /* Set the NODE values: 1) LEAF_FLAG - If this is a leaf set to "Y". Default value: N 2) TREE_NODE - Node name. 3) DESCR - Node description. (optional) 4) RANGE_FROM - Leaf's range from value. 5) RANGE_TO - Leaf's range to value. 6) DYNAMIC_FLAG - If this leaf has a dynamic range, set to "Y". Default value: N 7) ACTIVE_FLAG - Set to "N" for the node or leaf not to be a link. Default value: Y 8) DISPLAY_OPTION - Set to "N" to display the name only. Set to "D" to display the description only. Set to "B" to display both the name and the description. Only used for nodes. Default value: B 9) STYLECLASSNAME - Used to control the style of the link associated with the node or leaf. Default value: PSHYPERLINK 10) PARENT_FLAG - If this node is a parent and its direct children will be loaded now, set to "Y". If this node is a parent and its direct children are to be loaded on demand, set to "X". Default value: N 11) TREE_LEVEL_NUM - Set to the node's level. Default value: 1 12) LEVEL_OFFSET - If a child node is to be displayed more than one level to the right of its parent, specify the number of additional levels. Default value: 0 */ &REC.GetField(Field.LEAF_FLAG).Value = "N"; &REC.GetField(Field.TREE_NODE).Value = &ROOT_NODE.NAME; &REC.GetField(Field.DESCR).Value = &ROOT_NODE.DESCRIPTION; &REC.GetField(Field.RANGE_FROM).Value = ""; &REC.GetField(Field.RANGE_TO).Value = ""; &REC.GetField(Field.DYNAMIC_FLAG).Value = "N"; &REC.GetField(Field.ACTIVE_FLAG).Value = "Y"; &REC.GetField(Field.DISPLAY_OPTION).Value = "B"; &REC.GetField(Field.STYLECLASSNAME).Value = "PSHYPERLINK"; &REC.GetField(Field.PARENT_FLAG).Value = &PARENT_FLAG; &REC.GetField(Field.TREE_LEVEL_NUM).Value = 1;
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
197
Chapter 9
3. (Optional) Set the DISPLAY_OPTION field. The default for the DISPLAY_OPTION field is to display both the node name and the description. You can display just the node name or just the description. The values for this field are:
Field Value N D B Description Display the name only. Display the description only. Display both the name and description.
4. (Optional) Set the STYLECLASSNAME field for the root node. The STYLECLASSNAME field controls the style of the link associated with a node or leaf. The default for the STYLECLASSNAME is PSHYPERLINK. If PSHYPERLINK is not the style you want to use, change this field value to the style you want. 5. Change the assignment of the output of every GenerateTree call to the field attached to the HTML area that will display the tree. In this example, the HTML area control is the DERIVED_HTML.HTMLAREA. You must specify the record and field name associated with the HTML area control on your page. 6. Change the code that processes the select event to perform the action you want when the user selects a node or leaf.
198
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 9
This section is marked as Process Select Event in the following code sample.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
199
Chapter 9
5) RANGE_TO - Leaf's range to value. 6) DYNAMIC_FLAG - If this leaf has a dynamic range, set to "Y". Default value: N 7) ACTIVE_FLAG - Set to "N" for the node or leaf not to be a link. Default value: Y 8) DISPLAY_OPTION - Set to "N" to display the name only. Set to "D" to display the description only. Set to "B" to display both the name and the description. Only used for nodes. Default value: B 9) STYLECLASSNAME - Used to control the style of the link associated with the node or leaf. Default value: PSHYPERLINK 10) PARENT_FLAG - If this node is a parent and its direct children will be loaded now, set to "Y". If this node is a parent and its direct children are to be loaded on demand, set to "X". Default value: N 11) TREE_LEVEL_NUM - Set to the node's level. Default value: 1 12) LEVEL_OFFSET - If a child node is to be displayed more than one level to the right of its parent, specify the number of additional levels. Default value: 0 */ &REC.GetField(Field.LEAF_FLAG).Value = "Y"; &REC.GetField(Field.TREE_NODE).Value = ""; &REC.GetField(Field.DESCR).Value = ""; &REC.GetField(Field.RANGE_FROM).Value = &RANGE_FROM; &REC.GetField(Field.RANGE_TO).Value = &RANGE_TO; &REC.GetField(Field.DYNAMIC_FLAG).Value = &DYNAMIC_RANGE; &REC.GetField(Field.ACTIVE_FLAG).Value = "Y"; &REC.GetField(Field.DISPLAY_OPTION).Value = "B"; &REC.GetField(Field.STYLECLASSNAME).Value = "PSHYPERLINK"; /* Leaves never have children. */ &REC.GetField(Field.PARENT_FLAG).Value = "N"; &REC.GetField(Field.TREE_LEVEL_NUM).Value = &PARENT_LEVEL + 1; &REC.GetField(Field.LEVEL_OFFSET).Value = 0; &ROW = &ROW + 1; End-While; End-If; If &PARENT_NODE.HasChildNodes Then /* Load the child nodes into the &TREECTL Rowset. */ &FIRST = True; &CHILD_NODE = &PARENT_NODE.FirstChildNode; While &FIRST Or &CHILD_NODE.HasNextSib If &FIRST Then &FIRST = False; Else &CHILD_NODE = &CHILD_NODE.NextSib; End-If; If &CHILD_NODE.HasChildren Then &PARENT_FLAG = "X"; Else &PARENT_FLAG = "N"; End-If; /* If the tree uses strict levels, set the &LEVEL_OFFSET to the number of levels that the child node is to the right of its parent minus 1. */ If &SRC_TREE.LevelUse = "S" Then &LEVEL_OFFSET = &CHILD_NODE.LevelNumber &PARENT_NODE.LevelNumber - 1; Else &LEVEL_OFFSET = 0; End-If; &NODE_ROWSET.InsertRow(&ROW - 1); &REC = &NODE_ROWSET.GetRow(&ROW).GetRecord(1); &REC.GetField(Field.LEAF_FLAG).Value = "N";
200
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 9
&REC.GetField(Field.TREE_NODE).Value = &CHILD_NODE.Name; &REC.GetField(Field.DESCR).Value = &CHILD_NODE.Description; &REC.GetField(Field.RANGE_FROM).Value = ""; &REC.GetField(Field.RANGE_TO).Value = ""; &REC.GetField(Field.DYNAMIC_FLAG).Value = "N"; &REC.GetField(Field.ACTIVE_FLAG).Value = "Y"; &REC.GetField(Field.DISPLAY_OPTION).Value = "B"; &REC.GetField(Field.STYLECLASSNAME).Value = "PSHYPERLINK"; &REC.GetField(Field.PARENT_FLAG).Value = &PARENT_FLAG; &REC.GetField(Field.TREE_LEVEL_NUM).Value = &PARENT_LEVEL + 1; &REC.GetField(Field.LEVEL_OFFSET).Value = &LEVEL_OFFSET; &ROW = &ROW + 1; End-While; End-If; /* change the parent's PARENT_FLAG from 'X' to 'Y' */ &PARENT_REC.GetField(Field.PARENT_FLAG).Value = "Y"; HTMLAREA = GenerateTree(&TREECTL, TREECTLEVENT); End-If; &SRC_TREE.Close(); Else /* Process select event. */ /* As an example, just display the selected node name or leaf range as a MessageBox. */ If Left(TREECTLEVENT, 1) = "S" Then &ROW = Value(Right(TREECTLEVENT, Len(TREECTLEVENT) - 1)) + 1; &NODE_ROWSET = &TREECTL.GetRow(2).GetRowset(1); &REC = &NODE_ROWSET.GetRow(&ROW).GetRecord(1); If &REC.GetField(Field.LEAF_FLAG).Value = "N" Then MessageBox(0, "", 0, 0, "The selected node is %1.", &REC.GetField(Field.TREE_NODE).Value); Else If &REC.GetField(Field.DYNAMIC_FLAG).Value = "N" Then If &REC.GetField(Field.RANGE_FROM).Value = &REC.GetField(Field.RANGE_TO).Value Then &TEMP = "[" | &REC.GetField(Field.RANGE_FROM). Value | "]"; Else &TEMP = "[" | &REC.GetField(Field.RANGE_FROM). Value | " - " | &REC.GetField(Field.RANGE_TO).Value | "]"; End-If; Else &TEMP = "[ ]"; End-If; MessageBox(0, "", 0, 0, "The selected leaf is %1.", &TEMP); End-If; Else /* process all other events */ HTMLAREA = GenerateTree(&TREECTL, TREECTLEVENT); End-If; End-If; /* done processing the event, so clear it */ TREECTLEVENT = "";
Related Links
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
201
Chapter 9
2. Add the following PeopleCode to set the message set and number for the mouse-over text:
&REC.GetField(Field.EXPANDED_MSGSET).Value = 2; &REC.GetField(Field.EXPANDED_MSGNUM).Value = 903; &REC.GetField(Field.COLLAPSED_MSGSET).Value = 2; &REC.GetField(Field.COLLAPSED_MSGNUM).Value = 904; &REC.GetField(Field.END_NODE_MSGSET).Value = 2; &REC.GetField(Field.END_NODE_MSGNUM).Value = 905; &REC.GetField(Field.LEAF_MSGSET).Value = 2; &REC.GetField(Field.LEAF_MSGNUM).Value = 906;
3. Add the following fields fields to the TREECTL_NDE_SBR record: DESCR_MSGNUM DESCR_MSGSET
4. Add PeopleCode to set the DESCR_MSGNUM and DESCR_MSGSET fields. These two fields should be set to the correct message number and message set values that contain the text to be used as the mouse-over text.
202
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 9
To add selected node highlighting: 1. Add the field NODESELECTEDSTYLE to the TREECTL_HDR_SBR record. 2. Add PeopleCode to set the NODESELECTEDSTYLE field to provide the highlighting effect. The NODESELECTEDSTYLE field takes the name of a style class. The following example uses the PSTREENODESELECTED style:
&REC.GetField(Field.NODESELECTEDSTYLE).Value = "PSTREENODESELECTED";
You can set the style of the selected node when processing the select event. Note: You also must reset the style of the previous selected node when processing the select event. To find the previous selected node, you can search the node rowset looking for a node with a STYLECLASSNAME equal to the style you set for selected nodes. Alternatively, you can keep a global variable with the index of the node in the rowset. If you keep an index variable, however, you may have to update the index when processing the load children event.
2. Add PeopleCode to use the override values when writing tree control node records.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
203
Chapter 10
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
205
Chapter 10
Use the MAddAttachment function to upload one or more files from an end-user machine to a specified storage location. See "MAddAttachment (PeopleTools 8.53: PeopleCode Language Reference)". DetachAttachment Use the DetachAttachment function to download a file from its source storage location and save it locally on the end user machine. The file is sent to the browser with appropriate HTTP headers to cause the browser to display a save as dialog box to the user. See "DetachAttachment (PeopleTools 8.53: PeopleCode Language Reference)". ViewAttachment Use the ViewAttachment function to download a file from its source storage location and open it locally on the end user machine. See "ViewAttachment (PeopleTools 8.53: PeopleCode Language Reference)". Application server upload/download: PutAttachment Use the PutAttachment function to upload a file from the file system of the application server to the specified storage location. See "PutAttachment (PeopleTools 8.53: PeopleCode Language Reference)". GetAttachment Use the GetAttachment function to download a file from its source storage location to the file system of the application server. See "GetAttachment (PeopleTools 8.53: PeopleCode Language Reference)". Storage location maintenance: CleanAttachments Use the CleanAttachments function to remove orphan files (files with no corresponding file reference) from specified tables used as storage locations in the current database. See "CleanAttachments (PeopleTools 8.53: PeopleCode Language Reference)". CopyAttachments Use the CopyAttachments function to copy all files with file references from one storage location to another. The files to be copied can be limited to those referenced in specific file reference tables. See "CopyAttachments (PeopleTools 8.53: PeopleCode Language Reference)". DeleteAttachment
206
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 10
Use the DeleteAttachment function to delete a file from the specified storage location. See "DeleteAttachment (PeopleTools 8.53: PeopleCode Language Reference)". Image: PeopleCode file attachment functions The following diagram illustrates the operation of the PeopleCode file attachment functions:
Because these functions abstract the storage of the attachments, you can use any defined storage location. The location to be used is determined by the URL passed as the first parameter to the invoked attachment function.
Related Links
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
207
Chapter 10
208
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 10
Note: If the storage location is a database table, then the chunk size is exactly as specified by the value of the Maximum Attachment Chunk Size field (except for the last chunk written, which can be smaller than the maximum). See File Attachment Chunk Size. Note: If the storage location is an FTP site or an HTTP repository, the file is reassembled into a whole file at the destination.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
209
Chapter 10
Note: The file transfer process for MAddAttachment is, in general, similar to the process for AddAttachment. With a call to MAddAttachment, the files are streamed from the browser to the web server in bulk but from the web server through to the storage location one file at a time. Moreover, virus scanning cannot currently be performed on files uploaded with MAddAttachment.
210
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 10
Image: AddAttachment file transfer process The following diagram depicts this process of transferring a file with the AddAttachment function:
The file attachment architecture is designed for use in the frame template or the iframe template only. It is not supported in a pagelet or an HTML template. When content is rendered in a pagelet or HTML template, the user interaction is managed through the PeopleSoft portal servlet. For the file attachment
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
211
Chapter 10
architecture to work, the browser must communicate directly with the PeopleSoft content servlet, which requires the use of the frame or iframe template.
Related Links
"Understanding Portal Templates (PeopleTools 8.53: Portal Technology)" "Applying Template Types (PeopleTools 8.53: Portal Technology)"
In this case, MYRECORD is the record definition associated with the target table. A URL identifier in the form of:
URL.URL_ID
In this case, the URL identifier refers to the URL object named URL_ID.
212
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 10
Important! FTPS and SFTP require that a URL object be used and do not support URL strings. This form of URL string is for use with the FTP protocol only. A URL identifier in the form of:
URL.URL_ID
In this case, the URL identifier refers to the URL object named URL_ID. When specifying a URL for an FTP site, specify the FTP server's name or its IP address. Specify a path on the FTP server relative to the directory specified as the FTP server's home directory. The default FTP port is 21. If you want to use a different port, you must specify it in the URL, as part of the FTP server address. For example:
ftp://ftpserver.peoplesoft.com:6000/
Note: If the specified subdirectories do not exist the PeopleCode function tries to create them. The following limitations apply to FTP URLs: The FTP user name to is limited to 30 characters. The FTP password to is limited to 16 characters.
In this case, the URL identifier refers to the URL object named URL_ID. An HTTP repository can reside on a PeopleSoft web server, or on a different web server environment. If the HTTP repository resides on a PeopleSoft web server, then the psfiletransfer servlet has been provided to manage the file transfers to and from the storage location. If the HTTP repository resides on a nonPeopleSoft web server, then you need to ensure that the web server can handle file transfer security and requests. Additional configuration is required to set up a PeopleSoft web server as an HTTP repository. See the Working with HTTP/HTTPS section in the PeopleTools 8.53: System and Server Administration PeopleBook. See "URL Maintenance (PeopleTools 8.53: System and Server Administration)"
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
213
Chapter 10
straightforward way to restrict the file types that can be uploaded to or downloaded from your PeopleSoft system. File extension lists cannot be applied to ad hoc URL strings. See Restricting the File Types That Can Be Uploaded or Downloaded. URL objects are created and maintained using the URL Maintenance page (PeopleTools, Administration, Utilities, URLs). The length of the full URL is limited to 254 characters. Certain protocolsspecifically, FTPS, SFTP, HTTP, and HTTPSrequire the use of URL objects because other information in addition to the URL itself are required. This additional information is defined as URL properties on the associated URL Properties page. Note: For database tables and the FTP protocol only, the storage location can be specified as an ad hoc string at run time because these file transfer methods do not require additional URL properties. The PeopleTools 8.53: System and Server Administration PeopleBook contains detailed information on creating and maintaining URL objects. See "URL Maintenance (PeopleTools 8.53: System and Server Administration)" The following are examples of some valid storage location URLs:
record://MYAPP_ATT_CNTNT ftp://user01:[email protected]/myfiles ftps://ftp_user:[email protected]:6000/images sftp://usr10:[email protected]/attachments http://www.peoplesoft.com:8080/psfiletransfer/ps/docs https://www.peoplesoft.com:8090/psfiletransfer/empl/docs
214
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 10
table. If you need to store other information, store it as part of the file reference, as described in the step 3, or create another record and use it in the component. 2. Create a URL object that corresponds to your default storage location. See Understanding URL Strings Versus URL Objects. 3. Create an application-specific record definition to define the table that will store file reference information and any additional information about the file attachments. You must include the FILE_ATTACH_SBR subrecord in this new record definition. For example, create a new record called MYAPP_ATT_REF. Add fields for any other information related to the transaction you want to store. Your application must populate the fields in this file reference table with the system file name, user file name, and any information about the file that will be needed for later use. Note: Create a file reference record that is specific to your application. In addition, you should consider whether to create a separate file reference record for each storage location. Doing so can prevent file name conflicts, eliminates the need to store the URL string or URL identifier with each file reference, and can ease the use of the CopyAttachments function. See Considerations When Using CopyAttachments. 4. Clone the FILE_ATTACH_WRK record to create an application-specific derived/work record with a unique name. Save the PeopleCode with the new record. For example, create a record named MYAPP_ATT_WRK by cloning FILE_ATTACH_WRK. You can use this copy of the sample PeopleCode as the basis for your own application. Important! The FILE_ATTACH_WRK record is delivered as a sample only. It is not intended for direct use as part of an application running in production. Instead an application-specific clone of it must be used. Oracle can change the delivered sample PeopleCode in future releases. Any application that directly uses the FILE_ATTACH_WRK record might fail. Using application-specific PeopleCode makes it easier to manage during upgrades and your PeopleCode can be reused in other components that use file attachment functionality. You must also implement the PeopleCode to manage the data in your file reference table (or tables). 5. Use the records you created in the previous steps to create the file attachment component and page. The derived/work record has fields with FieldChange PeopleCode that you can use for Add, Delete, Detach, and View buttons. Add PeopleCodeprobably at the component record field levelto invoke the underlying functions in the application-specific derived/work record when the user clicks on one of the buttons.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
215
Chapter 10
Record FILE_ATTDET_SBR
Example MYAPP_ATT_CNTNT
Description Insert this subrecord in any record definition for target tables that will store attached files. Do not add other fields to this record. Insert this subrecord in any application-specific record for tables that will store references to attached files. The fields in this subrecord store the system file name and the user file name. Clone this derived/work record to create your own applicationspecific derived/work record. In your application-specific derived/work record, you can modify your copy of the delivered sample code to meet your file attachment requirements and manage your file reference table (or tables).
FILE_ATTACH_SBR
MYAPP_ATT_REF
FILE_ATTACH_WRK
MYAPP_ATT_WRK
FILE_ATTDET_SBR Subrecord
To use a database table as a storage location, you must create an application-specific record definition associated with the target table that will receive the attachments. You must include the FILE_ATTDET_SBR subrecord in your application-specific record, and it can contain no additional fields. The FILE_ATTDET_SBR subrecord has the following fields:
Field ATTACHSYSFILENAME Description The system file name, which must be unique to the storage location in order to avoid unintended file overwrites. Furthermore, if the file reference table to be used will contain references to file stored at more than one storage location, then the system file name must also be unique to that table. The value of the ATTACHSYSFILENAME field in the corresponding row of the file reference table must be identical to this value. FILE_SEQ VERSION FILE_SIZE The file sequence number (to support file chunking). Version number. The physical size of the file chunk.
216
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 10
Description Last update date and time. The user ID of the last user to update the attachment. The data of the file chunk.
PeopleTools maintains the values in this table. Therefore, do not reuse the fields in this table to store incomplete or nonstandard versions of the file name or other data.
FILE_ATTACH_SBR Subrecord
You must insert the FILE_ATTACH_SBR subrecord in the application-specific record definition to be associated with the table that will store references to the attached files. The fields in this subrecord store the system file name and the user file name. The FILE_ATTACH_SBR subrecord contains the following fields:
Field ATTACHSYSFILENAME Description The system file name (the name of the file as it exists at the storage location). Among other things, this means that if the file is stored in a database table, then the value in this field must be identical to the value of the ATTACHSYSFILENAME field in the rows that correspond to the file chunks in the database table. ATTACHUSERFILE The user file name (the name that the end user associates with the file).
Your application must populate these fields with the system file name, user file name, and any information about the file that will be needed for later use. See Managing Entries in File Reference Tables.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
217
Chapter 10
Field ATTACHADD
Description Contains a PeopleCode program used for uploading an attachment from an end-user machine to the specified storage location (via the AddAttachment built-in function). Contains a PeopleCode program used for downloading an attachment from the specified storage location to be saved on the end-user machine (via the DetachAttachment built-in function). Contains a PeopleCode program used for deleting an attachment from the specified storage location (via the DeleteAttachment built-in function). Contains a user-defined PeopleCode function that can be called to determine (by file name extension) whether the attachment operation will be permitted on a file. In this function, an array of file name extensions identifies which types of files will be regarded as impermissible. Note: The sample PeopleCode programs included in the FILE_ATTACH_WRK derived/work record invoke this user-defined PeopleCode function.
ATTACHDET
ATTACHDELETE
ATTACHUTIL
ATTACHVIEW
Contains a PeopleCode program used for downloading an attachment from the specified storage location to be viewed on the end-user machine (via the ViewAttachment built-in function).
The PeopleTools Test Utilities page demonstrates a sample application that makes use of the PeopleCode programs in the FILE_ATTACH_WRK derived/work record. See Using the PeopleTools Test Utilities Page.
218
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 10
ATTACHSYSFILENAME Save the system file name in the ATTACHSYSFILENAME field. This is the name of the file as it exists at the storage location and is also a key field of your file reference table. ATTACHUSERFILE Save the user file name, which is the value returned by AddAttachment in its UserFile parameter. This is essentially the base name of file selected by the end user for uploading and would be used to allow end users to identify the file in other file attachment operations (such as viewing, downloading, or deleting).
When your application is downloading or deleting files (for example, with ViewAttachment, DetachAttachment, or DeleteAttachment): ATTACHUSERFILE Use the ATTACHUSERFILE field to present a list of available files for end user selection. This field is also passed as a parameter to some of the built-in PeopleCode functions. ATTACHSYSFILENAME Use the ATTACHSYSFILENAME field (along with the ATTACHUSERFILE field, for some of the built-in PeopleCode functions) to construct the parameters to be passed to the built-in PeopleCode functions.
Related Links
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
219
Chapter 10
The FILE_ATTACH_WRK derived/work record definition also demonstrates a programmatic methodology for restricting file types. The IsLegalAttachmentType function compares a given file to an internally defined array of illegal file extensions. This programmatic methodology can be contrasted with restricting file types through the use of file extension lists. File extension lists can be provide an easier, more flexible, and more manageable approach to restricting file types than a programmatic method. Important! Do not combine these two methodologies in the same application. See Restricting the File Types That Can Be Uploaded or Downloaded.
When the file is uploaded to or downloaded from a storage location, the following characters are replaced with an underscore: (space) @ (at sign) ; (semicolon) + (plus sign) % (percent sign)
220
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 10
& (ampersand) ' (apostrophe) ! (exclamation point) # (pound sign) $ (dollar sign)
Note: In general, you should exercise caution when using an @ or : character in the name of a file selected for uploading. In FTP URLs, the : character must to be used as a delimiter between the FTP user ID and the FTP password or just before the FTP port number (if one is specified). In addition, in FTP URLs, the @ character must be used as a delimiter between the FTP password and the FTP server address.
If you want to transfer files in a non-interactive mode with functions that aren't think-time functions, see GetAttachment and PutAttachment.
Related Links
"Select (PeopleTools 8.53: PeopleCode API Reference)" "SelectNew (PeopleTools 8.53: PeopleCode API Reference)" Think-Time Functions
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
221
Chapter 10
= = = = =
Note: Unlike the PutAttachment function, the AddAttachment function automatically returns the converted file name for reference and later use. For example, the file name My Resume.doc is returned through the AddAttachment function as My_Resume.doc, with the space converted to an underscore.
Related Links
The topics in this section are of interest primarily to customers deploying file processing applications, and secondarily to application developers.
222
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 10
entirely if the specified destination directory does not exist on the application server domain currently in use. Therefore, the path to the local file must be specified with this in mind by creating directories that can be comparably accessed regardless of which application server domain actually services the request at runtime.
Notice that the content-type is audio/mpeg. The browser uses this MIME type to determine that the viewer for audio/MPEG is the appropriate application to open this attachment. If the web server did not send this content-type header, the browser would not be able to determine the nature of the file being transmitted, and it would be unable to invoke the correct viewer application. The browser would try to display the file as text/plain, which is often the wrong behavior. The web server maps file extensions to MIME types through entries in a web.xml configuration file. A copy of web.xml is deployed to each web server instance when it is installed. After a web server instance is created, edit its deployed copy to add any additional MIME types. The location of the deployment copies varies depending on the web server:
Web Server WebLogic WebSphere Location of Deployment Copy PS_HOME/webserv/web_server/applications/ peoplesoft/PORTAL.war/WEB-INF/web.xml PS_HOME/webserv/profile_name/installedApps/app_ nameNodeCell/app_name.ear/PORTAL.war/WEB-INF/ web.xml
See your web server documentation for the name and location of the master copy of this configuration file. This file contains definitions similar to the following:
<mime-mapping> <extension> doc </extension> <mime-type> application/msword </mime-type> </mime-mapping> <mime-mapping> <extension> xls
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
223
Chapter 10
Let's say you want to add a mapping that causes .log files to be interpreted as regular text files. To determine the correct MIME type, check RFC (Request for Comments) documents 2045, 2046, 2047, 2048, and 2077, which discuss internet media types and the internet media type registry. After checking the RFCs, you determine that the correct MIME type is text/plain. The following is an example of code you would add to the previous section of the configuration file:
<mime-mapping> <extension> log </extension> <mime-type> text/plain </mime-type> </mime-mapping>
Once you save the file, the .log extension is associated with the content type of text/plain. Note: You must restart your web server before these changes are recognized. Note: When trying to view the objects, the extension must exactly match what is set up in the web.xml file. This value is case-sensitive. Therefore, if the PreserveCase parameter has been used when uploading files, it will be necessary to add a MIME type entry for each case-permutation of the file extension in question. If the object view appears garbled, chances are that either the extension is not set up in the web.xml file or there is a case mismatch.
Related Links
224
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 10
Configuring VirusScan.xml. Logging virus scans. Virus scan errors and return codes.
Virus scanning can be performed on all files uploaded with the AddAttachment and InsertImage functions only. Warning! Virus scanning cannot currently be performed on files uploaded with the MAddAttachment function.
The location of VirusScan.xml on your system depends on which web server you use. Oracle WebLogic Server:
PS_HOME/webserv/web_server/applications/peoplesoft/PORTAL.war/WEB-INF/ classes/psft/pt8/virusscan
IBM WebSphere:
PS_HOME/webserv/profile_name/installedApps/app_nameNodeCell/app_name.e ar/PORTAL.war/WEB-INF/classes/psft/pt8/virusscan
Configuring VirusScan.xml
These tags are mandatory in VirusScan.xml:
Tag <class> Description Provider class of the scan engine Default provider class is:
psft.pt8.virusscan. provider. GenericVirusScanProviderImpl
<icapversion> <service-name>
ICAP version Service name for the scan engine host. Policy command used by the Scan Engine. Only SCAN is supported.
ICAP/1.0 /SYMCScanResp-AV
<policycommand>
?action=SCAN
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
225
Chapter 10
Tag <address>
Example Value for Scan Engine IP address of the machine where the scan engine is running Port where the scan engine is running
<port>
See PeopleTools 8.53: MultiChannel Framework PeopleBook for complete details on configuring VirusScan.xml. See "Enabling Virus Scanning (PeopleTools 8.53: PeopleSoft MultiChannel Framework)".
IBM WebSphere:
PS_HOME/webserv/profile_name/installedApps/app_nameNodeCell/app_name.e ar/logging.properties
The following results are logged with the date and the file name that was scanned: CLEAN, INFECTED, and SCANERROR The results for these statuses is logged in this form:
filename = result
For example:
finance.xls = INFECTED
CONNECTERROR and CONFIGERROR The results for these statuses is logged in this form:
Unable to connect to the Scan engine: REASON = result
For example:
Unable to connect to the Scan engine: REASON = CONFIGERROR
Chapter 10
If a problem is found, the PeopleCode function returns one the following return codes:
Numeric Value 13 Constant Value %Attachment_ViolationFound Description File violation detected by virus scan engine. Virus scan engine error. Virus scan engine configuration error. Virus scan engine connection error.
14 15
%Attachment_VirusScanError %Attachment_VirusConfigError
16
%Attachment_VirusConnectError
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
227
Chapter 10
Related Links
Related Links
"CopyAttachments (PeopleTools 8.53: PeopleCode Language Reference)" "CleanAttachments (PeopleTools 8.53: PeopleCode Language Reference)" "Copy File Attachments (PeopleTools 8.53: System and Server Administration)"
The topics in this section are of interest primarily to customers deploying file processing applications, and secondarily to application developers.
228
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 10
2. Select the Custom Properties page. 3. Add a new row, and enter these values:
Column Property Name Validation Type Property Value Value IDDA Number 32 (File processing)
4. Set the .level property of the logging.properties file to ALL. 5. Restart the web server. The log files are written to a directory that depends on the java.util.logging.FileHandler.pattern property of the logging.properties file. More information on IDDA logging is available in the PeopleTools PeopleBooks. See "Enabling IDDA Logging (PeopleTools 8.53: System and Server Administration)".
Because PeopleCode tracing can generate a lot of output, setting tracing for a specific client session only is recommended. Application server log files can be found in the PS_CFG_HOME/appserv/domain/LOGS directory. The application server log files have names in the form APPSRV_MMDD.LOG (in which MMDD represents the month and date). The file transfer log file has a name in the form of FILETRANSFERpid.LOG. The PeopleCode trace file has a name of the form, *.tracesql.
See "Specifying Trace Settings (PeopleTools 8.53: System and Server Administration)".
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
229
Chapter 10
An incorrect password. An incorrect account name. An inability of the application server to resolve the FTP server's host name. The FTP server is down.
Try to ping the FTP server machine from the application server system, and then try to manually transfer a file to the FTP server machine from the application server. If the FTP site is on Microsoft Windows, the host name for the system might not be associated with a fixed IP address and might not be resolvable using DNS (Domain Name System). If the application server is on a UNIX machine, the application server can resolve the host name using DNS onlyor perhaps using NIS (Network Information System) or an /etc/hosts file. However, the application server will be unable to use Windows mechanisms such as WinBeui or WINS. Therefore, the application server will not be able to convert the host name indicated for the Microsoft Windows file server into an IP address and route to it. If the file transfer fails, you must resolve the problem by either specifying the numeric IP address in the FTP URL or by putting the host name for the FTP site into DNS, NIS, or the hosts file on your application server so that the name can be resolved. Typically, the URL used for file attachments has the following format:
ftp://user:pwd@system_name/dir1/subdir
However, if the domain name cannot be resolved with DNS, then use the numeric IP address. The following example assumes system_name has the IP address of 123.123.123.123:
ftp://user:[email protected]/dir1/subdir
230
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 10
If your PeopleSoft system operates in a single language environment, use the native language character set for that language on each server tier.
The Global Technology PeopleBook provides examples of which character set to specify on which tier for three typical configurationsa multi-language environment, a single language environment (Western), and a single language environment (non-Western).
Related Links
Related Links
By default, the message level is 0 for each of these programs. The programs are demonstrated on the PeopleTools Test Utilities page.
Related Links
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
231
Chapter 11
Related Links
PeopleTools 8.53: PeopleCode API Reference PeopleTools 8.53: PeopleCode API Reference "Adding Message Definitions (PeopleTools 8.53: PeopleSoft Integration Broker)" "Specifying PeopleCode Actions (PeopleTools 8.53: Application Engine)" PeopleTools 8.53: Security Administration
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
233
Chapter 11
The file is saved to your temp directory, as specified in your environment, in a file with the following name:
PPCMMDDYY_HHMMSS.txt
, where MMDDYY represents the month, date, and year of the checkpoint, respectively, and HHMMSS represents the hour, minute, and second of the checkpoint, respectively. The top of the checkpoint file contains the following information:
[PeopleCode Checkpoint File] [RECORD.recordnameFIELD.fieldnameMETHOD.eventname]
If your PeopleCode program saves successfully, checkpoint files associated with that program are automatically deleted.
234
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 11
items with which they are associated, and they are named according to their associated events, such as ItemSelected, RowInit, or SaveEdit, as shown in the following example. Image: Example of PeopleCode programs in the Project view hierarchy The following image is an example of PeopleCode programs in the Project view hierarchy.
Double-click a record field or pop-up menu item program in the Project view to start the PeopleCode Editor and load that program for editing. When you load a program in the PeopleCode Editor, the status
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
235
Chapter 11
bar at the bottom of the Application Designer window displays the date, time, and the ID of the user who last updated the program as shown in the following example: Image: Status bar displaying the last update information for a PeopleCode program This example illustrates the fields and controls on the Status bar displaying the last update information for a PeopleCode program. You can find definitions for the fields and controls later on this page.
You can associate PeopleCode with other types of definitions, such as: Components Pages Component interfaces
Such PeopleCode programs do not appear in the Project view. Instead, you right-click the name of the definition and select View PeopleCode. You can also access these programs from their associated definitions. PeopleCode can also be associated with: Component records (specific records included in components). Component record fields (specific record fields included in components). Application packages.
Because component record fields and component records do not appear in the Project view, you must access their associated programs through their parent definitions.
Related Links
236
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 11
Related Links
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
237
Chapter 11
In the previous example, the first three fields (in boldface font) have PeopleCode associated with them. If you expand the subrecords in a record definition, any fields in the subrecord that have PeopleCode associated with them also appear in bold type. To access record field PeopleCode from an open record definition: 1. Click the PeopleCode Display button on the toolbar. A grid appears with a column for each event in the record field event set. Each cell represents a field-event combination. The column names are abbreviations of the record field event names, for example, FCh for the FieldChange event and RIn for the RowInit event. A check mark appears in the appropriate cell for each field/event combination that has an associated PeopleCode program. 2. Access the PeopleCode using one of these methods: Double-click the cell. Right-click the cell and select View PeopleCode. Select View, PeopleCode.
The PeopleCode Editor appears. If the field/event combination has an associated program, it appears in the editor.
Related Links
238
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 11
To access record field PeopleCode from a page definition, right-click a page control and select View Record PeopleCode. The PeopleCode Editor appears, displaying the first event in the event set associated with the underlying record field of that control. Button controls are a special case. You can associate a PeopleCode program with a button only if its destination is defined as PeopleCode Command. When the user clicks a button defined using this method, the FieldEdit and FieldChange events are triggered, so the PeopleCode must be associated with one of those two events. Typically, you use the FieldChange event. The following example shows button properties: Image: Page Field Properties dialog box for buttons The following image illustrates Page field properties for buttons.
To define a command button: 1. In the page definition, double-click the button to access its properties. 2. Select PeopleCode Command as the button destination. 3. Select the record and field with which your button and PeopleCode are associated. You should associate the button with a derived/work record field, which separates its PeopleCode from the PeopleCode associated with any of the pages other underlying record fields. You can then store generic PeopleCode with this field so that you can reuse it with buttons on other pages.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
239
Chapter 11
4. Click OK to return to the page. Right-click the command button and select View PeopleCode to access the PeopleCode Editor.
Related Links
Related Links
240
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 11
is associated with the field at the record level, then a lightning bolt does not appear, as shown in the following example: Image: Accessing component record field PeopleCode from the component structure This example illustrates the fields and controls on the Accessing component record field PeopleCode from the component structure. You can find definitions for the fields and controls later on this page.
Note: The Structure tab displays only the runtime state of the PeopleCode. That is, it only displays record field PeopleCode. For example, PeopleCode programs that are orphaned as a result of a page definition change do not appear on the Structure tab. Orphaned PeopleCode programs do appear, however, in the PeopleCode Editor, which displays the design-time view of PeopleCode. The PeopleCode Editor appears. If that field has associated PeopleCode, then the first program in the component record field event set appears in the editor.
Related Links
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
241
Chapter 11
The following events are associated with component non-search records: RowDelete Event RowInit Event In rare circumstances, the Component Processor does not run RowInit PeopleCode for some record fields. The Component Processor runs RowInit PeopleCode when it loads the record from the database. However, in some cases, the record can be initialized entirely from the keys for the component. When this happens, RowInit PeopleCode is not run. RowSelect Event SaveEdit Event SavePostChange Event SavePreChange Event
Related Links
Related Links
242
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 11
Related Links
Related Links
Related Links
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
243
Chapter 11
Note: Page PeopleCode can only be accessed in this way. You cannot access Page PeopleCode from the component definition Structure tab, from a project, or any other way. The PeopleCode Editor appears. If the page has associated PeopleCode, it appears in the editor. Note: The term page PeopleCode refers to PeopleCode programs owned by pages. Do not confuse page PeopleCode with PeopleCode properties related to the appearance of pages, such as the Visible Page Class property.
Related Links
PeopleTools 8.53: PeopleCode API Reference PeopleTools 8.53: PeopleCode Developers Guide
Related Links
PeopleTools 8.53: PeopleSoft Application Designer Developer's Guide PeopleTools 8.53: PeopleCode Developers Guide
Related Links
ItemSelected Event
244
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 11
If you are creating a new menu item, double-click the empty rectangle at the bottom of the pop-up menu. The Menu Item Properties dialog box appears. 2. If this is a new menu item, enter a name and a label for the item. 3. Select PeopleCode from the Type group box. 4. Click OK to close the Menu Item Properties dialog box.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
245
Chapter 12
Related Links
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
247
Chapter 12
The editor window contains the main edit pane, the drop-down definition list at the upper-left, and the drop-down event list at the upper-right. The drop-down lists enable you to navigate directly to the PeopleCode associated with related child definitions, for example, fields within a record and their event sets. Note: When you make a selection from either drop-down list box, your selected entry has a yellow background, indicating that you must click the edit pane before you can start typing. You can open as many editor windows as you want and resize them in Application Designer. Each line of code wraps automatically based on the windows current width. A vertical scroll bar appears if the program has more lines than the editor can display in the edit pane. Note: You cannot open two editor windows for a single parent definition, or for any two of its child definitions.
Related Links
Navigating Between Programs Associated With a Definition and Its Children Navigating Between Programs Associated With Events
248
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 12
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
249
Chapter 12
that definition. For every definition-event combination with associated PeopleCode, the event name is displayed in bold, and it appears at the top of the event list, as shown in the following illustration: Image: Selecting an event from the PeopleCode Editor This example illustrates the fields and controls on the Selecting an event from the PeopleCode Editor. You can find definitions for the fields and controls later on this page.
Related Links
PeopleTools 8.53: PeopleCode Developers Guide PeopleTools 8.53: PeopleCode Developers Guide
250
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 12
Set up help. Change colors in the PeopleCode Editor. Select a font for the PeopleCode Editor. Change word wrap in the PeopleCode Editor. Use PeopleCode Event properties.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
251
Chapter 12
Use these buttons to perform editing functions: Save the current PeopleCode program. You can also use the key combination CTRL+S. Cut the selected text or item. You can also use the CTRL+X or SHIFT+DEL key combinations. Copy the selected text or item. You can also use the CTRL+C or CTRL+INS key combinations. Paste from the clipboard. You can also use the CTRL+V or SHIFT+INS key combinations. Find specified text. You can also use the key combination CTRL +F. Find and replace specified text. You can also use the key combination CTRL+H. Validate the current PeopleCode program. Undo the last change. Use the CTRL+Z or ALT+BACKSPACE key combinations. Cancel the current operation. Use Esc key.
Related Links
You can move through finding and replacing text strings one string at a time, or click Replace All to replace globally. The Undo function is available to undo the last replace or replace all.
252
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 12
The Mark All button places a bookmark next to all lines that have the matching text. Use Shift+ctrl+f2 to remove all bookmarks. With the Replace dialog box, you can select to replace text either in a selected section or a whole file (that is, a PeopleCode program.)
Go To Dialog
Use the Go To dialog box to specify a line number in the current program, then go to that line. If you have line wrap not enabled, you can specify to go to statement numbers instead of line numbers. Image: Go To dialog box This example illustrates the fields and controls on the Go To dialog box. You can find definitions for the fields and controls later on this page.
The Validate utility has several functions, such as finding undeclared variables, mismatching data types, or invalid methods or properties for a class. You can check either a single component or an entire project. Errors or warnings produced by the Validate utility are displayed in the Validate tab at the bottom of the PeopleCode Editor window. Any variables that you don't declare are automatically declared for you, and a warning message appears in the Validate tab for each undeclared variable. You can right-click in the Validate tab and select Clear to delete all the warnings listed there, then use the Validate utility again to ensure that your code runs without errors or warnings. Note: This feature is convenient if you have written multiple PeopleCode programs and you want to check the syntax of one without saving. All PeopleCode programs associated with an item (record, component, and so on) are checked prior to saving.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
253
Chapter 12
Related Links
"Validating Projects (PeopleTools 8.53: PeopleSoft Application Designer Developer's Guide)" Compiling All PeopleCode Programs at Once
254
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 12
The PeopleCode Editor provides immediate access to external PeopleCode function definitions. Right-click the function name in the program where the function is called, then select View Function FunctionName. This opens a new PeopleCode Editor window containing the external function definition. Note: Internet scripts are contained in records similar to FUNCLIB_ records. However, their names begin with WEBLIB_.
This opens the application package or a new PeopleCode Editor window containing the application class. The following example shows the context menu for a fully-qualified application class name. Image: Context menu with options for View Application Package and View Application Class This example illustrates the fields and controls on the Context menu with options for View Application Package and View Application Class. You can find definitions for the fields and controls later on this page.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
255
Chapter 12
The following example shows the context menu for a method. Image: Context menu with options for View Application Class Method and View Application Class This example illustrates the fields and controls on the Context menu with options for View Application Class Method and View Application Class. You can find definitions for the fields and controls later on this page.
Note: The application class context menu is not available for methods that are called by indirection. In the following example the method CallMe would not be available to view using the context menu. Object0.GetObject().CallMe();
This may be helpful when you need to know whether a method has been overridden.
256
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 12
If you access a record definition from a record field reference (that is, recordname.fieldname) the specified record field is selected when the record definition opens. To open a new PeopleCode editor window, right-click a reference to the definition and select View PeopleCode or, for application class PeopleCode, select View Application Class Method or View Application Class. For example, you can access record PeopleCode from the following record and record field references: Record.BUS_EXPENSE_PER BUS_EXPENSE_PER.EXPENSE_PERIOD_DT
Note: You can only view the PeopleCode and definition when the text is in the format recordname.fieldname. If the text is in the format method(i).recordname, method(i).fieldname, or &MyRecord.Fieldname, the View PeopleCode and View Definition commands are not available. You can access application class PeopleCode from the following references: PT_BRANDING:BrandingBase %This.ValidateSave(&aErrs)
Accessing Help
The PeopleCode Editor has context-sensitive online help for all PeopleCode built-in functions, methods, properties, system variables, and meta-SQL. To access online help, place the cursor in the item that you want to look up, then press F1. If there is a corresponding entry in the online reference system it appears; otherwise an error message similar to the following appears.
Help cannot be displayed because no help topic was found for the help context ID "my_ topic".
If more than one entry is applicable, a pop-up window that lists all applicable entries appears. Select the entry for the item of interest.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
257
Chapter 12
Setting Up Help
To set up the help, use the F1 Help URL field on the PeopleTools Options page to specify where the documentation is stored. The format of the URL is as follows:
http://doc_location/f1search.htm?ContextID=%CONTEXT_ID%&LangCD=%LANG_CD%
The doc_location specifies the server and directory where the documentation files are located. The remainder of the URL after doc_location must follow the exact format shown. For example, you might place the following URL in the F1 Help URL field:
http://pandora.mycompany.com:8080/doc/f1search.htm?ContextID=%CONTEXT_ID%&LangCD=%LAN G_CD%
After you specify the help location on the PeopleTools Options page, you must stop and restart the application server through PSADMIN before you can access help.
Related Links
258
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 12
Note: When you select a font for the PeopleCode Editor, the font selection dialog box provides choices based on a character set appropriate for your international version of Microsoft Windows. If you experience trouble embedding foreign characters (such as Thai characters) in PeopleCode, you might need to change the font setting. If you are trying to display Thai characters in Microsoft Windows 95, you might also need to change your keyboard input settings for the characters to display correctly. You can change your keyboard input settings from the Input Locales tab on the Windows Regional Settings control panel, or on the Keyboard control panel.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
259
Chapter 12
Specify whether word wrap is the default mode when opening the editor. If this box is not checked, wrapping text based on window size is the default. Specify whether the text wraps based on the size of the window. Specify whether the text wraps based on the number of characters in a line. If this box is checked, you can specify the number of maximum number of characters per line. Specify the maximum number of characters allowed for a line before the text wraps. The default value is 90. Valid values are between 25 and 2000.
260
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 12
Note: This dialog box has been deprecated. It has no effect on the location of the execution of code.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
261
Chapter 12
You can also access a component interface using the component object model (COM). You can automatically generate a Visual Basic template, a Java template, or a C template, similar to the PeopleCode template, to begin.
262
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 12
To generate a template: 1. Open a component interface in Application Designer. 2. Right-click anywhere in the open component interface and select a template type. You must save the component interface before generating the template. When the template is successfully generated, a message appears with the full path and name of the file containing the template. 3. Open the generated file and modify the source code to meet the needs of your application. The following is the initial code snippet that is generated for a Visual Basic template:
Option Explicit '===> 'This is a dynamically generated Visual Basic template to be 'used only as a helper to the application developer. 'You need to replace all references to '<*>' OR default 'values with references to Visual Basic variables. Dim oSession As PeopleSoft_PeopleSoft.Session Private Sub ErrorHandler() '***** Display PeopleSoft Error Messages ***** If Not oSession Is Nothing Then If oSession.ErrorPending Or oSession.WarningPending Then Dim oPSMessageCollection As PSMessageCollection Dim oPSMessage As PSMessage Set oPSMessageCollection = oSession.PSMessages Dim i As Integer For i = 1 To oPSMessageCollection.Count Set oPSMessage = oPSMessageCollection.Item(i) Debug.Print "(" & oPSMessage.MessageNumber & "," & oPSMessage.MessageSetNumber & ") : " & oPSMessage.Text Next i '***** Done processing messages in the collection; '***** OK to delete ***** oPSMessageCollection.DeleteAll End If End If End Sub . . . .
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
263
Chapter 12
&REC.ExecuteEdits(%Edit_Required + %Edit_DateRange + %Edit_YesNo + %Edit_OneZero); If &REC.IsEditError Then For &E = 1 To &REC.FieldCount &MYFIELD = &REC.GetField(&E); If &MYFIELD.EditError Then &MSGNUM = &MYFIELD.MessageNumber; &MSGSET = &MYFIELD.MessageSetNumber; &LOGFILE.WriteLine("****Record:" | &REC.Name | ", Field:" | &MYFIELD.Name ); &LOGFILE.WriteLine("****" | MsgGet(&MSGSET, &MSGNUM, "")); End-If; End-For; Return False; Else Return True; End-If; End-Function; . . . .
264
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 13
Related Links
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
265
Chapter 13
program, then the names of the program, the section, the step, and the action are listed in the title bar, as shown in the following example: Image: Example of Application Engine program SQL in the SQL editor window This example illustrates the fields and controls on the Example of Application Engine program SQL in the SQL editor window. You can find definitions for the fields and controls later on this page.
The editor window consists of the main edit pane. For SQL definitions and SQL used with records, a drop-down database list appears at the upper left. For SQL definitions, a drop-down effective-date list is available at the upper right. Note: When you make a selection from either drop-down list box, your selected entry has a yellow background, indicating that you must click the edit pane before you can start typing.
Use general properties to specify a description for the SQL definition as well as additional comments. The description appears in Application Designer search lists. Use the advanced properties to display an effective date with the SQL definition.
266
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 13
Note: The Audit SQL field on the Advanced Properties tab is not used.
You access the SQL editor differently for each type of component.
To create a SQL definition: 1. From Application Designer, select File, New, SQL.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
267
Chapter 13
2. Specify the database type to associate with the SQL definition. You can associate more than one database type with a single SQL definition. In PeopleCode, you can specify the appropriate database type for the program. However, at least one of the SQL statements must be of type Default. 3. (Optional) Specify an effective date. To specify an effective date with your SQL definition: a. Access the object properties by selecting File, Object Properties. Alternatively, select the SQL definition, right-click it, and then select Object Properties, or press ALT + ENTER. b. Click the Advanced tab, and then click Show Effective Date. When you click OK, the SQL definition shows a date in the right-hand drop-down menu. 4. Enter the SQL code. You do not need to format your code. The SQL editor formats it when you save the SQL definition.
Related Links
PeopleTools 8.53: PeopleSoft Application Designer Developer's Guide PeopleTools 8.53: PeopleCode API Reference
268
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 13
Access the SQL editor with record definitions. 1. Open or create a dynamic view or SQL view record definition. 2. Select the Record Type tab. 3. Click the Click to Open SQL Editor button. You can select a database type, but not an effective date, from the SQL editor for dynamic view and SQL view record definitions. Note: You must be sure to save record definitions of the SQL View type before opening the SQL editor. Once the SQL editor is open, the Save options are disabled and inaccessible. If you do not save your changes before opening the SQL editor, you may lose your work.
Related Links
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
269
Chapter 13
The following example shows an Application Engine program in the SQL editor: Image: Example of an Application Engine program in the SQL editor window This example illustrates the fields and controls on the Example of an Application Engine program in the SQL editor window. You can find definitions for the fields and controls later on this page.
Access the SQL editor in an Application Engine program. 1. Open the Application Engine program. 2. Select the action. 3. Either right-click and select View SQL, or select View, SQL. Select the database type and effective date for this SQL in the section, not in the SQL editor.
270
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 13
This table describes the functions that are available in the SQL editor but not the PeopleCode editor:
Function Format Display Description You do not need to format your SQL statements; you only need to use the correct syntax. When you save or validate, the system formats the code according to the rules in the PeopleCode tables, no matter how you entered it originally. It automatically converts field names to uppercase and indents statements. The resulting look of SQL is consistent with other programs in the system. If the SQL contains meta-SQL, select Resolve Meta SQL to expand the meta-SQL statement in the output window. The expanded meta-SQL appears in the Meta SQL tab. You can delete standalone SQL statements. This menu item is not enabled with SQL statements that have a database type of Default with no effective date, or for statements that have a database type of Default and an effective date of 01/01/1900.
Delete Statement
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
271
Chapter 13
This example, using Resolve Meta-SQL, shows how the following code expands:
%Join(COMMON_FIELDS, PSAEAPPLDEFN ABC, PSAESECTDEFN XYZ)
Image: Meta-SQL expanded in the output window This example illustrates the fields and controls on the Meta-SQL expanded in the output window. You can find definitions for the fields and controls later on this page.
Related Links
272
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 14
Related Links
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
273
Chapter 14
In the following example, PTAF_UTILITIES is the primary package, and Encryption, Exception Utilities, Integration, and so on, are subpackages. Printable Document is a class in the PTAF_UTILITIES application package, while Base64 and PSCipher are classes in the Encryption subpackage. Image: Application Package Editor main window This example illustrates the fields and controls on the Application Package Editor main window. You can find definitions for the fields and controls later on this page.
274
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 14
subpackage is differentiated by the full path name of the class (from the package definition name and the subpackage name). Image: Example of application package naming conventions The following is an example of application package naming conventions, which shows a case where in, suppose in the application class PT_FRUIT, where PT_FRUIT is the primary class, you had the following structure of subpackages (no classes are listed in this example):
In this example, three subpackages are named Raw, but the fully qualified name for each is unique. For example, the first one is qualified by the name of the primary package. Its fully qualified name is PT_FRUIT:Raw. The other Raw subpackages are also qualified by the subpackages that contain them. Their names are PT_FRUIT:Reciepies:Raw and PT_FRUIT:Smoothies.Raw. Similarly, you cannot create two classes with the same name within a given package or subpackage. You can create classes with the same name within the same application package definition, just like subpackages, as long as the fully qualified name is unique. Each class is differentiated by the full path name of the class. Note: You cannot create a structure for which more than two levels of subpackages are defined below the primary package.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
275
Chapter 14
Related Links
Not available for this release. Instead, insert new subpackage and class nodes where needed and use the clipboard to copy and paste PeopleCode text from class to class. To copy the primary package, select File, Save As.
Delete
Click to delete either a class or a package. The PeopleCode text is not actually deleted until you save the application package. Deleted PeopleCode classes can be recovered by reinserting the class node, as long as you have not saved in the interim. Click to insert an application class. Because classes cannot have children (subclasses), they can be inserted only into an existing package. Click to insert an application package. You can only insert packages into an existing package or subpackage. Click to rename either a class or a subpackage. When you save the definition, all PeopleCode programs associated with the renamed class are also updated. To rename the primary package definition, select File, Rename. Click to view the associated PeopleCode. PeopleCode can be defined only for application classes, and it is not directly related to package nodes.
Insert App Class (insert application class)application classesinserting Insert Package Rename
View PeopleCode
276
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 14
Click to print the application package definition, including all the PeopleCode in the classes. Select an application package or class and click to search for references. See Finding References to Application Packages and Classes.
Only one event is defined for an application class, OnExecute. This is not an event in the Component Processor flow. The application class runs when called.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
277
Chapter 14
The drop-down list at the upper-left enables you to navigate directly to the PeopleCode associated with every class in the package, as well as to every subpackage and its classes. To edit an application class: 1. Open the application package. 2. Select a class. 3. Either select View, PeopleCode or right-click and select View PeopleCode. A PeopleCode Editor window appears.
Related Links
278
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 15
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
279
Chapter 15
Note: You can start a debugging session either before or after you start a PeopleSoft component. 1. Determine whether to run Application Designer in two-tier mode or three-tier mode. If you are debugging Application Engine or component interface PeopleCode, run Application Designer in two-tier mode, with a direct connection to the datatbase. If you are debugging an application in PeopleSoft Pure Internet Architecture (PIA), run Application Designer in three-tier mode, through the application server. You must be logged on to PIA and to Application Designer using the same user ID. 2. Access the debugger through Application Designer by selecting Debug, PeopleCode Debugger Mode. The Local Variables watch pane and the Call Stack pane open. PeopleCode programs that had breakpoints set from your previous debugging session are opened also, and the breakpoints are restored. If you did not have breakpoints set, open the PeopleCode program you want to debug and enter debug mode. The debugger will open with the current PeopleCode program and you can set your breakpoints. Note: If you have already opened the debugger and then closed it, the menu may not change correctly to enable you to access the debugger a second time. If this occurs, click the Local Variables window, and then try the Debug menu again.
280
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 15
In PIA, navigate to the point where the breakpoint occurs. Your application pauses and the Application Designer icon flashes in the task bar. Switch to Application Designer to step through your program or continue running it. Image: Application Designer icon flashes in the toolbar when the application hits a breakpoint This example illustrates the fields and controls on the Application Designer icon flashes in the toolbar when the application hits a breakpoint. You can find definitions for the fields and controls later on this page.
If the debugger does not engage, check that you used the same user ID to log into PIA and Application Designer, then check your application server configuration to verify that PeopleCode debugger is enabled. Note: Your security administrator has options for allowing users to access different parts of Application Designer, including the PeopleCode debugger. If you are having problems accessing the debugger, you may need to contact your system administrator about your security access. You can access the PeopleCode debugger from outside a firewall.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
281
Chapter 15
Visible current line of execution. Visible breakpoints. Hover inspect. Single debugger. Variable panes. General debugging tips.
Visible Breakpoints
The PeopleCode debugger supports visual indicators that signify breakpoint locations. In the following example, the current line indicator (green arrow) is shown at the first line, and the breakpoint (red dot displayed in left-hand gutter) is on line 8: All breakpoints are saved when Exit Debug Mode is selected. Note: You cannot set breakpoints in function declarations, variable declarations, or comments.
282
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 15
Hover Inspect
If the program is already running, you can see the actual values for the variables by holding the cursor over them. The current value appears in a pop-up window, as shown in the following example: Image: PeopleCode debugger with breakpoint, current line of execution, and hover inspect This example illustrates the fields and controls on the PeopleCode debugger with breakpoint, current line of execution, and hover inspect. You can find definitions for the fields and controls later on this page.
Hover inspect is implemented only for simple variables and fields. Hover inspect is not implemented for object expressions (for example, rowset assignments and array assignments).
Single Debugger
Each PeopleSoft session you run on a machine can have its own debugging session. However, only one instance of the PeopleCode debugger can occur per session. If more than one instance of Application Designer is running for a session, only one may be the active debugger at a given time. From within a running instance of Application Designer, any component in the same session is also placed into debug mode. After the session is in debug mode, any component that is started and that belongs to that session automatically goes into debug mode. Similarly, Application Engine PeopleCode and component interface PeopleCode can be debugged. After you exit debug mode by selecting Debug, Exit Debug Mode or by exiting Application Designer, all components in that session go out of debug mode. If you exit a component, debugging continues with any remaining open and running components. If more than one Application Designer session is running, the Application Designer session that is used as a debugger is the first one to be started. In debug mode, a PeopleCode Editor window opens for every item (for example, record, component, or page) that has PeopleCode in it when that PeopleCode is executed. If a component has more than one event with a PeopleCode program, then only one window opens per item. For example, if you have a record that has PeopleCode in both the SearchSave and RowInit events, only one PeopleCode Editor window opens: first it contains the SearchSave PeopleCode program, and then the RowInit program. If you have PeopleCode in the RowInit event for two different records that are part of the same component, two PeopleCode Editor windows open, one for each RowInit PeopleCode program.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
283
Chapter 15
Variables Panes
The four types of variables panes are: Local Global Component Parameter
The Local, Global, and Component variable panes show local, global, and component variables, respectively. The Parameter variable pane shows the value of parameters passed in function declarations. From the variables pane, you can check the value of the variables you have in the program. These values are updated as the code runs. The following example shows the variables pane: Image: Local Variables pane This example illustrates the fields and controls on the Local Variables pane. You can find definitions for the fields and controls later on this page.
284
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 15
In addition, you can expand any of the objects to see its properties by clicking the plus sign next to the variable name. In the following example, a level one rowset is expanded. You can see the properties, such as ActiveRowCount and DBRecordName, that are part of the rowset. Image: Local Variables pane with rowset object expanded This example illustrates the fields and controls on the Local Variables pane with rowset object expanded. You can find definitions for the fields and controls later on this page.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
285
Chapter 15
In addition, some objects contain other objects: a rowset contains rows, rows contain records or child rowsets, and records contain fields. You can expand these secondary objects to see their properties. In the following example, the first row of a rowset is expanded, as is the EMPL_CHECKLIST record: Image: Variable pane with rowset, row, and record expanded (shown with condensed font) This example illustrates the fields and controls on the Variable pane with rowset, row, and record expanded (shown with condensed font). You can find definitions for the fields and controls later on this page.
Field Values
When you view a field object in the debugger, the value of the field is listed in the Value column. Therefore, you do not have to navigate to the Value property to see the value of a field.
286
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 15
The following example shows the PERSONAL_DATA record and the values of the fields: Image: PERSONAL_DATA record field values This example illustrates the fields and controls on the PERSONAL_DATA record field values. You can find definitions for the fields and controls later on this page.
In addition, the only fields that appear in the debugger are the fields that are actually in the Component Buffer. For example, suppose you have a derived work record, but you do not access all the fields in the work record. Only the fields that you access and that are in the Component Buffer actually appear in the debugger.
Related Links
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
287
Chapter 15
The Call Stack pane is updated, when necessary, with each change of the debug state.
Go To Source Code
Right-click on a function to access a context menu with these options:
Options Copy Description Copies the text of the selection in the call stack to the clipboard. Selects all rows in the call stack. You can also use standard shift-click and CTRL-click actions to select multiple rows. Displays the selected function in the Edit window. In addition, the active variables windows will be updated in sync with the Call Stack and Edit windows. Double-click a function name to go to the source code.
Select All
Go To Source Code
When the displayed source code is at the execution point, the execution pointer icon (green arrow) appears in the source window.
288
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 15
When the displayed source code is not at the execution point, the selected function icon (yellow triangle) appears in the source window. Image: Source code pane and call stack pane showing the yellow triangle execution pointer This example illustrates the fields and controls on the Source code pane and call stack pane showing the yellow triangle execution pointer. You can find definitions for the fields and controls later on this page.
Viewing source code for functions that are not at the top of the stack does not change the point of execution. Nor does it disable the ability to continue execution. For example, in the previous example, selecting Go would cause the program execution to continue at FUNCLIB_PORTAL.PORTAL_GEN_FUNC.FieldFormula PortalOpen and not at the function in the source code window. During debugging it is easier to go back to the previous code event from the call stack window as compared to trying to keep track of where the control was transferred and then finding the right opened PeopleCode window in Application Designer. This can be useful when trying to understand the component design and PeopleCode flow.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
289
Chapter 15
While the debugger is running and halted at a breakpoint, select a field in the value column, such as the Local Value column in the example, and revise the value. Image: Local Variables pane showing a drop-down list to set the value for a Boolean variable This example illustrates the fields and controls on the Local Variables pane showing a drop-down list to set the value for a Boolean variable. You can find definitions for the fields and controls later on this page.
The debugger performs data type checking to prevent entry of incorrect data type values. For example, character strings are not allowed for integer data types, and so on. However, data integrity is not verified, so be aware that changing variable values at runtime can corrupt program execution as well as program data. For example, setting an integer value higher than what is permitted in the function could cause a crash when execution continues. It is the developers responsibility to enter an appropriate value. Modifying a variable in a debugger pane changes the value in memory only. The change does not trigger any PeopleCode events and does not cause any PeopleCode flags to be set.
290
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 15
If a database transaction has been started (either for you by PeopleTools, or by you in PeopleCode) other users of that database are blocked from accessing that database until the transaction is complete. If you are stepping through PeopleCode while this transaction is open, you could potentially block other users for an extended period of time. You may want to use a private database for debugging to avoid blocking other users.
Using the debugger is resource intensive and will impact overall system performance. Oracle recommends that you do not run debugger on your production system unless the issue you are trying to debug cannot be replicated in any other environment. If that is the case, debug when there is the least activity on the system. As an alternative you can try PeopleCode tracing. To create a file that contains all the PeopleCode for a project (or database), use the Find In feature and search for ;. Be sure to select Save PeopleCode to File.
The following example shows the Find In dialog box: Image: Find In dialog box This example illustrates the fields and controls on the Find In dialog box. You can find definitions for the fields and controls later on this page.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
291
Chapter 15
DoModal Considerations
If you set the PeopleCode debugger to break at start and you are using the DoModal PeopleCode function, the DoModal window may appear behind the PeopleCode debugger window. The debugger may appear to have stopped, but it has not. Be sure to check that other windows have not opened while you are debugging the code.
Exits debug mode. When you exit debug mode, all breakpoints are automatically saved. If you close Application Designer, you automatically exit debug mode. Stops the PeopleCode program that is currently running. Displays the location of the running code in a dialog box. This display includes the record name, field name, event name, and line number of the code. It also indicates if the code is executing
292
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 15
on the client or server. You can view the exact code by clicking View Code. Image: Execution Location Properties dialog box This example illustrates the fields and controls on the Execution Location Properties dialog box. You can find definitions for the fields and controls later on this page.
Break at Start
Pauses execution of the component on the first line of every PeopleCode program that executes in the component. If you start a component with Break at Start selected and then you start a second component, the PeopleCode associated with the second component is stopped at the first line of the first PeopleCode program as well, as part of the same debugging session. Removes the breakpoint if the line the cursor is currently on has a breakpoint. Adds a breakpoint if the line the cursor is currently on does not have a breakpoint. Opens a dialog box that displays the lines that have breakpoints. From this dialog box, you can display the code that contains the
Edit Breakpoints
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
293
Chapter 15
breakpoint by clicking View Code. You can also remove one or all breakpoints. Image: Breakpoints dialog box This example illustrates the fields and controls on the Breakpoints dialog box. You can find definitions for the fields and controls later on this page.
Continues processing until the next breakpoint. If Break At Start is enabled, processing pauses at the next PeopleCode program. Executes the current line of the PeopleCode program, stepping into functions. Steps through each line of the PeopleCode program, one line at a time, but steps over the functions; the functions are executed, but not stepped into. Processes past the return of the current function, and then pauses. Processes low-level, pseudo-machine code instructions internal to PeopleCode. This option is used in conjunction with Log Options. Opens a separate window for viewing the call stack. The Call Stack window displays a stack of PeopleCode functions and methods that are currently active but not completed. You can use the Call Stack window to observe the flow of an application as it executes a series of nested functions. Opens a separate window for watching global variables. Opens a separate window for watching component variables. Opens a separate window for watching local variables.
294
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 15
Opens a separate window for watching user-specified parameters in function calls. Opens a separate window for viewing the current component buffers. This is equivalent to getting a level zero rowset for the component.
Note: The previous five windows update continuously as the program executes. Options Image: General Options dialog box This example illustrates the fields and controls on the General Options dialog box. You can find definitions for the fields and controls later on this page. Enables you to select between opening a dialog box for general options or for specifying log options.
The General Options dialog box enables you to specify conditions of the view windows. The default is for both of these options to be selected. Enable Auto Scroll If you select this check box and you click a plus symbol next to a variable name in a view window, the variable you clicked scrolls to the top of the window. Select to display all view windows with a smaller font.
Additional Features
Break at Termination After you are in debug mode, generally, any PeopleCode program in the session that terminates abnormally first breaks in the debugger. In addition, the error message appears in the PeopleCode log in the bottom window of Application Designer.
Related Links
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
295
Chapter 15
Related Links
"Setting Up the PeopleCode Debugger (PeopleTools 8.53: System and Server Administration)"
296
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 15
1. Open Application Designer while accessing the database that contains the PeopleCode that you want to check. 2. Select the compile option to use. Select Tools, Compile All PeopleCode or Tools, Compile Project PeopleCode. 3. Click Compile in the Compile All PeopleCode dialog box. Errors appear in the PeopleCode log display window. Note: If you specified a log file in the debugger log options, then all errors are written to the log file as well.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
297
Chapter 15
All log information appears in the PeopleCode log window, at the bottom of Application Designer. Image: PeopleCode log window This example illustrates the fields and controls on the PeopleCode log window. You can find definitions for the fields and controls later on this page.
You can record what you see in a log file. Also, you can tailor the log results to record a variety of online information. If you exit debug mode but do not close Application Designer, all the log options that you specified are still there when you start debug mode again. When you close the Application Designer, all log options are clear. The next time you enter debugging mode, you must reselect debug log options. See Interpreting the PeopleCode Debugger Log File. All the options available in the Log Options dialog box are also available in PeopleSoft Configuration Manager, on the Trace tab, in the PeopleCode Trace section.
298
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 15
Option Stack
Description Indicates the contents of the internal machine stack. Typically, only PeopleSoft staff developing PeopleCode language enhancements use this option.
Log To File
When you select this option, you must specify the name of a file, or you receive an error and logging to file is disabled. If you do not specify a directory location, the file is placed in the same directory from which you are running PeopleTools. If you specify the name of an existing file, a warning message appears, asking you whether to overwrite the file. You must go back into the Log Options dialog box and specify a different file name; otherwise, the log file is overwritten. If you do not exit Application Designer before running a different application, each trace is appended to the specified log file.
Related Links
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
299
Chapter 15
With PeopleTools utilities (included for backward compatibility purposes only and should not be used).
All trace files except those produced using the Log File option contain timing information, such as when each line started processing and how long it took to execute. The Log File option writes to a file that you specify. The log file produced by the other options is specified by the PeopleTools Trace File option in PeopleSoft Configuration Manager. All of these options write to the same file. Trace files are also produced by Application Engine. These logs may contain more information. This section discusses: Log file contents. Other items in the log file.
Related Links
300
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 15
Description Issued when the Fetch Field option is selected. It contains the record and field name and the value that is retrieved. Issued when the Fetch Field option is selected and the selected record.field contains a null value. Issued when the Fetch Fields option is selected and when the field is not found. Displayed after a branch test when the branch is taken. Displayed whenever a referenced field was not found error causes the PeopleCode processor to skip to the next statement. Issued when the List Program option is selected. It marks the beginning of a PeopleCode program listing. Issued when the List Program option is selected. It marks the end of a PeopleCode program listing. Issued when a fatal error condition terminates the PeopleCode program.
Fetch Field:recordname.fieldname Contains Null Value Fetch Field:recordname.fieldname Does Not Exist Branch Taken Field Not Found, Statement Skipped
vvvvvv PeopleCode Program Listing ^^^^^ PeopleCode Program Listing End Error Return -> NNN
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
301
Chapter 15
Related Links
"WriteToLog (PeopleTools 8.53: PeopleCode Language Reference)" "%ApplicationLogFence (PeopleTools 8.53: PeopleCode Language Reference)"
Related Links
302
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 15
The following example shows the Find In dialog box: Image: Example of the Find In dialog box showing options for Find Type This example illustrates the fields and controls on the Example of the Find In dialog box showing options for Find Type. You can find definitions for the fields and controls later on this page.
You can select to search in a specific project or the entire database. If a project is currently open, then the initial search scope is that project. If you are searching PeopleCode programs and SQL statements, you can specify if you want record PeopleCode, page PeopleCode, menu PeopleCode, and so on. All output from the search is placed in an output window. You can save these results to a file, copy them, clear them, or print them. From the output window, you can immediately open any of the PeopleCode programs, SQL statement, HTML definitions, or free-form stylesheets listed. You also can insert selected definitions into a project from the output window. Then, if you need to search those definitions again, you can search by project. Note: To create a file that contains all the PeopleCode for a project (or database) you can use the Find In feature and search for ;. Be sure to select Save PeopleCode to File. To find a text string: 1. In Application Designer, select Edit, Find in. Alternatively, if a project is open, right-click the project name in the project workspace; select Find In Project from the pop-up menu.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
303
Chapter 15
The Find In dialog box appears. If a project is currently open, then the initial search scope is that project. Otherwise, the search scope is the entire database. 2. Type the string that you want to find in the Find What edit box. If you want only those items that match the case of what you entered, select the Match Case check box at the bottom of the dialog box. 3. Specify with the Find Type edit box whether you are searching in PeopleCode and SQL, just PeopleCode, just SQL, HTML definitions, or freeform stylesheets.. 4. Select the project to search. You can search the entire database or any existing project. 5. (Optional) Select the view to search. If you decide to not search the entire database, you can specify if you want to search the Development view or the Upgrade view. The default is the Development view. 6. Select the items to search. You can search all items that contain either PeopleCode or SQL, or a subset of items. Note: When you select a Find Type of Text String in HTML the Search check box list is empty. The search is conducted against all HTML definitions. Similarly, when you select a Find Type of Text String in Freeform Stylesheets the Search check box list is empty. The search is conducted against all freeform stylesheets. 7. (Optional) Save the search results to a file. You can save the results of a PeopleCode search to a text file, which you can view or print using a text editor or word processor. The text file contains the entire PeopleCode program that contained the string. To save your results to a file, select the Save PeopleCode to File check box at the bottom of the dialog box. The results are saved to the file, and appear in the Application Designer Find In output window. This option is not available when searching SQL, HTML, or freeform stylesheets. 8. Click the Find button to start the search. As the Find In feature searches the database, it displays a counter at the bottom of the Find In dialog box indicating the number of PeopleCode programs searched. You can click the Cancel button to stop the process. 9. Check the Find in tab on the output window for results. The results of the search appear in the Find In tab of the output window. Each line shows where the string was found. You can open any of the programs listed by double-clicking a line in the output window.
304
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 15
The following example shows the Find In tab of an output window: Image: Opening a PeopleCode program from the Find In tab This example illustrates the fields and controls on the Opening a PeopleCode program from the Find In tab. You can find definitions for the fields and controls later on this page.
To save records, you select them in the output window, as shown in the following example: Image: Find In output window with definitions selected This example illustrates the fields and controls on the Find In output window with definitions selected. You can find definitions for the fields and controls later on this page.
To save definitions in a project: 1. Use the Find In feature to search for a string. 2. Press the Shift key while selecting the references to save in the output window. 3. Right-click the highlighted definitions and select Insert Into Project. All the selected definitions are inserted into the current open project. 4. Save your project.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
305
Chapter 15
The following example shows the Insert Into Project option: Image: Insert Into Project option of the Find In pop-up menu This example illustrates the fields and controls on the Insert Into Project option of the Find In pop-up menu. You can find definitions for the fields and controls later on this page.
Prerequisites
To be able to search for references to application packages or classes, you must compile all PeopleCode for the database first: Note: This compilation process is a one-time activity per database, which takes many hours to complete and depending on the size of your database. 1. Sign into Application Designer in two-tier mode. 2. In Application Designer, select Tools, Compile all PeopleCode. 3. In the Compile All PeopleCode dialog box, select the Compile all and Save all PeopleCode option. 4. Click the Compile button. After this initial PeopleCode compilation, new application package and class definitions and references are automatically added to the database. Important! When importing a project that contains application package and application class definitions, you must select the Compile PeopleCode after Import option to add these definitions to the database.
Related Links
306
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 15
After you select this item, a search of the database takes place, and the results appear on the Find Definition References tab of the output window. 4. Select any definition that is displayed in the Find Definition References tab by double-clicking it. The selected definition opens in the editor. Note: Find definition references will not find an application package or class name when it appears in a PeopleCode comment or when the name appears in a string literal (that is, within quotes). Use the Find In feature instead.
Related Links
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
307
Chapter 15
See "Understanding Projects (PeopleTools 8.53: PeopleSoft Application Designer Developer's Guide)""Using Projects (PeopleTools 8.53: PeopleSoft Application Designer Developer's Guide)". PeopleTools is delivered with these PeopleCode cross-reference reports: XRFFLPC. Reports on all fields in the system referenced by other PeopleCode programs. The report sorts by record names and field names. XRFFLPC shows the records, fields, and PeopleCode program types that reference each field. XRFPCFL. Reports on the fields that each program references. It sorts the report by record definition, field name, and PeopleCode type. It shows the records and fields referenced for each program. This report and XRFFLPC complement each other by using converse approaches to reporting the cross references. XRFPNPC. Reports on pages with PeopleCode. This report shows pages containing fields with PeopleCode attached to them. You can run these reports using PeopleSoft Query and either view the reports online or print them. You can also download them to a Microsoft Excel spreadsheet. The following example shows an XRFPNPC report: Image: Example of XRFPNPC PeopleSoft Query results This example illustrates the fields and controls on the Example of XRFPNPC PeopleSoft Query results. You can find definitions for the fields and controls later on this page.
Related Links
308
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 15
"Understanding Cross-Reference Reports (PeopleTools 8.53: PeopleSoft Application Designer Developer's Guide)"
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
309
Chapter 16
Server trips are bad for performance. Each server trip consumes resources on the application server, slows down the user data entry, and can affect type ahead. Whenever you see an hourglass as you move between fields on a page, it is because the browser is waiting for a server trip to complete. The larger the components buffer (based on the number of record definitions accessed, the number of fields in each record, and the number of rows in each grid or scroll area for each record), the longer each round trip to the server, because of the increased server processing. Deferred mode reduces the users time to complete the transaction and conserves application server resources.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
311
Chapter 16
The following user interactions cause a trip to the server. Only the first three items in the list are deferred in deferred processing mode. Entering data in fields with FieldEdit or FieldChange PeopleCode. Entering data in fields that have prompt table edits. Entering data in fields that have related displays. Inserting a row in a grid or scroll area. Deleting a row from a grid or scroll area. Using grid or scroll area controls to move forward or back. Accessing another page in the component. Selecting an internal tab. Expanding or collapsing a collapsible section. Clicking a button or link.
Each trip goes through the same process of checking security, unpacking the buffers that store the data being processed, processing the service request, generating the HTML for the page to be redisplayed, packing updated buffers, and storing the buffers on the web server. To maximize online performance, minimize server trips.
312
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 16
When the page is redisplayed, the cursor is positioned in the same field it was when the user pressed the Refresh button. Note: The Refresh button does not refresh the page from the database. It simply causes a server trip so that any deferred PeopleCode changes are processed. If no deferred changes exist or the deferred changes do not cause any errors or other changes on the page, it may appear to the user as if nothing has happened. Fields on derived work records are not updated if the user clicks the Refresh button.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
313
Chapter 16
314
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 16
Send messages in the SavePostChange event. Use metadata and the RowsetCache class. Setting MaxCacheMemory
Optimizing SQL
A simple join optimizes SQL more effectively than issuing two related SQL statements separately. However, if your transaction requires a complex SQL statement (for instance, one that uses correlated subqueries), consider breaking it up into multiple SQL statements. You may get more predictable performance this way.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
315
Chapter 16
Setting MaxCacheMemory
PeopleTools stores application data in a memory cache to increase system performance. However, too large a cache can leave insufficient available memory on your system, which leads to reduced performance. Use this setting to specify the maximum size of the memory cache. PeopleTools prunes the cache to keep it within the specified size, and places the pruned data in a disk cache instead. Because using a disk cache can also reduce performance, the default setting might not be optimal for your application. You can adjust this setting to achieve the best trade-off between speed and available memory. See "Cache Settings (PeopleTools 8.53: System and Server Administration)".
316
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 16
For example, if you know that a particular variable is going to be an Integer value, declare it to be Integer in the first place. You can get much better runtime performance. It is particularly effective for loop control variables but, since an integer has limited range (up to 9 or 10 digits), you must use it judiciously. 3. Watch references. In PeopleCode function calls, parameters are passed by reference; a reference to the value is passed instead of the value itself. If you are passing a reference to a complex data structure, such as a rowset object or an array, passing by reference saves significant processing. Watch out for unexpected results, though. In the following code, the function Test changes the value of &Str after the function call.
Function Test(&Par as String) &Par = "Surprise"; end-function; Local String &Str = "Hello"; Test(&Str); /* now &Str has the value "surprise" */
4. Put Break statements in your Evaluate statements. In an Evaluate statement, the When clauses continue to be evaluated until an End-evaluate or a Break statement is encountered. If you have an Evaluate statement with a number of When clauses, and you only expect one of them to match, put a Break statement following the likely clause. Otherwise, all the subsequent When clauses are evaluated. Your program is still correct, but it is inefficient at runtime, particularly if you have a large number of When clauses, and the Evaluate statement is in a loop. 5. Govern your state. One of the key features in PeopleSoft Pure Internet Architecture is that the application server is stateless. When required, the state of your session is bundled up and exchanged between the application server and the web server. For example, on a user interaction, the whole state, including your PeopleCode state, has to be serialized to the web server. Then, once the interaction has completed, that state is deserialized in the application server so that your application can continue. To improve efficiency: Watch the size of PeopleCode objects that you create (strings, arrays, and so on) to make sure they are only as big as you need them to be. For user interactions, you might be able to change the logic of your program to minimize the state. For example if you are building up a large string (a couple of megabytes) and then performing a user interaction, you might be able to change your program logic to build the string after the interaction.
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
317
Chapter 16
For secondary pages that are infrequently accessed but retrieve lots of data, consider setting No Auto Select in the Application Designer for the grids and scroll areas on the secondary page, to prevent loading the data the secondary page when the page buffers are initially built. Then add the necessary Select method to the Activate event for the secondary page to load the data into the grid or scroll area.
6. Isolate common expressions. The PeopleCode compiler is not an optimizing compiler, unlike some current compilers for languages such as C++. For example, the PeopleCode compiler does not do common subexpression analysis. So, sometimes, if you have a complicated bit of PeopleCode that is used often, you can isolate the common expression yourself. This isolation can make your code look cleaner and make your code faster, especially if it is in a loop. In this example, notice how the common subexpression is broken out:
/*---- For this customer, setup time on B is influenced by *---- the machine flavors of A. */ &r_machine = &rs(&idB.GetRecord(Record.MACHINE_INFO); If (&typeA = "F") And (&typeB == "U") Then &r_machine.SETUP_TIME.Value = 50; Else &r_machine.SETUP_TIME.Value = 10; End-If;
The compiler has to evaluate each occurrence of the expression, even though it would only execute it once. Here is another example. Notice that once &RS and &StartDate are created, they can be used repeatedly in the loop, saving significant processing time.
&RS = GetRowset(); &StartDate = GetField(PSU_CRS_SESSN.START_DATE).Value; For &I = 1 To &RS.ActiveRowCount &RecStuEnroll = &RS.GetRow(&I).PSU_STU_ENROLL; &Course = &RecStuEnroll.COURSE; &Status = &RecStuEnroll.ENROLL_STATUS; &PreReqStart = &RS.GetRow(&I).PSU_CRS_SESSN.START_DATE.Value; If &Course.Value = "1002" And (&Status.Value = "ENR" Or &Status.Value = "CMP") Then If &PreReqStart < &StartDate Then &Completed = True; Break; End-If; End-If; End-For;
7. Avoid implicit conversions. The most common implicit conversion is from a character string to a number and vice versa. You might not be able to do anything about this, butby being aware of ityou might be able to spot opportunities to improve performance. In the following example, two character strings are converted into numeric values before the difference is taken. If this code were in a loop and one of the values did not change, performance would improve significantly by doing the conversion once, as the second statement illustrates.
&Diff = &R1.QE_EMPLID.Value - &R2.QE_EMPID.Value;
318
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 16
8. Choose the right SQL style. In certain cases, use SQLExec, as it only returns a single row. In other cases, you could benefit greatly by using a SQL object instead, especially if you can plan to execute a statement more than once with different bind parameters. The performance gain comes from compiling the statement once and executing it many times. For instance, code that uses SQLExec might look like this:
While (some condition) . . .set up &Rec SQLExec("%Insert(:1)", &rec); /* this does a separate tools parse of the sql and db compile of the statement and execute each time */ End-while;
The following code rewrites the previous example to use the new SQL object:
Local SQL &SQL = CreateSQL("%Insert(:1)"); While (some condition) . . .Setup &Rec &Sql.Execute(&Rec); /* saves the tools parse and db compile on the SQL statement and the db setup for the statement */ end-while;
SQL objects also have the ReuseCursor property, which can be used for further performance gains. See "ReuseCursor (PeopleTools 8.53: PeopleCode API Reference)". 9. Tighten up loops. Examine loops to see if code can be placed outside the loop. For example, if you are working with file objects and your file layout does not change, there is no reason to set the file layout every time you go through the loop reading lines from the file. Set the file layout once, outside the loop. 10. Set objects to NULL when they will no longer be accessed. Once you are finished with an object reference, especially one with a global or component scope, assign it to NULL to get rid of the object. This setting allows the runtime environment to clean up unused objects, reducing the size of your PeopleCode state. 11. Improve your application classes Simple properties (without get/set) are much more efficient than method calls. Be clear in your design about what needs to be simple properties, properties with get/set, and methods. Never make something a method that really should be a property. Analyze your use of properties implemented with get/set. While PeopleCode properties are in a sense first class properties with more flexibility in that you can run PeopleCode to actually get and set their values, make sure you actually need get and set methods. If all you have is a normal property which is more of an instance variable then avoid get/set methods. In the following example (without the strikethrough!) by having get/set for the property SomeString you have made it much more inefficient to get/set that property since every property reference has to run some PeopleCode. Often,
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
319
Chapter 16
this inneficiency can creep in when properties are designed to be flexible at the beginning and never subsequently analyzed for whether getters/setters were really needed after all.
class Test ... property String SomeString get set; end-class;get SomeString return &SomeString; end-get; set SomeString &SomeString = &NewValue; end-set;
This code has the following problems: You might run out of memory in the Fill method if the Select gathers a large amount of data. The Fill is selecting all the columns in the table when all that is being updated is one column.
You can change this code to read in the data one row at a time using a SQL object or using a similar algorithm, but chunking the rowsets into a manageable size through the use of an appropriate Where clause. The following are some approximate numbers you can use to see how large a rowset can grow. The overhead for a field buffer (independent of any field data) is approximately 88 bytes. The overhead for a record buffer is approximately 44 bytes. The overhead for a row is approximately 26 bytes. So a rowset with just one record (row) the general approximate formula is as follows:
320
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 16
memory_amount = nrows * (row overhead + nrecords * ( rec overhead + nfields * ( field overhead) + average cumulative fielddata for all fields)) The following are some code examples to show isolating common expressions. In this example, a simple evaluation goes from happening three times to just once &RS_Level2(&I).PSU_TASK_EFFORT. In addition, the rewritten code is easier to read. Example of code before being rewritten:
Local Rowset &RS_Level2; Local Boolean &TrueOrFalse = (PSU_TASK_RSRC.COMPLETED_FLAG.Value = "N"); For &I = 1 To &RS_Level2.ActiveRowCount &RS_Level2(&I).PSU_TASK_EFFORT.EFFORT_DT.Enabled = &TrueOrFalse; &RS_Level2(&I).PSU_TASK_EFFORT.EFFORT_AMT.Enabled = &TrueOrFalse; &RS_Level2(&I).PSU_TASK_EFFORT.CHARGE_BACK.Enabled = &TrueOrFalse; End-For;
In the next example, the following improvements are made to the code: Shorthand is used: &ThisRs(&J) instead of &ThisRs.GetRow(&J). Eliminated all the autodeclared messages by declaring all the local variables. This action can improve your logic and possibly give you better performance. Notice the integer declaration. If you know your variables will fit in an integer (or a float), then declare them that way. Runtime performance for Integers can be better than for variables declared as Number. Fewer evaluation expressions. Example of code before being rewritten:
Local Row &CurrentRow; &TrueOrFalse = (GetField().Value = "N"); &CurrentRow = GetRow(); For &I = 1 To &CurrentRow.ChildCount For &J = 1 To &CurrentRow.GetRowset(&I).ActiveRowCount For &K = 1 To &CurrentRow.GetRowset(&I).GetRow(&J).RecordCount For &L = 1 To &CurrentRow.GetRowset(&I).GetRow(&J).GetRecord(&K).FieldC ount &CurrentRow.GetRowset(&I).GetRow(&J).GetRecord(&K).GetField(&L).Enab led = &TrueOrFalse; End-For; End-For; End-For; End-For;
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
321
Chapter 16
*/
Concatenating a large number of strings into a large string. Sometimes you need to do this. The simplest approach is to do something like:
&NewString = &NewString | &NewPiece;
In itself this is not a bad approach but you can do this much more efficiently using an application class below.
class StringBuffer method StringBuffer(&InitialValue As string); method Append(&New As string) returns StringBuffer; // allows &X.Append("this ").Append("that").Append("and this") method Reset(); property string Value get set; property integer Length readonly; property integer MaxLength; private instance array of string &Pieces; end-class; method StringBuffer /+ &InitialValue as String, +/ &Pieces = CreateArray(&InitialValue); &MaxLength = 2147483647; // default maximum size &Length = Len(&InitialValue); end-method; method Reset &Pieces.Len = 0; &Length = 0; end-method; method Append /+ &New as String +/ Local integer &TempLength = &Length + Len(&New); If &Length > &MaxLength Then throw CreateException(0, 0, "Maximum size of StringBuffer exceeded(" | &Ma xLength | ")"); End-If; &Length = &TempLength; &Pieces.Push(&New); return %This;
322
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Chapter 16
end-method; get Value /+ Returns String +/ Local string &Temp = &Pieces.Join("", "", "", &Length); /* collapse array now */ &Pieces.Len = 1; &Pieces[1] = &Temp; /* start out with this combo string */ Return &Temp; end-get; set Value /+ &NewValue as String +/ /* Ditch our current value */ &Pieces.Len = 1; &Pieces[1] = &NewValue; /* start out with this string */ &Length = Len(&NewValue); end-set;
The code is meant to enable the user to type in a name and get the person's phone number. In the example, the developer expects that the user will input data such as Smith, in which case the resulting SQL would look like this:
SELECT NAME, PHONE FROM PS_INFO WHERE NAME='Smith'
However, if the user specified "Smith' OR AGE > 55 --", the resulting SQL would look like this:
SELECT NAME, PHONE FROM PS_INFO WHERE NAME='Smith' OR AGE > 55 --'
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
323
Chapter 16
Note the use of the comment operator (--) to ignore the trailing single quotation mark placed by the developer's code. This would allow a devious user to find everyone older than 55. Use the following approaches to avoid SQL injection vulnerabilities: Where possible, avoid using string-building techniques to generate SQL. Note: String-building techniques cannot always be avoided. String-building does not pose a threat unless unvalidated user input is concatenated to SQL. Use bind variables where possible rather that string concatenation. The following example is vulnerable:
SQLExec("SELECT NAME, PHONE FROM PS_INFO WHERE NAME='" | &UserInput | "'", &Name, &Phone);
Use the Quote PeopleCode function on the user input before concatenating it to SQL. This pairs the quotation marks in the user input, effectively negating any SQL injection attack. The following example is vulnerable:
SQLExec("SELECT NAME, PHONE FROM PS_INFO WHERE NAME='" | &UserInput | "'", &Name, &Phone);
Specify whether SQL errors appear to the user with the Suppress SQL Error setting in the PSTOOLS section of the application server configuration file. Normally, the SQL in error appears to the user in a number of messages. If you consider this a security issue, add the following line to your application server configuration file:
Suppress SQL Error=1
When this line is set, SQL errors do not display details; instead, they refer the user to consult the system log. The detail that was in the SQL message is written to the log file.
Related Links
"Quote (PeopleTools 8.53: PeopleCode Language Reference)" "PSTOOLS Options (PeopleTools 8.53: System and Server Administration)"
324
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Appendix A
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
325
Appendix A
Key Shift-Delete (down arrow) Ctrl- Shift- End Ctrl-End Shift-End Shift-Ctrl-End Enter Esc (escape) F2 Ctrl-F2 Shift-F2 Shift-Ctrl-F2 F3 Shift-F3 F5 F8 F9 Atl-F9 Ctrl-F9 F10 Home Ctrl-Home Shift-Home
Description Edit cut Line down Scroll window down one line Line down with selection Position cursor at end of line Position cursor at end of file Select to end of line Select to end of file New line Clear selection Next bookmark Toggle bookmark off and on Previous bookmark Remove all bookmarks Find next Find previous Go (Debug) Step (Debug) Toggle debug breakpoint Edit breakpoints (Debug) Break at start (Debug) Step over (Debug) Position cursor to first character of line Position cursor to start of file Select to start of line
326
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
Appendix A
Key Shift-Ctrl-Home Insert Ctrl-Insert Shift-Insert (left arrow) Ctrl- Shift- Shift-Ctrl- Page Down Page Up (right arrow) Ctrl- Shift- Shift-Ctrl- Tab Shift-Tab (up arrow) Ctrl- Shift-Ctrl-W Ctrl-X Ctrl-Y Ctrl-Z Shift-Ctrl-Z
Description Select to start of file Toggle insert mode Copy Paste Position cursor left one character Position cursor left one word Select one character left of cursor Select next word left of cursor Page down Page up Position cursor right one character Position cursor right one word Select one character right of cursor Select next word right of cursor Tab Back tab Line up Scroll window up one line Select word Edit cut Edit redo Edit undo Edit redo
Copyright 1988, 2013, Oracle and/or its affiliates. All rights reserved.
327