TagAbap

Debug Story – BAdI not implemented for appset …

It was started couple days ago. Two of my colleagues reporting issue regarding write back data on a BPC Environment Model. We’ve never have this problem before. The write back engine run smoothly on every model in every situation.

So I start to debug several spots to understand what’s going on.

The error caused by Exception cx_badi_not_implemented which generated by method,
Find BAdI implementation,
GET BADI lo_badi
FILTERS
appset_id = d_appset_id
application_id = d_appl_id
module_id = ds_wb_param-work_status-module_id.

So, my first attempt I try to by pass this procedure by change flag ds_wb_param-execute_badi into abap_false.
But, on the following step there is more validation for this exception.

My second attempt would be checking the the object of lo_badi which reference into BAdI badi_ujr_write_back. There are two implementations using this enhancement spot. I’m guessing since this implementation we need to input appset_id, application_id, & module_id so we get the right implementation.
But the write back we used comes from standard process, it doesn’t make any sense if the implementation doing something wrong with standard process. So I crossed this possibility and start to think another option.

Then I tried to debug deeper.
The next guess would be my third attempt.
I found the same exception showed on method CL_UJV_VALIDATION_MGR -> CHECK_VALIDATION.
Try to dig deeper, I found the table UJV_MODULES which for BPC Validations – Module On/Off Table.
And there is only one record for that model. *AHA

So i googled little bit then found out that TCode UJ_VALIDATION which generate the record for tables UJV_MODULES.

Then I ask permission one of my senior if he still using the validation or not. Then Turning off validation for that model. It works like a charm.
Problem Solved

for further information on how UJ_VALIDATION works or how to use it check:
UJ_VALIDATION

Generate Notification from Measurement Reading

Last week I have this requirement from PM module to generate notification (IW28) from measurement reading. This requirement trigger from save button on tcode IK11 or IK22.

At first I was told by functional to use user exit on IMRC0001 with function module EXIT_SAPLIMR0_001. But somehow, the BAPI is not working, dump with ‘type_message_x’ error. The 001 exit is used on save-event. I try to move the code into another exit which is ..004 the BAPI is working. I guess the problem occur because of transaction already using commit whenever save-event but then the BAPI try using it again. Then I move the code another place before the measurement document created, the moment before commit. The BAPI works like a charm. And the notification created succesfully.

Whenever measurement reading are outside range of measuring point program will automatic generate notification. The measurement reading refers to measuring point that could be access on tcode IK03.
Input Measuring Point > Click Additional Data > Upper-Lower Limit Showed.

We use BAPI to create notification on IW28. Below are snippet code sequence of BAPI.


gw_notifheader-short_text = lv_stext.
        gw_notifheader-priority = '1'.
*gw_notifheader-reportedby = imrg_ins-readr.
        gw_notifheader-reportedby = gw_imrg-readr.
        gw_notifheader-notif_date = sy-datum.

        CALL FUNCTION 'BAPI_ALM_NOTIF_CREATE'
          EXPORTING
*           EXTERNAL_NUMBER    =
            notif_type         = 'M2'
            notifheader        = gw_notifheader
*           TASK_DETERMINATION = ' '
*           SENDER             =
*           ORDERID            =
*           IV_DONT_CHK_MANDATORY_PARTNER       =
*           NOTIFCATION_COPY   =
*           DOCUMENT_ASSIGN_COPY                = ' '
          IMPORTING
            notifheader_export = gw_notifheader_exp.
* TABLES
*   NOTITEM     =
*   NOTIFCAUS   =
*   NOTIFACTV   =
*   NOTIFTASK   =
*   NOTIFPARTNR =
*   LONGTEXTS   =
*   KEY_RELATIONSHIPS                   =
*   RETURN      =
        .

        CALL FUNCTION 'BAPI_ALM_NOTIF_SAVE'
          EXPORTING
            number      = gw_notifheader_exp-notif_no
*           TOGETHER_WITH_ORDER       = ' '
          IMPORTING
            notifheader = gw_notifheader_res
