In PeopleCode a rowset object, instantiated from a Rowset class, is a collection of rows associated with buffer data. Standalone rowset is an independent rowset object which is not associated with the component buffer. It means if you are using a rowset which is not in the component buffer, it is a Standalone rowset. Standalone rowset allows you to work with data outside of the buffer by getting whatever additional data you need form the database. In this sense Standalone rowset is somewhat similar to the functionality of derived records which were once used as place holders to store data not directly associated with the component. Standalone rowset is not associated with the component buffer, there is no automatic action taken by the component processor on it. So if you want to manipulate (Delete/insert/Update) data using Standalone rowset then code needs to be written manually to save the changes done. Standalone rowsets are not associated with a component or page. The scope of Standalone rowsets can be Local, Global, or Component.
Standalone Rowset
In PeopleCode a standalone rowset is an independent rowset object not associated with the component buffer. They allow you to work with data outside of the buffer by getting whatever additional data you need form the database. In this sense they replace the functionality of derived records which were once used as place holders to store data not directly associated with the component. Because a standalone rowset is standalone, there is no automatic action by the component processor on it. This means that if a standalone rowset is used to manipulate data (inserts/updates), code will need to be added to manually save the changes.
Multilevel Rowsets
A multi-level rowset is one that has a parent-child-grandchild relationship structure. Such rowsets can be really handy when you need to emulate the structure of the component buffer (scroll levels). For this example I'm going to use a structure based on PeopleTools security the USER_ROLES page in the USERMAINT component which is located at: PeopleTools > Security > User Profiles > User Profiles > Roles (tab) The reason I'm using PeopleTools security is that it is available for all PeopleSoft applications (HRMS, Campus Solutions, Finance etc). A simplified version of the scroll structure in the USER_ROLES page is:
What I want is to create a rowset that emulates this scroll structure so that I can store the roles a particular user may have. The first step is to declare the rowsets and use an appropriate naming convention and suffix with the scroll level which I makes sense:
Local Rowset &rsUser0; Local Rowset &rsRoles1; Local Rowset &rsUserRoles;
Rowset &rsUser0 is for PSOPRDEFN, &rsRoles1 is for PSROLEUSER_VW and &rsUserRoles is the multi-level rowset with the structure we want. Now we need to create the standalone rowsets for level 0 and level 1 in our scroll structure:
&rsUser0 = CreateRowset(Record.PSOPRDEFN); &rsRoles1 = CreateRowset(Record.PSROLEUSER_VW);
This gives us a rowset where each user (operator ID) can have one or more roles. In our example, we could then populate the standalone rowset from the component buffer like so:
Local Rowset &rs0; &rs0 = GetLevel0();
&rs0.CopyTo(&rsUserRoles);
For more information, see this article on copying rowsets. You might have a case where you want multiple children at a scroll level. Here's another example using the PSOPRALIAS page on theUSERMAINT component. The structure this time is:
Level 0: PSOPRDEFN
o o
Level 2: PSORPALIASFIELD
Now we have three scroll levels and two children at the same scroll level (scroll 1 has PSOPRALIAS and PSOPRALIASTYPE). Once again we start with the standlone rowsets for each record in the scroll structure. However this time, using a bottom-up approach we link the lower scroll levels to the higher scroll levels as follows:
Local Rowset &rsUser0, &rsAlias1, &rsAliasType1, &rsAliasField2;
&rsAliasField2 = CreateRowset(Record.PSOPRALIASFIELD); &rsAliasType1 = CreateRowset(Record.PSOPRALIASTYPE, &rsAliasField2); &rsAlias1 = CreateRowset(Record.PSOPRALIAS, &rsAliasType1); &rsUser0 = CreateRowset(Record.PSOPRDEFN);
The same applies for getting to a particular field. For example, say I wanted to message out the field PSOPRALIAS.OPRALIASTYPE. This would be the code to use with the &rsUserAlias multilevel rowset:
MessageBox(0, "", 0, 0, "Operator Alias Type = " | &rsUserAlias(1).GetRowset(Scroll.PSOPRALIAS)(1).PSOPRALIAS.OPRALIASTYPE.Value);
Going down to level 2 or 3 can get quite confusing! That's why it is easier to do the manipulation to the underlying rowsets then combine them together at the end into a multilevel rowset. Getting information out of the multilevel rowset still poses the same challenges though. Which is why you might want to create scroll level rowsets that reference scroll levels on your multilevel rowset. The previous examples can be simplified this way by creating &rsUserAlias1which references the PSOPRALIAS scroll at level 1 on the &rsUserAlias multilevel rowset.
Local Rowset &rsUserAlias1;
&rsUserAlias1 = &rsUserAlias(1).GetRowset(Scroll.PSOPRALIAS);
Copying Rowsets
I find that you often need to create and manipulate standalone rowsets. Sometimes you can get the data for your standalone rowset from the database using the Fill method, however sometimes you'll want to copy from existing rowsets. This is where the CopyTo method comes in handy. However there is one important thing to note when using CopyTo - it will only copy like-named record fields and subscrolls at corresponding levels In order to work correctly, the record in the source rowset must have the same name as the record in target rowset, unless you specify a record list in the parameters. For instance, say I have data in a rowset &rsExample with one record, EXAMPLE which is populated in the component buffer. The EXAMPLE record has the following fields:
EMPLID NAME
Now, say I want to copy the data from my rowset &rsExample to another rowset, &rsExampleAudit which consists of an audit record forEXAMPLE called AUDIT_EXAMPLE. The AUDIT_EXAMPLE record has the following fields:
AUDIT_OPRID AUDIT_STAMP AUDIT_ACTN EMPLID NAME
What I want is to copy the like-name fields between &rsExample and &rsExampleAudit (the fields EMPLID and NAME). The following code will NOT work:
&rsExample.CopyTo(&rsExampleAudit)
Why? Because &rsExample consists of a record named EXAMPLE, but &rsExampleAudit consists of a record named AUDIT_EXAMPLE. Because the two rowsets do not have the same underlying record name, the copy does absolutely nothing (quite frustrating!). In this scenario, we need to specify a record list, so it knows the source and target record names. This how I need to write this code to make it work:
&rsExample.CopyTo(&rsExampleAudit, Record.EXAMPLE, Record.AUDIT_EXAMPLE)
You can use these two methods to show or hide a grid on a page associated wtih a particular rowset. Simply make sure that the grid uses the main record that your rowset refers to, then refer to this scroll record using a rowset and call the methods to show or hide the grid. This is particularly useful if you have a field that determines whether or not a grid should be displayed. For example, a check box field calledSpecify individual users and a grid used to enter individual users. Make sure you put your PeopleCode in both the FieldChange andRowInit methods to ensure consistency when showing/hiding your grid. Also make sure that in your page properties, you have the Adjust Layout for Hidden Fields check box set. This ensures the page height adjusts dynamically based on whether or not the grid is visible, rather than leaving a big whitespace gap when it is hidden. Note if you are receiving errors about modifying the current program context, move your code up a scroll level and then use ShowAllRows()or HideAllRows() from the higher level scroll on your rowset. You cannot use this code at the same scroll level as the grid itself.