Saturday, April 25, 2009

And now? Going back to ABAP?

So Oracle buys Sun and gets Solaris, Mysql, MaxDB and Java. The first is a very important database but not very relevant to enterprise and SAP world (although it is used in SAP xMII). The second (previously named SAP DB) is the core to SAP APO LiveCache. And the last, the Java programming language, is the programming environment on which most new SAP products are developed and is also used for the cross platform GUI. And I would guess a lot of customers run on Solaris.

Before this purchase Oracle already had the most used database in SAP deployments. Is it me, or this is too much Oracle on SAP's backyard? If it was in my house, I would start doing some cleaning.

Labels:

Sunday, March 22, 2009

Marked Cell in Demand Planning Macros

I wanted to allow the users to choose a planning book cell, then click on a macro button to open a pop-up window with additional information related to the cell. But it does not seem to be possible to get the marked cell when developing planning book macros.

The standard macro functions PLOB_MARKED and COLUMN_MARKED work when selecting full rows and columns. Consider the following example macro:



It is possible to use that macro to identify a cell if the user selects both the row and column (pressing the control key to allow that kind of selection). But that is very user-unfriendly.



It turns out that most of the functionality for getting the marked cell in the macros is already available in the lower level macro functions. The standard function /SAPAPO/MARKED_ELEMENTS is used in the macro functions that return the marked row and column. That function also has information on the marked cell, so with some simple modifications it can be used for returning the selected cell.

It was easy to develop new functions to check the row (PLOB) for the marked cell and a function to check the column for the marked cell. Both call internally the modified /SAPAPO/MARKED_ELEMENTS and are based on the standard functions.

Then it is possible to develop macros that act on cells, to put the toolbar button for the macro and to open an ALV with cell detail information.



I still find it strange that marked cell macro is not available in the standard. Perhaps it is in some recent release. IMHO is a must have for planning books.

Labels: ,

Friday, January 23, 2009

No more smiles

No more smiles in ATP. Why SAP why?

Labels: ,

Monday, January 12, 2009

Another spell for the hacker book


The object oriented programming in APO uses in many cases the singleton pattern. An object static method (class method in standard object oriented talk) is used to obtain the object instance. If it is the first time the object is created and stored in a static attribute (class attribute). Then further calls to the method return the instance stored in the attribute. A practical result of this coding logic is that these objects become global structures of data because as long they were initialized at a given point of time, they are can be accessed at any later time just by calling the static method. For example, the object /SAPAPO/CL_ATPFIELD_BUF can be called in ATP user-exits to get the field catalog (some user-exits don’t have the field catalog available in the input parameters).


CALL METHOD /sapapo/cl_atpfield_buf=>get_atpfield
EXPORTING
iv_ordid = lv_ordid
iv_delps = lv_delps
IMPORTING
et_atpfield = lt_atpfield.


This works because the field catalog is stored in a static attribute of the object.

For global classes (like /SAPAPO/CL_ATPFIELD_BUF) this is very simple, but ABAP also allows the definition of local classes. For example, the main objects for the ATP calculation (LCL_REQUIREMENT_ATP, etc) are classes defined inside program /SAPAPO/SAPLATPT. I always wanted to have access to these objects inside user-exits (because it means having access to all ATP information). Something like this trick for global variables but able to access the objects.

After many failed attempts, this one works fine.


DATA:
l_name(150) TYPE c,
l_tabtype(150) TYPE c,
ldr_reqref TYPE REF TO data.

FIELD-SYMBOLS:
<reqref_t> TYPE ANY TABLE.

l_name = '\PROGRAM=/SAPAPO/SAPLATPT\CLASS=LCL_REQUIREMENT_ATP'.
l_tabtype = '\PROGRAM=/SAPAPO/SAPLATPT\TYPE=TBL_REQREF'.

CREATE DATA ldr_reqref TYPE (l_tabtype).
ASSIGN ldr_reqref->* TO <reqref_t> CASTING TYPE (l_tabtype).

CALL METHOD (l_name)=>get_instances
RECEIVING rt_reqref = <reqref_t>.


Now this pointer <reqref_t> is a pointer to a list of all LCL_REQUIREMENT_ATP object instances relevant for the current ATP check.

A Simple Controller

There are many ways to design a PAL model. The design that comes naturally to our minds is the one that splits the available quantity over a number of buckets (markets, plants, customers, etc).



This design is simple to understand, but from the point of view of automatic control it faces serious challenges. A control system would have to compute where to deallocate and where to allocate quantity. It becomes an optimization problem.

But let's see a different design (that was also part of this discussion). It checks first the capacity on the main buckets and then checks on a second level a capacity that is available for all orders (sequence of procedures).



Let's suppose we use monthly buckets and that at the start of the month the first procedure has 100% of total capacity and the second procedure has zero capacity. This is exactly as having just one level. Then as time passes the control system can read each bucket and compare the available capacity to some expected target value. If there is more free capacity than the target the system can reduce the bucket capacity and allocate the remaining to the second procedure.

The target open quantity can be one of many functions that return a profile of consumption over time. For example it could just be linear, linear within an internal interval or exponential as shown bellow.



This will make a control algorithm that is simple to understand and implement. And for many practical purposes it does what business expects (if a market is not consuming the quota, then it becomes available for the other markets).

Labels: , ,