*  TABLES
*           return      = .
          .

        CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
          EXPORTING
            wait = 'X'
* IMPORTING
*           RETURN        =
          . 

For note,
IK11 is tcode for creating single measurement document and IK22 for creating multiple measurement document. There is no problem when using one measurement point, but when dealing with multiple measuring point like IK22 you need to determine which measuring point are not initial. What I meant is try accessing IK22 then click ‘All Measuring Point Object’. Then all measuring point showed. If you dont get the right table to be pass over the transaction, The BAPI will create notification for initial measuring reading.

So which is the right table? the clue is IMRG_BUF. All you need is to find the right spot before the table is clear.

Posting Batch Using BAPI

So last month I’m working on program that have requirement to read material from barcode scanner on warehouse that needs to integrate it with SAP.
For specific material there is a case that I think it’s interesting and challenging to program for beginner like me.
The material is ‘CABLE’. The business process is for the piece of cable that already cut off must be registered as a batch. The batch number contain cable information where it’s ‘cut from’ and ‘cut to’ of material master (cable).

In standard SAP program we can use it standard TCode ‘MSC1N’.

In order to post batch programmaticaly using BAPI as requirement, there are some steps which must be done.
Why? because I can’t find the right BAPI or I haven’t found the right parameter to create batch with all information inside ‘MSC1N’ transaction. So, the approach that I’m using is create the batch first, then put additional information using BAPI_OBJCL_CHANGE.
The sequence I use are :

> BAPI_BATCH_CREATE
> BAPI_OBJCL_CONCATENATEKEY
> BAPI_OBJCL_GETDETAIL
> BAPI_OBJCL_CHANGE
> BAPI_TRANSACTION_COMMIT

We need to create it batch first to get batch number (CHARG). Concatenate matnr and batch number key. The output of this function will be used for paramtern OBJECTKEY in ‘BAPI_OBJCL_GETDETAIL’ . Get information for specific material number and batch number for initialization. Function ‘BAPI_OBJCL_CHANGE’ is used to stored the information Batch Feeder, Cutting From and Cutting To.


WHEN 'F1SAV'.
      PERFORM FM_GET_DATA.
      LOOP AT GI_PO_BATCH INTO GW_PO_BATCH.
        GW_BATCH_ATTR-VENDRBATCH = GW_PO_BATCH-BATCH_REEL.
        GW_BATCH_CTRL-DOCLASSIFY = 'X'.

        "BAPI_BATCH_CREATE
        PERFORM FM_SAVE_BATCH USING GW_PO_BATCH GW_PO_ITEM GW_BATCH_ATTR GW_BATCH_CTRL.
        MODIFY GI_PO_BATCH FROM GW_PO_BATCH
        TRANSPORTING CHARG.
        LOOP AT GI_PO_ITEM INTO GW_PO_ITEM WHERE EBELP = gw_po_item-EBELP.
          GW_PO_ITEM-CHARG = GW_PO_BATCH-CHARG.
          MODIFY GI_PO_ITEM FROM GW_PO_ITEM
          TRANSPORTING CHARG.
        ENDLOOP.

        "BAPI_OBJCL_CONCATENATEKEY
        PERFORM FM_BATCH_CONCATENATE USING GW_PO_BATCH GW_PO_ITEM
                                     CHANGING W_OBJECT.
        "BAPI_OBJCL_GETDETAIL 
        PERFORM FM_BATCH_GETDETAIL USING W_OBJECT.
        PERFORM FM_CHECK_BATCHNUM.

        "Initialize itab NUMTAB & CHATAB
        PERFORM FM_INITIAL_NUMTAB.
        PERFORM FM_INITIAL_CHATAB.
        
        "BAPI_OBJCL_CHANGE
        PERFORM FM_BATCH_CHANGE USING GW_PO_BATCH GW_PO_ITEM.
        PERFORM FM_BAPI_CHANGE USING W_OBJECT.

        WAIT UP TO 1 SECONDS.

      ENDLOOP.

Double Click ALV Object into T-Code

