Bu makalede ABAP’ ta en çok ihtiyaç duyulan işlemlerden biri olan “batch programlama” yı bir örnek ile açıklamaya çalışacağım. Abapçının olmazsa olmazı olan stoğundan gerekli bir parça daha, faydalı olması dileklerimle 😉
(Not1: Batch programının amacı bazı verilerin işlem yapmadan excelden veya txt gibi dosya formatında SAP’ a aktarılmasıdır)
Programın amacı X şirketinde PA30 da personellerin tek tek elle girilen bilgilerini exel’den SAP a aktarmak. -Bir personel için 3 farklı para birimi için hesap açılmaktadır. –
(Not2: Pa30 işlem kodu personel bazlı işlemlerin yapıldığı programdır. )
Ekran görüntüleri ile adım adım neler yapılacağını ve kod parçamızı görelim :
Önce banka bilgilerinin girilmesi için yapılan işlemler dizisi :
2. Pa30 da ilk olarak personel numarası girilir. Daha sonra bilgi tipi (banka detayları) seçilir. Ve sağ üstte yarat butonuna tıklanır.
3.Açılan yeni sayfada gerekli alanlar doldurulur ve kaydedilir.
4. Kaydettikten sonra PA30 ekranına geri dönülür ve butonuna tıklanır. Burada bütün kayıtlar görüntülenir.
Burada kayıt göründüğü anda işlem tamam demektir. Ancak her personel için maddelerin tek tek yapıldığını ve her personelin minimum üç hesabı olduğunu düşünürsek inanılmaz iş yükü çıkıyor ve bu noktada “batch programı” devreye giriyor.
Programı geliştirmek için yapılacak işlemler dizisi
1. SHDB işlem koduna girilir. İlk kayıt ismi girilerek “kayıt yarat” butonuna tıklanır.
2.Yarat butonuna tıkladıktan sonra açılan ekranda işlem koduna PA30 girilir ve kaydı başlata tıklanır.
3.Kaydı başlata tıklandıktan sonra PA30 da olduğu gibi erkan gelir. Burada yukardaki gibi işlemler yapılır . Personel numarası ve bilgi tipi girilir.
4.Banka ayrıntısının detayı girilir(detaylar için enterı kullanıyoruz)
5. Kaydet’e tıklanır ve bu kısım kullanılarak BDC programlama gerçekleştirilir.
Gelelim kod kısmına :
*&---------------------------------------------------------------------* *& Report ZHR_BATCH_BANK_INFO *& *&---------------------------------------------------------------------* *& *& *&---------------------------------------------------------------------* REPORT zhr_batch_bank_info. ********************************************************************** TYPE-POOLS : truxs , slis . “** Alv için gerekli veri tanımları DATA: fieldcatalog TYPE slis_t_fieldcat_alv WITH HEADER LINE, gd_layout TYPE slis_layout_alv, gd_repid LIKE sy-repid, g_save TYPE c VALUE 'X', g_variant TYPE disvariant, gx_variant TYPE disvariant, g_exit TYPE c . TABLES : pa2001,pa0000 . ********************************************************************** “** excelden okunacak veri tipinde bir type tanımlanması TYPES : BEGIN OF ty_out , pernr TYPE pa0009-pernr , begda TYPE char10, endda TYPE char10, bnksa TYPE pa0009-bnksa, emftx TYPE q0009-emftx, banks TYPE pa0009-banks, bankl TYPE pa0009-bankl, bankn TYPE pa0009-bankn, iban00 TYPE q0009-iban00, zlsch TYPE pa0009-zlsch, waers TYPE pa0009-waers, END OF ty_out. “** alv de gösterilecek veri tipinde bir type oluşturuma . TYPES : BEGIN OF ty_alv , sel TYPE flag, pernr TYPE pa0009-pernr , begda TYPE char10, endda TYPE char10, bnksa TYPE pa0009-bnksa, emftx TYPE q0009-emftx, banks TYPE pa0009-banks, bankl TYPE pa0009-bankl, bankn TYPE pa0009-bankn, iban00 TYPE q0009-iban00, zlsch TYPE pa0009-zlsch, waers TYPE pa0009-waers, durum TYPE char20, hata_log TYPE string, END OF ty_alv. “** gerekli tanımlamaların yapılmsı. DATA : lv_error_t100 TYPE natxt. DATA : lv_hata_log TYPE string. DATA : lt_alv TYPE TABLE OF ty_alv. DATA : ls_alv TYPE ty_alv. DATA : gt_excel TYPE TABLE OF ty_out . DATA : gs_excel TYPE ty_out . DATA : gt_excel_pernr TYPE TABLE OF ty_out. DATA : gs_excel_pernr TYPE ty_out. DATA : gt_type TYPE truxs_t_text_data. DATA : messtab TYPE STANDARD TABLE OF bdcmsgcoll WITH HEADER LINE. DATA : bdcdata LIKE bdcdata OCCURS 0 WITH HEADER LINE. DATA : lv_email TYPE comm_id_long. DATA : lt_rec TYPE bcsy_smtpa. DATA : ls_rec TYPE ad_smtpadr. DATA : lt_body TYPE srm_t_solisti1. DATA : ls_body TYPE solisti1. DATA : lv_hesaplar TYPE string. ********************************************************************** “** batch için gerekli makroların tanımlanması p olan shdb deki program ve “** ekran değerlerinin girileceği yerdir. f ise filedler ve değerleri için. DEFINE p. clear bdcdata. move : &1 to bdcdata-program, &2 to bdcdata-dynpro , 'X' to bdcdata-dynbegin. append bdcdata. END-OF-DEFINITION. DEFINE f. clear bdcdata. move : &1 to bdcdata-fnam, &2 to bdcdata-fval. append bdcdata. END-OF-DEFINITION. “** mail body si için gerekli makro. DEFINE satir_ekle. ls_body-line = &1. append ls_body to lt_body . clear : ls_body. END-OF-DEFINITION. ********************************************************************** “burada parametre olarak alınan dosya yolu var ve f4 yardımı var . PARAMETERS : p_file LIKE rlgrap-filename. AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file. CALL FUNCTION 'F4_FILENAME' EXPORTING field_name = 'P_FILE' IMPORTING file_name = p_file. START-OF-SELECTION. “** kod başladıktan sonra excel deki veriyi oku ve gt_excel itabına at. REFRESH gt_excel[]. CALL FUNCTION 'TEXT_CONVERT_XLS_TO_SAP' EXPORTING * i_field_seperator = 'X' i_line_header = 'X' i_tab_raw_data = gt_type i_filename = p_file TABLES i_tab_converted_data = gt_excel EXCEPTIONS conversion_failed = 1 OTHERS = 2. IF sy-subrc NE 0 . MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. ENDIF. START-OF-SELECTION. PERFORM create_batch. PERFORM build_fieldcatalog. PERFORM display_alv_report. *&---------------------------------------------------------------------* *& Form build_fieldcatalog *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* “** burda alv de gözükecek alanların düzenlenmesi işlemi yapılıyor. FORM build_fieldcatalog . DATA lv_colpos TYPE i . “** makro ile alv ye alan ekleme işlemleri yapılacak. Bu yüzden makro “**tanımlanır. DEFINE add_fctalog . fieldcatalog-fieldname = &1 . fieldcatalog-seltext_m = &2. fieldcatalog-col_pos = lv_colpos . lv_colpos = lv_colpos + 1 . append fieldcatalog to fieldcatalog. clear fieldcatalog. END-OF-DEFINITION. “** makro ile field catalog yani alv düzeni oluşturulur. add_fctalog 'PERNR' 'Personel Numarası' . add_fctalog 'BEGDA' 'Başlangıç Tarihi' . add_fctalog 'ENDDA' 'Bitiş Tarihi' . add_fctalog 'BNKSA' 'Banka Kayıt Türü' . add_fctalog 'EMFTX' 'Personel Adı' . add_fctalog 'BANKS' 'Banka Ülke Anahtarı' . add_fctalog 'BANKL' 'Banka Anahtarı' . add_fctalog 'BANKN' 'Banka Hesabi' . add_fctalog 'IBAN00' 'IBAN' . add_fctalog 'ZLSCH' 'Ödeme Biçimi' . add_fctalog 'WAERS' 'Para Birimi' . add_fctalog 'DURUM' 'Kayıt Durumu' . add_fctalog 'HATA_LOG' 'Hata Logu' . ENDFORM. "build_fieldcatalog *&---------------------------------------------------------------------* *& Form display_alv_report *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* “** burada alv gösterme işlemleri burada. Standart işlemler olduğu için “** açıklamaya gerek yok FORM display_alv_report . gd_repid = sy-repid. gd_layout-box_fieldname = 'SEL'. gd_layout-zebra = abap_true. gd_layout-colwidth_optimize = abap_true. CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY' EXPORTING i_callback_program = gd_repid i_callback_pf_status_set = 'SET_PF_STATUS' i_callback_user_command = 'USER_COMMAND' it_fieldcat = fieldcatalog[] i_save = 'X' is_layout = gd_layout * is_variant = g_variant TABLES t_outtab = lt_alv EXCEPTIONS program_error = 1 OTHERS = 2. IF sy-subrc <> 0. ENDIF. ENDFORM. "display_alv_report *&---------------------------------------------------------------------* *& Form set_pf_status *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * -->RT_EXTAB text *----------------------------------------------------------------------* “** pf status üst butonların çalışması vs o yüzden oluşturmak gerekiyor. FORM set_pf_status USING rt_extab TYPE slis_t_extab. SET PF-STATUS 'SET_PF_STATUS' . ENDFORM. "set_pf_status *&---------------------------------------------------------------------* *& Form CREATE_BATCH *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * --> p1 text * <-- p2 text *----------------------------------------------------------------------* “** asil batch işlemi burada. Burada amaç bir personel için kayıtlar atılacak ve atılan kayıtların bir kişi için birden çok olabilir açılan hesaplar kişiye mail olarak atılacak. FORM create_batch . gt_excel_pernr[] = gt_excel[]. SORT gt_excel_pernr BY pernr. DELETE ADJACENT DUPLICATES FROM gt_excel_pernr COMPARING pernr. LOOP AT gt_excel_pernr INTO gs_excel_pernr. LOOP AT gt_excel INTO gs_excel WHERE pernr = gs_excel_pernr-pernr. p: 'SAPMP50A' '1000'. f: 'BDC_OKCODE' '/00', 'RP50G-PERNR' gs_excel-pernr, 'BDC_SUBSCR' '/1PAPAXX/HDR_30000A 0100SUBSCR_HEADER', 'BDC_SUBSCR' 'SAPMP50A 0320SUBSCR_ITMENU', 'BDC_SUBSCR' 'SAPMP50A 0330SUBSCR_TIME', 'RP50G-TIMR6' 'X', 'BDC_SUBSCR' 'SAPMP50A 0350SUBSCR_ITKEYS', 'BDC_CURSOR' 'RP50G-CHOIC', 'RP50G-CHOIC' '9'. p: 'SAPMP50A' '1000'. f: 'BDC_CURSOR' 'RP50G-PERNR', 'BDC_OKCODE' '=INS', 'RP50G-PERNR' gs_excel-pernr, 'BDC_SUBSCR' '/1PAPAXX/HDR_30000A 0100SUBSCR_HEADER', 'BDC_SUBSCR' 'SAPMP50A 0320SUBSCR_ITMENU', 'BDC_SUBSCR' 'SAPMP50A 0330SUBSCR_TIME', 'RP50G-TIMR6' 'X', 'BDC_SUBSCR' 'SAPMP50A 0350SUBSCR_ITKEYS'. p: 'MP000900' '2000'. f: 'BDC_CURSOR' 'Q0009-IBAN00', 'BDC_OKCODE' 'UPD', 'P0009-BEGDA' gs_excel-begda, 'P0009-ENDDA' gs_excel-endda, 'P0009-BNKSA' gs_excel-bnksa, 'Q0009-EMFTX' gs_excel-emftx, 'P0009-BANKS' gs_excel-banks, 'P0009-BANKL' gs_excel-bankl, 'P0009-BANKN' gs_excel-bankn, 'Q0009-IBAN00' gs_excel-iban00, 'P0009-ZLSCH' gs_excel-zlsch, 'P0009-WAERS' gs_excel-waers, 'BDC_SUBSCR' 'MP000900 0100SUB0009', 'BDC_SUBSCR' 'SAPMP50A 0090SUBSCREEN_T582C'. CALL TRANSACTION 'PA30' USING bdcdata MODE 'N' UPDATE 'S' MESSAGES INTO messtab. CLEAR :lv_hata_log. LOOP AT messtab WHERE msgtyp = 'E'. CLEAR : lv_error_t100. SELECT SINGLE text FROM t100 INTO lv_error_t100 WHERE sprsl = 'T' AND arbgb = messtab-msgid AND msgnr = messtab-msgnr . CONCATENATE lv_hata_log lv_error_t100 INTO lv_hata_log SEPARATED BY space. ENDLOOP. MOVE-CORRESPONDING gs_excel TO ls_alv. IF lv_hata_log IS INITIAL. ls_alv-durum = 'Başarılı'. CLEAR :ls_alv-hata_log . APPEND ls_alv TO lt_alv. CONCATENATE lv_hesaplar gs_excel-iban00 INTO lv_hesaplar SEPARATED BY '/'. ELSE. ls_alv-durum = 'Hata Oluştu'. ls_alv-hata_log = lv_hata_log. APPEND ls_alv TO lt_alv. ENDIF. REFRESH : bdcdata , messtab. CLEAR : bdcdata , gs_excel , ls_alv. ENDLOOP. ********************************************************************** ** mail at bakalım.. SELECT SINGLE usrid_long FROM pa0105 INTO lv_email WHERE pernr = gs_excel_pernr-pernr AND usrty = '0010' AND endda = '99991231'. CONDENSE lv_email NO-GAPS . ls_rec = lv_email . APPEND ls_rec TO lt_rec.CLEAR ls_rec. satir_ekle '<HTML>'. satir_ekle '<head>' . satir_ekle '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>'. satir_ekle '</head>'. satir_ekle '<body>'. satir_ekle 'Merhaba;'. satir_ekle '<br /><br />'. satir_ekle 'Banka bilgileriniz aşağıdaki gibidir.'. satir_ekle '<br />' . satir_Ekle 'IBAN numaralarınız : '. satir_ekle lv_hesaplar. satir_ekle '<br /><br />'. satir_ekle 'Bilgileri Yukarıdaki gibi olan personelin lokasyonu değişmiştir.'. satir_ekle '<br /><br /><br />'. satir_ekle 'Bilginize.'. satir_ekle '</body>'. satir_ekle '</html>'. IF lv_hesaplar is NOT INITIAL. CALL FUNCTION 'ZHR_LOKASYON_MAIL_AT' EXPORTING ip_rec = lt_rec * IP_REC_CC = ip_body = lt_body ip_sender = 'info.bank@avea.com.tr' ip_header = 'Banka Bilgileriniz Hakkında Bilgilendirme'. ENDIF. REFRESH : lt_rec ,lt_body. CLEAR : lv_hesaplar , gs_excel_pernr. ENDLOOP. ENDFORM. " CREATE_BATCH
ZHR_LOKASYON_MAIL_AT fonksiyonunun içeriği ise şöyle ;
(Not3: Exelli mail atma fonksiyonundan daha önce bahsetmiştik .)
FUNCTION ZHR_LOKASYON_MAIL_AT. *"---------------------------------------------------------------------- *"*"Local Interface: *" IMPORTING *" REFERENCE(IP_REC) TYPE BCSY_SMTPA *" VALUE(IP_REC_CC) TYPE BCSY_SMTPA OPTIONAL *" VALUE(IP_BODY) TYPE SRM_T_SOLISTI1 OPTIONAL *" REFERENCE(IP_SENDER) TYPE SO_REC_EXT *" REFERENCE(IP_HEADER) TYPE SO_OBJ_DES *"---------------------------------------------------------------------- DATA: lt_swastrtab TYPE TABLE OF swastrtab, lt_att TYPE solix_tab, gs_text TYPE soli, gt_text TYPE soli_tab , lv_length TYPE so_obj_len, it_rec TYPE bcsy_smtpa , it_rec_cc TYPE bcsy_smtpa , lv_status_mail TYPE bcs_stml, lv_date TYPE char10 , lv_date1 TYPE char10 , lv_datestr TYPE char21 , lv_intadd TYPE ad_smtpadr . LOOP AT ip_rec INTO lv_intadd. APPEND lv_intadd TO it_rec. CLEAR lv_intadd. ENDLOOP. LOOP AT ip_rec_cc INTO lv_intadd. APPEND lv_intadd TO it_rec_cc. CLEAR lv_intadd. ENDLOOP. DATA: lc_send_request TYPE REF TO cl_bcs, lc_document TYPE REF TO cl_document_bcs, lc_recipient TYPE REF TO if_recipient_bcs, lc_exception_info TYPE REF TO if_os_exception_info, lc_bcs_exception TYPE REF TO cx_bcs, lc_sender TYPE REF TO cl_cam_address_bcs. " part 1 - receivers DATA :receivers TYPE somlreci1_t . DATA :ls_rec TYPE somlreci1. DATA :l_pernr TYPE pernr_d , lv_so10 TYPE tdobname , lt_body TYPE srm_t_solisti1 , ls_body TYPE solisti1 , lv_header TYPE so_obj_des , lv_pdf_title TYPE so_obj_des , lv_sender TYPE so_rec_ext, lv_sender_add_type TYPE so_adr_typ VALUE 'INT', lv_doc_type TYPE so_obj_tp VALUE 'HTM' , lt_rec TYPE somlreci1_t, lv_subrc TYPE subrc . DATA: ls_cont TYPE solisti1, ls_head TYPE thead, lt_text TYPE TABLE OF tline, ls_text TYPE tline. lv_sender = ip_sender . lv_header = ip_header . DATA ls_adr6 TYPE adr6 . DATA ls_usr21 TYPE usr21 . CLASS:cl_cam_address_bcs DEFINITION LOAD, cl_abap_char_utilities DEFINITION LOAD. DATA lv_sender_address TYPE adr6-smtp_addr . lv_sender_address = lv_sender . LOOP AT ip_body INTO ls_body. CLEAR gs_text. gs_text-line = ls_body-line. APPEND gs_text TO gt_text. ENDLOOP. * DESCRIBE TABLE gt_text LINES lv_length. * lv_length = lv_length * 255 . * DATA lv_len TYPE so_obj_len . * * DATA : employeenumber LIKE bapi7004-pernr VALUE '1001'. * DATA : sequencenumber LIKE bapi7004_rl-sequencenumber VALUE '350'. * DATA : payslipvariant LIKE bapi7004-payslip_variant VALUE 'DF01'. * DATA : lv_xstring TYPE xstring. DATA : lv_isim TYPE so_obj_des. TRY. lc_send_request = cl_bcs=>create_persistent( ). lc_sender = cl_cam_address_bcs=>create_internet_address( i_address_string = lv_sender_address ). CALL METHOD lc_send_request->set_sender EXPORTING i_sender = lc_sender. LOOP AT it_rec INTO lv_intadd. lc_recipient = cl_cam_address_bcs=>create_internet_address( lv_intadd ). CALL METHOD lc_send_request->add_recipient EXPORTING i_recipient = lc_recipient i_express = '' i_copy = '' i_blind_copy = '' i_no_forward = ''. ENDLOOP. * Add recipient with its respective attributes to send request LOOP AT it_rec_cc INTO lv_intadd. lc_recipient = cl_cam_address_bcs=>create_internet_address( lv_intadd ). CALL METHOD lc_send_request->add_recipient EXPORTING i_recipient = lc_recipient i_express = '' i_copy = abap_true i_blind_copy = '' i_no_forward = ''. ENDLOOP. * Build the Main Document lc_document = cl_document_bcs=>create_document( i_type = 'HTM' i_subject = lv_header i_length = lv_length i_sensitivity = 'F' i_text = gt_text i_sender = lc_sender ) . * IF NOT li_content_hex IS INITIAL. * lc_document->add_attachment( * i_attachment_type = 'xls' * i_attachment_subject = lv_isim * i_attachment_size = lv_size * i_att_content_hex = li_content_hex ). * CLEAR lv_isim. * ENDIF. CALL METHOD lc_send_request->set_document( lc_document ). lv_status_mail = 'E'. CALL METHOD lc_send_request->set_status_attributes EXPORTING i_requested_status = 'E' i_status_mail = lv_status_mail. lc_send_request->set_send_immediately( 'X' ). CALL METHOD lc_send_request->send( ). COMMIT WORK. CATCH cx_bcs INTO lc_bcs_exception. ENDTRY . ENDFUNCTION.
Allah zihin açıklığı versin 🙂