Debugger-Scripting

To collect all the FM’s called by some application during the work I would use Debugger-Scripting.

Log of all ABAP commands of an application can be provided by script RSTPDA_SCRIPT_STATEMENT_TRACE

Drill down to debugging as usual, select the RSTPDA_SCRIPT_STATEMENT_TRACE
Check the box «Breakpoint reached» and create new one on «CALL FUNCTION» then start the script.

When everything will be done, /h into the command line, press F3 and then stop the script.

The transaction SAS can show the results:

Прокси-сервер в ABAP

Если вы из программы на ABAP пытаетесь получить веб-контент через HTTP, то соединение будет производиться не с компьютера клиента, а с сервера приложений. В зависимости от конфигурации локальной сети вам может понадобиться пробираться через прокси-сервер (иначе потребуется прямая видимость сервера или NAT).

При оформлении HTTP запроса можно непосредственно указать прокси-сервер:

if client is initial.
call method cl_http_client=>create
 exporting
  host  = 'www.example.com'
  proxy_host    = '192.168.1.1'
  proxy_service = '8080'
 importing
  client  = client
exceptions
  argument_not_found = 1
  internal_error     = 2
  plugin_not_active  = 3
  others             = 4.

Однако здесь есть пара моментов. Во-первых – хардкод в коде не приветствуется, а во-вторых – нет авторизации.

Глобальную настройку HTTP-прокси можно обнаружить в транзакции SM59:

И там уже в появившемся окошечке можно указать не только сервер/порт, но также и логин/пароль для авторизации.

© Иван Болховитинов

Важные слова не важны

В процессе написания кода по заданной спецификации неожижанно обнаружилось, что ключевые слова ABAP не являюся зарезервированными.
Поэтому нижеследующий код компилируется и даже выполняется:

TYPES TYPE.
 
DATA USING TYPE TYPE.
 
PERFORM FORM USING USING USING USING.
 
FORM FORM USING USING TYPE TYPE DATA LIKE USING TYPE TYPE TYPE.
 
  DATA = TYPE.
 
  DATA TO TYPE I.
  DATA ADD LIKE TO.
 
  ADD ADD TO TO.
 
  DATA IF.
  DATA EQ.
  DATA ENDIF.
  IF IF EQ EQ.
    MOVE TO TO ENDIF.
  ENDIF.
 
ENDFORM.

Даже если так писать и можно, то этого делать всё-таки не следует:

  • Усложняет восприятие, хотя есть и подсветка кода и uppercase/lowercase
  • Name-conventions
  • Ограничения при работе с БД
  • Это не смешно

Зато есть служебная таблица TRESE, в которой перечисляются разные наименования полей, которые нельзя создавать из-за ограниченний в разных БД.
© Иван Болховитинов

Geschützt: Propose next empty bin (WMS)

Dieser Inhalt ist passwortgeschützt. Um ihn anschauen zu können, bitte das Passwort eingeben:

Saving Word documents from ABAP

program ytrans.
 
******************************************************************
* TABLE DECLARATIONS.
******************************************************************
tables: e070, e07t.
 
data:  display type c,
       exit type c,
       ok_code like sy-ucomm,
       lo_form type ref to ytform,
       lf_test type ref to ytform,
       l_template type string value 'block',
       l_num type i,
       isource type table of string,
       xsource type t_source.
 
selection-screen begin of block standard.
select-options: p_skorr    for e070-strkorr,
                p_user     for e070-as4user no intervals default sy-uname,
                p_date     for e070-as4date.
selection-screen skip.
 
selection-screen end of block standard.
 
start-of-selection.
  types: begin of t_reqs,
    sel,
    strkorr like e070-strkorr,
    as4text like e07t-as4text,
    as4user like e070-as4user,
    as4date like e070-as4date,
  end of t_reqs.
 
  data: lt_reqs type standard table of t_reqs,
        wa_reqs type t_reqs. "like line of lt_reqs. "work area (header line)"
  select * from e070 inner join e07t on e070~strkorr eq e07t~trkorr
    into corresponding fields of table lt_reqs where e070~trkorr in p_skorr[] and
    e070~as4user in p_user[] and e070~as4date in p_date[] and e070~trstatus eq 'R'.
 
  xsource = '1.'. append xsource to isource.
  xsource = '2.'. append xsource to isource.
  xsource = '3.'. append xsource to isource.
  xsource = '4.'. append xsource to isource.
