In this second part of the series, we will go through methods which can make your script way more dynamic. These methods are well documented for the most part. Hard-coding is acceptable at times but statically written script can easily turn into “write-only” spaghetti which is difficult to maintain.
In many cases, it is enough to modify a script only slightly to make it much more flexible. Using dimension properties is my favorite way of bringing order to an otherwise chaotic environment. The most valuable benefit you gain by using properties instead of hard-coded member values is that any new AUDITID or ACCOUNT (or whatever dimension) members will be automatically handled correctly. This can make a huge difference when changes are frequent and schedules are tight.
It may sound paradoxical, but adding a little bit of complexity early on can make things a lot simpler down the road. Proper design during the implementation phase eliminates the need for technical expert involvement during day to day operations. Having autonomy and control over the system allows the business to make changes independently. Time and again clients have emphasized how important it is to retain ownership of THEIR solution. Flexible maintenance is one of BPC’s key strengths and where it truly shines out.
The following table shows how the dimension members should be maintained to support a dynamic script suitable for our purposes. In this case, we have added a custom property SRCTYPE for both AUDITID and ACCOUNT dimensions. We have also added a custom property TRGTACCT for the ACCOUNT dimension. A new account INCPERC has been created. These preparations are necessary to make our solution more flexible. Exactly how they are used will be explained shortly.
Dimension | Member | Property SRCTYPE value | Property TRGTACCT value |
AUDITID | PAYR01 | PAYR | |
AUDITID | PAYR02 | PAYR | |
AUDITID | CALCRES | Any value but PAYR | |
ACCOUNT | PL5110 | PAYR | PL5119 |
ACCOUNT | PL5111 | PAYR | PL5119 |
ACCOUNT | PL5119 | Any value but PAYR | |
ACCOUNT | PL6110 | PAYR | PL6119 |
ACCOUNT | PL6111 | PAYR | PL6119 |
ACCOUNT | PL6119 | Any value but PAYR | |
ACCOUNT | INCPERC | Any value but PAYR |
Now that we have maintained all the dimension members, we can improve the script easily. Our first step is to replace the hard-coded scoping with dynamic member selections. The following example shows how to do this. We use the names %AUDITSRC% and %ACCOUNTSRC% to temporarily store our selection of source AUDITID and ACCOUNT members.
*SELECT(%AUDITSRC%, ID, AUDITID, SRCTYPE= PAYR)
*SELECT(%ACCOUNTSRC%, ID, ACCOUNT, SRCTYPE= PAYR)
*XDIM_MEMBERSET AUDITID = %AUDITSRC%
*XDIM_MEMBERSET ACCOUNT = %ACCOUNTSRC%
The above statements make our scoping of data dynamic but we still need hard-coded values to handle different percentage rates and target accounts. Generally speaking, percentages and other values should not be hard-coded. A simple way to avoid this is to store the necessary values as transaction data. That is the reason we created the INCPERC account. We use this account to enter the two percentage values used in our calculations. We only need one account as the percentages are associated with the AUDITID’s. So our preparations should include entering the correct percentages for the relevant AUDITID’s.
In the Microsoft version, the keyword GET could be used to retrieve the stored values. In the Netweaver version we use the tuple syntax instead. Our second step is to replace the hard-coded percentage values with references to values stored in the database. The script below shows how this can be done using the tuple syntax.
*REC(FACTOR = [ACCOUNT].[INCPERC], ACCOUNT = PL5119, AUDITID = CALCRES)
We only specify the account here which implies that the percentages are stored with the same level of detail as our data entry. This is done to keep our business case simple. In practice, percentages are usually entered at a much higher level so that a single value is used by all profit centers, for all periods of the year etc. So the tuple part of a real-life script would include more dimensions. Percentage values are typically entered centrally at the beginning of the planning cycle. Entry may also be decentralized and the timing can vary depending on the process requirements.
Our third and final step is to replace the static target account with a dynamic statement. In this example, we use ACCOUNT property TRGTACCT to determine the posting account. AUDITID can remain hard-coded because it never changes in our example.
*REC(FACTOR = [ACCOUNT].[INCPERC], ACCOUNT = ACCOUNT.TRGTACCT, AUDITID = CALCRES)
The script shown below wraps it all up. You will notice that this dynamic script is much shorter than the original static version. More importantly, this script will not need to be changed when ACCOUNT and AUDITID members are updated. It is compatible with driver-based planning and it can cover many scenarios that would not be feasible with hard-coded values.
*SELECT(%AUDITSRC%, ID, AUDITID, SRCTYPE= PAYR)
*SELECT(%ACCOUNTSRC%, ID, ACCOUNT, SRCTYPE= PAYR)
*XDIM_MEMBERSET AUDITID = %AUDITSRC%
*XDIM_MEMBERSET ACCOUNT = %ACCOUNTSRC%
*WHEN AUDITID
*IS *
*REC(FACTOR = [ACCOUNT].[INCPERC], ACCOUNT = ACCOUNT.TRGTACCT, AUDITID = CALCRES)
*ENDWHEN
Sometimes you might want to use a LOOKUP instead of a tuple. This is the case when the driver values are stored in a separate model or if you require more flexible use of properties in your rules. Here’s an example how you can use a lookup in your REC statement.
*REC(FACTOR = LOOKUP(LINCPERC), ACCOUNT = ACCOUNT.TRGTACCT, AUDITID = CALCRES)
If you want to select accounts using hierarchy nodes instead of property values you can use a script like the one below. In this example, PL5000 is the hierarchy node you want to select. Keyword BAS is used to determine the base levelmembers under PLNODE. I prefer properties because they allow more flexibility than a hierarchy selection but it all depends on your needs and setup.
*SELECT(%ACCOUNTSRC%, ID, ACCOUNT, ID = PL5000)
*XDIM_MEMBERSET ACCOUNT = BAS(%ACCOUNTSRC%)
Script Logic is readily accessible to and easily understood by most business users. Using Script Logic instead of ABAP means that the solution can continue to be owned by the business with minimum IT expert involvement.
We have already seen how easy it is to write dynamic script that requires few if any changes when accounts or other members are added. In the third part of this series we will delve deeper and learn how to harness the immense power of Script Logic variables.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.