December 5, 2007
Derived Record PeopleCode
Last week I referred
to the heavy use of derived/work records in some areas of the
system—self service pages, for example. Although these can
be very useful, there are certain considerations to keep in mind.
I've previously mentioned that the component processor handles these
differently from "real" tables and views in some cases (in grids,
in component-changed handling and so on). Today I'd just like to
discuss the use of PeopleCode on derived records.
When I started my current self service project I created a new
derived record and attached some PeopleCode to it. After all, this
derived record was specifically for our custom self service system,
so it seemed to be a safe bet. That was a mistake. As the system
grew (the more we rolled out, the more the client wanted!), I kept
running into situations in which a field on the derived record
could not be used on a new page because it carried the baggage of
PeopleCode intended for another component.
For example, if a field on a derived record has RowInit code and
that field is used on a new page, the RowInit code will fire whether
that's appropriate or not. One solution is to wrap the code in
If %Component = Component.X_MY_OLD_COMPONENT Then .... But
in order to do that correctly, we need to know which components
currently use the code. Miss one and we will break a component that
we are not even working on at the moment. We could use a negative
condition such as
If %Component <> Component.X_MY_NEW_COMPONENT Then ...,
but then that must be maintained for each new component we create.
A better solution is to keep the code attached to the component itself
as component PeopleCode (component-, record- or field-level). That way
we know that it will not affect other components and we have a smaller
chance of modifying code that is included in two different projects. Record
PeopleCode is best used when it is intended to be shared by different
components. Code related to editing of data on a table is a good example—every
component that saves data to that table will probably need this code, so
it is shared. But there are fewer cases of this when we are dealing with
Another solution to the problem is to place our shared code in functions
located in FieldFormula. That way, the components can call the functions
they need without the danger of breaking other parts of the system.
As a general guideline, only FieldFormula should contain record-level PeopleCode
on a derived/work record and all of this code will be within functions.
Following this guideline will keep all of the fields on your record
available for new pages and will help you avoid unexpected bugs.
Not following the guideline—for example, adding record-level
PeopleCode to a derived field where the derived record is already in use—can
cause other parts of the system to break unexpectedly.
Until next time...