end-of-selection.
 
  perform alv_grid_display.
 
*&---------------------------------------------------------------------*
*&      Form  alv_grid_display
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
form alv_grid_display.
  type-pools: slis.
  data: it_fieldcat  type slis_t_fieldcat_alv,
        wa_fieldcat  type slis_fieldcat_alv,
        fs_layout type slis_layout_alv.
  fs_layout-box_fieldname = 'SEL'.
  fs_layout-zebra = 'X'.
 
  wa_fieldcat-fieldname  = 'STRKORR'.
  wa_fieldcat-seltext_m  = 'Номер запроса'.
  append wa_fieldcat to it_fieldcat.
  wa_fieldcat-fieldname  = 'AS4TEXT'.
  wa_fieldcat-seltext_m  = 'Описание'.
  append wa_fieldcat to it_fieldcat.
  wa_fieldcat-fieldname  = 'AS4USER'.
  wa_fieldcat-seltext_m  = 'Имя пользователя'.
  append wa_fieldcat to it_fieldcat.
  wa_fieldcat-fieldname  = 'AS4DATE'.
  wa_fieldcat-seltext_m  = 'Дата'.
  append wa_fieldcat to it_fieldcat.
 
  call function 'REUSE_ALV_GRID_DISPLAY'
    exporting
      it_fieldcat              = it_fieldcat
      is_layout                = fs_layout
      i_callback_program       = sy-repid
      i_callback_pf_status_set = 'SET_GUI_STATUS'
      i_callback_user_command  = 'COMMANDS_HANDLER'
    tables
      t_outtab                 = lt_reqs
    exceptions
      program_error            = 1
      others                   = 2.
endform.                    "alv_grid_display
*&---------------------------------------------------------------------*
*&      Form  set_gui_stat
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->RT_EXTAB   text
*----------------------------------------------------------------------*
form set_gui_status using rt_extab type slis_t_extab.
  set pf-status 'YSTATUS' excluding rt_extab.
  set titlebar text-005.
endform.                    "set_gui_status
 
*&---------------------------------------------------------------------*
*&      Form  STAT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->R_UCOMM      text
*      -->RS_SELFIELD  text
*----------------------------------------------------------------------*
form commands_handler using r_ucomm like sy-ucomm
rs_selfield type slis_selfield.
  data selfield type slis_selfield.
  data lt_sel type standard table of t_reqs.
  case r_ucomm.
    when 'QUIT'.
      leave program.
    when 'SELE'.
      delete lt_reqs where sel ne 'X'.
      set pf-status ''.
      call screen 0100.
  endcase.
endform.                    "STAT
 