So yesterday, I’ve got requirement that the user want to make some number inside their ALV object to be linked (clickable) into standard tcode. Since I’m not the original developer I need to read the code first and understand what kind of technology inside that code. This feature is similar to ‘VL10E’.

Then I found that ALV they are using is ALV Hierarchy. Since the ALV they are using still using function module ALV ,”REUSE_ALV_HIERSEQ_LIST_DISPLAY” (I don’t know what they called exactly), and I am usually using ALV OO, so I need to debug it first to see how event double click is read inside ALV.

I type /h in transaction field then watch every step (or you could set up a watchpoint) until entering the program. It turned out they already prepare the user_command like in ALV. Then I put some code inside ‘&IC1’ condition. Set the parameter and call the tcode.


SET PARAMETER ID: 'KTN' FIELD GW_HEADER-VBELN.
CALL TRANSACTION 'VA43' AND SKIP FIRST SCREEN.   

example source:
FM_ALV_USER_COMMAND

Conversion Routine

What is Conversion Routine?
Conversion Routine is used to convert the value stored in SAP (input) into value that showed in screen (output) or vice-versa.

When we use this?
Let’s say you have document number ‘3141592’, with datatype VBELN_VA. If we look into detail, VBELN_VA have 10 lengths character in its format.
Somehow and you want to use function module or BAPI that need to input the document number.
You wonder why document number ‘3141592’ not showing result as you expected. But when you put leading zero ‘0003141592’ the function is working.
Instead of manually to code leading zero into document number. SAP already prepared the function to do that job.

If you want to save it into SAP format.

If you want to show the document number without leading zero.

How do we use this?
Call Function conversion routine that compatible with the data type is used.
Example :
for value with datatype VBELN_VA

CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
  EXPORTING
    INPUT         = lv_vbeln
 IMPORTING
   OUTPUT        = lv_vbeln
          .

How do we find the right conversion for given datatype?
1. Go to Tcode SE11
2. Input datatype > display
3. Double click domain for the datatype

4. If the datatype have conversion routine input field conversion routine is not initial. Click to show what conversion routine that available.

5. Double click to try the function module

================================================

Note:

CONVERSION ROUTINE – DATE

Not all datatype have conversion routine in their domain level.
For example datatype ‘DATUM’ that used for date format. You need to make extra effort to search it in function module. Or you could simply googling it.

If we have input date like ‘21.12.2014’ and we want to save it into database date format ‘20141221’, I use function module ‘CONVERSION_EXIT_PDATE_INPUT’.

for inverse process, I use ‘CONVERSION_EXIT_PDATE_OUTPUT’

ZDownload – Download your Program into HTML

Ever happened you need to document all of your source code from your project?
Or you need to backup the source code when somethings wrong with Server?
Tired of copy-paste-ing for each program and each include inside etc?

I use this program to download all ABAP program inside a package. So, that I have collection of program that it I might used in future. It’s no hassle at all.
Since this program using GNU Public License hence I post it on my blog. Credits to original developers. It makes our life easier 😀

ZDOWNLOAD

Analisa Into Corresponding Field vs Into Table

Dalam melakukan proses SELECT * kita sudah tau bahwa sebaiknya tidak menggunakan SELECT *, karena proses ini akan memilih semua field yang ada pada table. Agar efektif maka lebih baik kita memilih field yang diperlukan saja untuk dimasukan kedalam internal table. Untuk memasukan field ke internal table ada beberapa ABAPer yang menggunakan cara INTO TABLE dan ada yang menggunakanan INTO CORRESPONDING FIELDS OF TABLE.

Abaper yang menggunakan cara INTO TABLE beranggapan bahwa penggunaan INTO CORRESPONDING FIELDS OF TABLE tidak efektif karena akan mencocokan nama field sumber dengan semua field tujuan terlebih dulu.
Sedangkan penggunaan SELECT bsart ebeln bukrs harus disesuaikan dengan isi structure dari table internal tujuan.
Jadi penggunaan syntax SELECT diatas digunakan untuk mengisikan structure,

