1 Scenario
In BW-BPS a planning function can be executed by the end user directly in the user
interface (planning folders or web interfaces). These planning functions are executed
online and the user will have to wait until they are finished until he can proceed with his
task. Sometimes an end user wants to start a planning function that is a very long
running one and does not want to wait for the planning function to be finished before
continuing to work. It is possible to execute a planning sequence in batch but with the
current system setup this is a task that is usually performed only by super users or
administrators. The aim of this paper is show a method how a planning sequence (and
thus indirectly a planning function) can be started in a batch job by the end user by
simply pressing a button in the user interface.
2 Introduction
This paper shows how a planning function type Exit can be created that start planning
sequences in a batch process. The name of the planning sequence that is to be started
will be entered in the parameter group of the planning function. The planning function
(Exit) itself can be started in a web interface or a planning folder by simply pressing a
function button.
The sequence that runs in the batch will write a log so the end user can check whether
his batch job was executed correctly.
As the planning function type Exit is only used for starting the batch process and should
not perform any changes on the transaction data we use a planning package that
contains no data. This will make sure that
- there is no overlap with the selection of the planning sequence itself and thus no
locking issue will occur;
- as few time as possible is spent on the data selection (note: the minimum data
base time will be reached when selecting from an empty InfoCube that contains
just one characteristic and one key figure).
Note 1: The planning function that is executed in batch runs on a separate planning
buffer instance. That means that any unsaved data or variable settings the user has
made in the planning session from which the sequence is triggered will not be available
for the batch sequence! It is possible to force a save by calling the function module
API_SEMBPS_POST in the exit function BEFORE the sequence is triggered.
Note 2: If the planning sequence that is executed in the batch job has some data in
common with the current web interface or with the exit function used for starting the
batch job then there will be a locking issue. In the coding of the report
Z_BUNDLE_EXECUTE a work around for this problem can be used by un-commenting
the relevant lines (see below). The report will try to execute the planning sequence. If an
error occurs then the report will wait for one minute and try to execute the planning
sequence again. This procedure is repeated ten times. This gives the user enough time
to leave the web interface and release the locks after he has pressed the button for
starting the planning sequence in batch.
The Step By Step Solution
First of all we will implement the necessary function modules and reports.
3.1 Create the Report Z_BUNDLE_EXECUTE
1. This report will be called from the Init
module of the planning function and
is used to start the planning
sequence in batch. If you want to
use another name for the report you
will also have to adapt the coding for
the Init module. You will find the
coding in the Appendix. Use
transaction se38 to create the report.
3.2 Create the Function Modules for the Planning Function
2. Create the Init function module by
either using transaction se80 or
transaction se37. Use the coding
from the Appendix.
3. Create an empty Exit function
module. You can either copy the
function module TEMPLATE_EXIT
in the function group UPFX or use
this function module directly in your
planning function.
3.3 Create the Planning Function type Exit
4. In a given planning level create a
planning function type Exit. Enter the
name of the Init function module and
the name of the Exit function module
(either the one that you created or
use TEMPLATE_EXIT directly).
5. Create an Exit parameter that will be
used in the parameter group to
specify the planning sequence that
is to be started in batch. You can
create your own data dictionary field
or use the data dictionary field
char60.
3.4 Create the Parameter Group, Package, and End user Front end
6. Create one or several parameter
groups. Specify the names of the
planning functions that are to be
executed.
7. Create a planning package. As the
planning function is just used for
starting the sequence in batch it is
wise to crate a planning package
that will select no data on the data
base (see above). One could for
example use 0FISCYEAR = 9999.
8. You can now use you planning
function in any of the BPS front
ends, e.g. planning folders or web
interfaces.
3.5 Check the Execution of the Planning Sequence
9. Each user can check the execution
of his planning sequences. One has
to choose from the menu ‘System’
the entry ’Own Jobs’. The name of
the job is ‘BPS_BUNDLE_xxx’
where ‘xxx’ is replaced by the name
of the planning sequence. Additional
information can be found in the job
log. The same information can be
gained from the BPS0 when going to
the screen for planning sequences
and choosing the job overview.
4 Appendix: Coding
4.1 Report Z_BUNDLE_EXECUTE which executes the BPS Planning Sequence in Back Ground
*&———————————————————————*
*& Report Z_BUNDLE_EXECUTE
*&
*&———————————————————————*
*&
*&
*&———————————————————————*
REPORT Z_BUNDLE_EXECUTE.
DATA: lt_return TYPE bapiret2 OCCURS 0.
DATA: ls_return TYPE bapiret2.
DATA: ls_t100 LIKE t100.
DATA: g_dummy TYPE c.
DATA: g_s_log TYPE bal_s_log.
DATA: l_s_msg TYPE bal_s_msg.
data: l_log_handle type BALLOGHNDL.
data: lt_log_handle type BAL_T_LOGH.
PARAMETERS: bundle LIKE upf_bsteps-bundle.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR bundle.
CALL FUNCTION ‘UPF_AI_BUNDLE_VALUES_GET’
* EXPORTING
* I_DISPLAY =
CHANGING
x_bundle = bundle.
AT SELECTION-SCREEN.
START-OF-SELECTION.
DATA: l_subrc TYPE sy-subrc.
DATA: l_subrc2 TYPE sy-subrc.
CLEAR lt_return.
** Un-comment for workaround in case of locking problems
*do 10 times.
*
* Execute the global planning sequence
CALL FUNCTION ‘API_SEMBPS_GLSEQUENCE_EXECUTE’
EXPORTING
i_sequence = bundle
IMPORTING
e_subrc = l_subrc
TABLES
etk_return = lt_return.
IF l_subrc = 0.
* Save to data base
CALL FUNCTION ‘API_SEMBPS_POST’
IMPORTING
e_subrc = l_subrc2
es_return = ls_return.
if not ls_return is initial.
append ls_return to lt_return.
endif.
** Un-comment for workaround in case of locking problems
* exit.
* else.
* wait up to 60 seconds.
*
ENDIF.
** Un-comment for workaround in case of locking problems
*enddo.
*
* release the buffer
CALL FUNCTION ‘API_SEMBPS_REFRESH’.
* define some header data of this log
g_s_log-extnumber = ‘Bundle_Log’.
g_s_log-aluser = sy-uname.
g_s_log-alprog = sy-repid.
g_s_LOG-OBJECT = ‘SEM-BPS’.
G_s_LOG-SUBOBJECT = ‘FUNC’.
* create a log
CALL FUNCTION ‘BAL_LOG_CREATE’
EXPORTING
i_s_log = g_s_log
IMPORTING
e_log_handle = l_log_handle
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
LOOP AT lt_return INTO ls_return.
* define data of message for Application Log
CLEAR: l_s_msg.
l_s_msg-msgty = ls_return-type.
l_s_msg-msgid = ls_return-id.
l_s_msg-msgno = ls_return-number.
l_s_msg-msgv1 = ls_return-MESSAGE_V1.
l_s_msg-msgv2 = ls_return-MESSAGE_V2.
l_s_msg-msgv3 = ls_return-MESSAGE_V3.
l_s_msg-msgv4 = ls_return-MESSAGE_V4.
CALL FUNCTION ‘BAL_LOG_MSG_ADD’
EXPORTING
I_LOG_HANDLE = l_log_handle
i_s_msg = l_s_msg
EXCEPTIONS
log_not_found = 0
OTHERS = 1.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDLOOP.
if not lt_return is initial.
append l_log_handle to lt_log_handle.
CALL FUNCTION ‘BAL_DB_SAVE’
EXPORTING
* I_CLIENT = SY-MANDT
* I_IN_UPDATE_TASK = ‘ ‘
* I_SAVE_ALL = ‘ ‘
I_T_LOG_HANDLE = lt_log_handle
* IMPORTING
* E_NEW_LOGNUMBERS =
* EXCEPTIONS
* LOG_NOT_FOUND = 1
* SAVE_NOT_ALLOWED = 2
* NUMBERING_ERROR = 3
* OTHERS = 4
.
IF SY-SUBRC <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
endif.
CALL FUNCTION ‘BAL_DSP_LOG_DISPLAY’
* EXPORTING
* I_S_LOG_FILTER =
* I_T_LOG_CONTEXT_FILTER =
* I_S_MSG_FILTER =
* I_T_MSG_CONTEXT_FILTER =
* I_T_LOG_HANDLE =
* I_T_MSG_HANDLE =
* I_S_DISPLAY_PROFILE =
* I_AMODAL = ‘ ‘
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE ‘S’ NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
if l_subrc <> 0.
message id ‘UPC’ type ‘E’ number 308.
endif.
4.2 Init Function Module to call the report for execution os sequence in back ground
FUNCTION Z_BATCH_INIT.
*”———————————————————————-
*”*”Lokale Schnittstelle:
*” IMPORTING
*” REFERENCE(I_AREA) TYPE UPC_Y_AREA
*” REFERENCE(I_PLEVEL) TYPE UPC_Y_PLEVEL
*” REFERENCE(I_PACKAGE) TYPE UPC_Y_PACKAGE
*” REFERENCE(I_METHOD) TYPE UPC_Y_METHOD
*” REFERENCE(I_PARAM) TYPE UPC_Y_PARAM
*” REFERENCE(IT_EXITP) TYPE UPF_YT_EXITP
*” REFERENCE(ITO_CHASEL) TYPE UPC_YTO_CHASEL
*” REFERENCE(ITO_CHA) TYPE UPC_YTO_CHA
*” REFERENCE(ITO_KYF) TYPE UPC_YTO_KYF
*” EXPORTING
*” REFERENCE(ETO_CHAS) TYPE ANY TABLE
*” REFERENCE(ET_MESG) TYPE UPC_YT_MESG
*”———————————————————————-
data: ls_exitp like line of it_exitp,
ls_mesg like line of et_mesg,
l_jobname LIKE TBTCJOB-JOBNAME,
l_jobcount LIKE TBTCJOB-JOBCOUNT,
l_bundle like upf_bsteps-bundle.
read table it_exitp index 1 into ls_exitp.
if sy-subrc <> 0.
exit.
endif.
concatenate ‘BPS_BUNDLE_’ ls_exitp-chavl into l_jobname.
CALL FUNCTION ‘JOB_OPEN’
EXPORTING
jobname = l_jobname
IMPORTING
jobcount = l_jobcount
EXCEPTIONS
cant_create_job = 1
OTHERS = 2.
IF sy-subrc <> 0.
CLEAR ls_mesg.
ls_mesg-msgid = sy-msgid.
ls_mesg-msgty = sy-msgty.
ls_mesg-msgno = sy-msgno.
ls_mesg-msgv1 = sy-msgv1.
ls_mesg-msgv2 = sy-msgv2.
ls_mesg-msgv3 = sy-msgv3.
ls_mesg-msgv4 = sy-msgv4.
APPEND ls_mesg TO et_mesg.
EXIT.
ENDIF.
l_bundle = ls_exitp-chavl.
SUBMIT z_bundle_execute
WITH bundle = l_bundle
USER sy-uname VIA JOB l_jobname NUMBER l_jobcount
AND RETURN.
IF sy-subrc <> 0.
CLEAR ls_mesg.
ls_mesg-msgid = ‘UPC’.
ls_mesg-msgty = ‘E’.
ls_mesg-msgno = ‘306′.
ls_mesg-msgv1 = ‘Z_BUNDLE_EXECUTE’.
ls_mesg-msgv2 = l_jobname.
APPEND ls_mesg TO et_mesg.
EXIT.
ENDIF.
CALL FUNCTION ‘JOB_CLOSE’
EXPORTING
jobcount = l_jobcount
jobname = l_jobname
strtimmed = ‘X’
EXCEPTIONS
cant_start_immediate = 1
invalid_startdate = 2
job_close_failed = 4
job_nosteps = 5
job_notex = 6
lock_failed = 7
OTHERS = 8.
IF sy-subrc <> 0.
CLEAR ls_mesg.
ls_mesg-msgid = sy-msgid.
ls_mesg-msgty = sy-msgty.
ls_mesg-msgno = sy-msgno.
ls_mesg-msgv1 = sy-msgv1.
ls_mesg-msgv2 = sy-msgv2.
ls_mesg-msgv3 = sy-msgv3.
ls_mesg-msgv4 = sy-msgv4.
APPEND ls_mesg TO et_mesg.
EXIT.
ENDIF.
CLEAR ls_mesg.
ls_mesg-msgid = ‘UPC’.
ls_mesg-msgty = ‘S’.
ls_mesg-msgno = ‘305′.
ls_mesg-msgv1 = l_jobname.
APPEND ls_mesg TO et_mesg.
ENDFUNCTION.
*————————————————– END————————-