*----------------------------------------------------------------------*
*  MODULE status_0100 OUTPUT
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
module status_0100 output.
  "class CL_ABAP_CHAR_UTILITIES definition load.
  data: io_text type string,
        lv_username type string,
        header_date type string,
        lv_commalist type string,
        lv_reqlist type string,
        lv_reqtext type string,
        lv_teststeps type string.
 
  field-symbols: <fs> like line of lt_reqs,
                 <fsi> like line of isource.
 
  case sy-ucomm.
    when 'TESTS'.
      editor-call for isource.
    when 'EXIT'.
      leave program.
    when 'GENERATE'.
      loop at lt_reqs assigning <fs> .
        concatenate <fs>-strkorr lv_reqlist into lv_reqlist separated by ';'.
        lv_reqtext = <fs>-strkorr && cl_abap_char_utilities=>horizontal_tab &&
                      <fs>-as4text && cl_abap_char_utilities=>cr_lf && lv_reqtext.
        lv_commalist = |{ <fs>-strkorr }, { lv_commalist }|.
      endloop.
 
      shift lv_reqlist right deleting trailing ';'. shift lv_reqlist left deleting leading space.
      shift lv_commalist right deleting trailing ', '.
 
      select single name_text from user_addrp into lv_username where bname = sy-uname.
      concatenate sy-datum+6(2) sy-datum+4(2) sy-datum(4) into header_date separated by '.'.
 
      sort isource descending.
      loop at isource assigning <fsi> .
        lv_teststeps = <fsi> && cl_abap_char_utilities=>horizontal_tab &&
                      lv_teststeps && cl_abap_char_utilities=>cr_lf.
      endloop.
 
      create object
        lo_form
        exporting
          i_template = 'Y_TRMAIN'.
 
      lo_form->replicate(
       i_template_id = l_template
       i_copy_num = 2
      ).
 
      lo_form->prep_seq_access( ).
      if lo_form->find_variable('header_date') eq abap_true.
        lo_form->set_value( header_date ).
      endif.
      if lo_form->find_variable('header_num') eq abap_true.
        lo_form->set_value( lv_commalist ).
      endif.
      if lo_form->find_variable('source_client') eq abap_true.
        lo_form->set_value( sy-mandt && space && sy-sysid ).
      endif.
      if lo_form->find_variable('dest_client') eq abap_true.
        lo_form->set_value('300 [PEW]').
      endif.
      if lo_form->find_variable('sec_nums') eq abap_true.
        lo_form->set_value( lv_commalist ).
      endif.
      if lo_form->find_variable('trans_list') eq abap_true.
        lo_form->set_value( lv_reqtext ).
      endif.
      if lo_form->find_variable('special') eq abap_true.
        lo_form->set_value( io_text ).
      endif.
      if lo_form->find_variable('owna') eq abap_true.
        lo_form->set_value( lv_username ).
      endif.
      lo_form->finish_seq_access( ).
      lo_form->clean( ).
 
      lo_form->display( sy-datum && '_' && lv_reqlist ).
 
      create object
        lf_test
        exporting
          i_template = 'Y_TESTS'.
 
      lf_test->replicate(
       i_template_id = l_template
       i_copy_num = 2
      ).
 
      lf_test->prep_seq_access( ).
      if lf_test->find_variable('header_date') eq abap_true.
        lf_test->set_value( header_date ).
      endif.
      if lf_test->find_variable('trans_list') eq abap_true.
        lf_test->set_value( lv_reqtext ).
      endif.
      if lf_test->find_variable('sec_nums') eq abap_true.
        lf_test->set_value( lv_commalist ).
      endif.
      if lf_test->find_variable('test_sys') eq abap_true.
        lf_test->set_value( 'TES310' ).
      endif.
      if lf_test->find_variable('test_steps') eq abap_true.
        lf_test->set_value( lv_teststeps ).
      endif.
      if lf_test->find_variable('special') eq abap_true.
        lf_test->set_value( io_text ).
      endif.
      if lf_test->find_variable('owna') eq abap_true.
        lf_test->set_value( lv_username ).
      endif.
      lf_test->finish_seq_access( ).
      lf_test->clean( ).
 
      lf_test->display( sy-datum && '_' && lv_reqlist && '_ПТ').
      leave program.
  endcase.
endmodule.                 " STATUS_0100  OUTPUT

Mapping columns on distributing into EWM

Firmenzentrale SAP

During distribuiton a delivery from ERP to EWM we can add some ERP-related data into EWM delivery tables:

/SCWM/IF_EX_MAPIN_OD_SAVEREPL~MAPIN
 