TYPES: BEGIN OF ty_ekko,
bsart LIKE ekko-bsart,
ebeln LIKE ekko-ebeln,
bukrs LIKE ekko-bukrs,
END OF ty_ekko.

Perhatikan urutan field yang di SELECT dengan urutan field dalam table, urutanya sama bsart ebeln bukrs. Oleh karena itu penggunaan INTO TABLE membutuhkan effort lebih dalam menempatkan urutan field.
Jika tidak sesuai dengan urutan fieldnya, sebagai contoh dengan structur yang sama kita menggunakan command SELECT bukrs bsart ebeln, maka field bsart akan terisi oleh record isian dari bukrs.
Namun hanya dengan proses pemasukan data kedalam internal table itu saja apakah proses INTO TABLE bisa lebih cepat dibandingkan dengan INTO CORRESPONDING FIELDS OF TABLE ?

Untuk pembuktianya akan dilakukan proses SQL Trace pada T-code ST05 untuk membandingkan runtime dari proses selection pada table dengan menggunakan dua cara,
Cara pertama menggunakan syntax INTO TABLE dengan snippet berikut,

SELECT bsart ebeln bukrs
INTO TABLE gi_ekko
FROM ekko
WHERE bsart = c_bsart.

Cara kedua menggunakan,

SELECT * INTO CORRESPONDING FIELDS OF TABLE gi_ekko
FROM ekko
WHERE bsart = c_bsart.

Jangan lupa sebelum melakukan proses selection table kita harus mengaktifkan SQL Trace terlebih dahulu dengan CALL FUNCTION 'SQLT_TRACE_ON'. Dan mematikanya dengan CALL FUNCTION 'SQLT_TRACE_OFF'. Atau jika tidak secara terprogram maka kita aktifkan dan deactive-kan secara manual lewat T-code ST05.
Dalam ST05 jika kita klik Display Trace (jangan lupa deactivate terlebih dahulu) maka akan tampil proses proses SQL yang telah dilakukan dalam rentang waktu tertentu.

SQL Trace List

Gambar 1. SQL Trace List

Dalam gambar diatas klik pada Menu item Trace List, kemudian pilih Combined Table Accesses.

Gambar 2. Combined Table Accesses

Gambar 2. Combined Table Accesses

Pada kolom Access Time terdapat runtime dalam unit miliseconds penggunaan SQL sebanyak 2 baris, sesuai dengan 2 proses SQL yang kita gunakan. Baris pertama penggunaan dengan INTO TABLE , baris kedua untuk INTO CORRESPONDING FIELDS OF TABLE.

Gambar 3. Table Summary

Gambar 3. Table Summary

Runtime keduanya jika dilihat tidak jauh berbeda, bahkan jika saya coba berulang ulang kali terkadang access time dari INTO TABLE bisa lebih cepat dari INTO CORRESPONDING FIELDS OF TABLE.
Mengapa hal ini bisa terjadi? Untuk mengetahui proses yang terjadi didalm lebih lanjut kita kembali lagi ke tampilan trace list awal pada gambar pertama. Pada operation REOPEN, klik pada bagian statement yang ada kemudian klik tombol Explain.
Pada SQL trace waktu penggunaan syntax INTO CORRESPONDING FIELDS OF TABLE , SQL statement yang diterjemahkan telah memilih field yang sesuai dengan structure yang dimiliki oleh internal table.

Gambar 4. Explain SQL Statement

Gambar 4. Explain SQL Statement

ABAP engine disini sudah pintar, sudah tau field field apa yang kita butuhkan tanpa harus memilih field field yang diperlukan sesuai dengan field yang telah di definisikan sesuai structurepada internal table.
Dapat disimpulkan bahwa penggunaan INTO CORRESPONDING FIELDS OF TABLE, tidak terlalu berbeda jauh runtimenya untuk memilih field field tertentu dari table.
Yah sejak awal belajar karena saya menggunakan INTO TABLE maka setelah membuktikan sendiri seperti ini sepertinya saya akan beralih menggunakan INTO CORRESPONDING FIELDS OF TABLE.

© 2018 Rijdz

Theme by Anders NorenUp ↑