METHOD /scwm/if_ex_mapin_od_saverepl~mapin.
 
  DATA: lv_break TYPE char1,
        lt_vbeln TYPE TABLE OF zerp_get_pkkey_vbeln,
        lv_dest         TYPE char10.
 
  FIELD-SYMBOLS: <ls_item_data> LIKE LINE OF it_bapi_item_data,
                 <ls_vbeln> LIKE LINE OF lt_vbeln,
                 <ls_dlv_request> LIKE LINE OF ct_dlv_request,
                 <ls_keymap> TYPE /scdl/dl_keymap_item_str,
                 <ls_item> TYPE /scdl/af_dr_item_str.
 
  IF is_bapi_header_data-dlv_type = 'ZKBN'.
 
    LOOP AT it_bapi_item_data ASSIGNING <ls_item_data>.
      APPEND INITIAL LINE TO lt_vbeln ASSIGNING <ls_vbeln>.
      <ls_vbeln>-vbeln = <ls_item_data>-deliv_numb.
      <ls_vbeln>-posnr = <ls_item_data>-itm_number.
    ENDLOOP.
 
    lv_dest = zcl_ewm_main=>get_destination( ).
    CALL FUNCTION 'ZERP_GET_PKKEY' DESTINATION lv_dest
      TABLES
        it_vbeln = lt_vbeln
      EXCEPTIONS
        not_data = 1
        OTHERS   = 2.
    IF sy-subrc = 0.
      LOOP AT ct_dlv_request ASSIGNING <ls_dlv_request>.
        LOOP AT <ls_dlv_request>-t_item ASSIGNING <ls_item>.
          LOOP AT <ls_item>-t_keymap_item ASSIGNING <ls_keymap>.
            READ TABLE lt_vbeln ASSIGNING <ls_vbeln> WITH KEY vbeln = <ls_keymap>-docno
                                                              posnr = <ls_keymap>-itemno.
            IF sy-subrc = 0.
              <ls_item>-s_eew-zzpkkey = <ls_vbeln>-pkkey.
            ENDIF.
          ENDLOOP.
        ENDLOOP.
      ENDLOOP.
    ENDIF.
  ENDIF.
 
 
ENDMETHOD.

For SMW0

Own customer exit for JITL (JITPP)

Broadcast from jit.sap.sd/jitl:

Defining the production info describes principles of using the table JITPP («JIT : Production Information») – repetitive manufacturing (A), stock transfer (B) and customer exit (Z). Table field is JITPP-BAFLU.

The transaction for controlling this behaviour is JITL:

The last one (customer exit) is very typical customer-function call, which is calls from functional module JIT03_DO_BACKFLUSH (CALL CUSTOMER-FUNCTION ‹009›), so function EXIT_SAPLJIT03_009 transmits into include ZXJIT0U19 next structures:

JITDIABACKF_IT STRUCTURE  JITDIABACKF  "Aggregate Information on Call Components
JITBACKFTMP_CT STRUCTURE  JITBACKFTMP  "Backflush Data Call Components
JITIT_IT       STRUCTURE  JITIT        "Table of Components Groups Involved

*Modifikation der Rückmeldedaten

Häufig gestellte Fragen

  • Q: How to convert sy-datum type type to string DD.MM.YYYY?
    A: write sy-datum using edit mask ‹==PDATE› to lv_datestring.
  • Q: How to convert CHAR type to RAW type?
    A:

      types: begin of c16,
               aaa(16) type c, "CHAR(16)
             end of c16.
      types: begin of r16,
               aaa type guid_16, "RAW(16)
             end of r16.
      data: it_chars type table of c16,
            it_raws type table  of r16,
            c1(16) type c.
      c1 = '1234567890123456'.
      append c1 to it_chars.
      call method CL_RSZ_WWW_DB_INTERFACE=>CONVERT_CHAR_TO_RAW
        exporting
          I_T_IN  = IT_chars
        importing
          E_T_OUT = it_raws
  • Q: What does mean asterisk in front of the name?
    A: EKPO and *EKPO are usually defined in TABLES statement, and both use the DDIC structure of EKPO. Classical usage is to distinguish between old and new value of the record.
    SELECT SINGLE * FROM *bkpf is equal to SELECT SINGLE * FROM bkpf into *bkpf
    the same as SELECT SINGLE * FROM bkpf is equal to SELECT SINGLE * FROM bkpf into bkpf
  • While declaring variables, always follow the naming conventions through out your code. Your variable names talks a lot about its usage.
    Make sure your variables are of the form:

    {Prefix1}{Prefix2}_{Name} where:

    Prefix1:
    L – Local
    I – Import
    E – Export
    G – Global
    T – Table Type

    Prefix2:
    V – Single Value
    S – Structure
    T – Table
    R – Type ref to Data
    O – Type ref to Object
    E – Type ref to Exception objects

    Name – name of the variable.
    e.g.:
    lt_sel – local table
    lo_rvs – local object
    and so on.

    Before changing the parameters (type or name), make sure that you run “Where used”, make a note and change them as well.
    While working on ABAP Classes and Interfaces, Never change a super class of a framework. It could potentially bring all applications down. Double check to make sure that the code you change is in your class only.

    Ctrl + D Duplicate any line.
    Ctrl + . & Ctrl + , Comment and Un-Comment selected lines.
    Ctrl+Shift+X Deletes the whole line.
    Ctrl+Shift+V Gives All Paste options.
    To assist in locating codes, can be a bookmark, using a combination: CTRL + ALT + (0 to 9).
    To go to bookmark created, use combination CTRL + (0 to 9).

    • Q: How to debug IDOCs IBOUND processing (most first FMs on receiver system (under ALEREMOTE non dialog user)?
      A: Simple and stupid solution is to put eternal loop in form FA5_DOCUMENT_SYNTAX_CHECK (program LEDI1FA5):

      data: x type flag.
      *if sy-uname eq 'SAPSD'.
      while x is initial.
      endwhile.
      "endif.

      Then the process will be available for debugging in the transaction SM50.

    • Please create lock objects on the header tables and make sure that you obtain a lock before changes and release the lock after changes.
    • Make sure that you transactions are atomic. Either commit your work after all changes are successful or Rollback in case of error. If you rollback, make sure that you have released the locks.
    • Q: How to pass dynamic varable into SELECT … WHERE IN clause?
      A:

      data: lv_pabprfs type string,
               qry type string.
        select single param from zparam into lv_pabprfs where paramid  = 'PAPROFIL'.
        "lv_pabprfs = 'M033', 'M833', 'M843'
        qry = 'b~pabprf in (' && lv_pabprfs && ')'.
       
        select single baset into myvar from jitoco where outpo = '3' and (qry).
    • During save, please make sure that entries in all the text (_T_*) tables that relate to your modules are also saved. If no data exists, treat it as an error. (As across check, you can verify the same by executing the view and making sure that the data is returned correctly)
    • The Function should be RFC Enabled. Never raise an exception. Always return errors in the ET_RETURN (Type BAPIRET2) structure.
    • Never hardcode text strings. Make sure that you use a text element. But use it with text reference.
      E.g. If you have an error during validating the email, use it as «Email ID is required»(001) instead of using text-001. This will ensure that error messages are displayed regardless of user logon language.
    • At the end of the function, Always call «get details» and return the values as export/table values. This will serve the purpose of reflecting the data as-is in the DB back to the user and will save another round trip to retrieve it again.
    • Q: How to get variable value from another running program?
      A:

      "in case of needed programm isn't in the memory area, we can to call it via
      PERFORM change_control_record IN PROGRAM SAPMV50A.
        ld_mem = '(SAPMV50A)XLIPS[]'.
        ASSIGN (ld_mem) TO <mem>.
        IF sy-subrc = 0. "if ld_mem is assigned
          lt_xlips[] = <mem>.
        ENDIF.
    • Update audit fields created by, created date, created time only during create.
    • Please ensure that IV_UNAME (SY-UNAME) and IV_LANGUAGE (SY_LANGU) are mandatory for all modules. Extract the data for the language specified.
    • Q: Where are the packing handling units data stored during execution of transaction VL01/VL02/VL32N»? CVEKP table is always empty.
      A: The variable is (SAPLV51G)IVEKP[]
    • в: What are difference among 3 types of internal tables: standard, sorted and hashed?
      отв: Standard tables: the row numbering (index) is maintained internally. Both index and key accesses are possible. You should choose this table type when you mainly use the index to access the internal table.
      Sorted tables: the data records are automatically sorted in ascending order of the key fields. Here too, the index is maintained internally. Both index and key accesses are possible. You should choose this table type if you mainly access the internal table with the key or would like the table to be automatically sorted by key.
      Hashed tables: the data records are managed for fast key access using the hashing procedure. A unique key is required. With hashed tables only key accesses are possible. You should choose this table type if the internal table is very large and you want to access it by key only.

      DATA: lt_student1 TYPE STANDARD TABLE OF ty_students.
      DATA stab TYPE SORTED TABLE OF skb1 WITH UNIQUE KEY bukrs saknr.
      DATA htab TYPE HASHED TABLE OF skb1 WITH UNIQUE KEY bukrs saknr.

      You fill sorted tables using the INSERT statement. Entries are inserted according to the sort sequence defined through the table key. Any illegal entries are recognized as soon as you try to add them to the table. The response time for key access is logarithmically proportional to the number of table entries, since the system always uses a binary search. Sorted tables are particularly useful for partially sequential processing in a LOOP if you specify the beginning of the table key in the WHERE condition.

      You cannot access a hashed table using its index. The response time for key access remains constant, regardless of the number of table entries. Like database tables, hashed tables always have a unique key. Hashed tables are useful if you want to construct and use an internal table which resembles a database table or for processing large amounts of data. Accesses must use generic key operations (SORT, LOOP, etc.).

    • в: How to handle errors calling RFC-FM’s?
      отв: When you use CALL FUNCTION … DESTINATION … statement you should always add EXCEPTIONS section.

      data: begin of ls_msg,
              msgv1 type char50,
              msgv2 type char50,
              msgv3 type char50,
              msgv4 type char50,
            end of ls_msg.
      clear ls_msg.
      call function 'RFC_EXECUTE' destination 'DEST_RFC1'
        exceptions
          communication_failure = 1 message ls_msg
          system_failure        = 2 message ls_msg.
      if sy-subrc ne 0.
        message i000(zzz)
          with ls_msg-msgv1
               ls_msg-msgv2
               ls_msg-msgv3
               ls_msg-msgv4.
      endif.
    • в: Wie kann i oi Email aus einem ALV-Rebord heraus verschigga?
      отв:

         data(lo_msg) = new cl_bcs_message( ).
          data  lo_alv type ref to cl_salv_table,
                lv_xls type xstring.
       
       
          lv_xls = lo_alv->to_xml( xml_type = if_salv_bs_xml=>c_type_xlsx ).
          lo_msg->set_subject( 'Transaktion KREDITLI' ).
      loop at it_mail assigning filed-symbol ().
        lv_addr = -low.
        lo_msg-&gt;add_recipient( iv_address = lv_addr ).
      endloop.
       
          lo_msg->add_attachment( iv_filename = 'kreditli'
                                      iv_contents_bin = lv_xls ).
          lo_msg->set_update_task( abap_false ).
          lo_msg->send( ).
       
          lo_alv->display( ).
       
      *                                         ///*
      *                                   ///////////////////
      *                             ,///////////////////////
      *                            (/////////////////////
      *                            (////////////////////////
      *                         (///////////////////////////*
      *                       /////////////////////////////
      *                              (//////////////////////
      *                                ///////////////////(
      *                                ///////////////(              ////*/
      *                               //////////////////       //////////////
      *                              ////////////////////////////////////////
      *                            */////////////////////////////////////////
      *                           //////////////////////////////////////(*
      *                          /////////////////////////////////////.
      *                        ,/////////////////////////////////(/
      *                      *//////////////////////////////(#
      *                    (//////////////////////////////
      *                  (//////////////////////////////////
      *                ///////////////////////////////////////
      *              ////////////////////(   #//////////////////
      *            ////////////////////        ((/////////////////*,,.
      *          *//////////////////(            /(//////////////////////*
      *            ///////////////.                 (///////////////////
      *              ,/////////////                   (///////////////
      *                  (//////////                    //////////
      *                       .(////                      (///

    Набор полезных программ

    Получить внешние вызовы ФМ, транзакций и многого другого внутри программы можно с помощью программы — RSINCL00.

    Транзакция ABAPDOCU — ABAP документация и примеры.

    Транзакция BIBS — примеры пользовательского интерфейса для ABAP программ.

    Транзакция DWDM — демо примеры с использованием Enjoy контролов.

    Программа ADBC_DEMO — демо программа ADBC API (для подключения к внешним базам данных).

    Транзакция SE83 — библиотека примеров с ALV и прочими контролами.

    Программа BALVBT01 — демонстрация множественного использования ALV.

    Программа SHOWICON — список всех иконок.

    Программа SHOWCOLO — все цвета используемые во WRITE или ALV.

    Программа SHOWLINE — всевозможные линии во write отчётах.

    Программа SHOWSYMB — символы.

    Программа AFX_CODE_SCANNER (или RPR_ABAP_SOURCE_SCAN) — поиск в исходных кодах.

    Программа RSBDCOS0 — выполнение системных команд на сервере.

    Программа REPTRAN — массовая выгрузка исходников.

    © abap-blog.ru