SAP CRM 如何高效debug 查看BOL的值

为了不涉及版权问题首先声明这个网上有英文版的 作者JerryWang大神。我觉得方便,所以分享一下。

背景:当我们debug crm程序时,很多BOL特别深,譬如要看  eh_onsave里的parter bol 时就特别难get 到。因此我们可以用一个脚本来快速获取。

首先,我们创建一个report (subroutine pool), 代码如下:

REPORT  rstpda_script.

 
*---------------------------------------------------------------------*
*       CLASS lcl_debugger_script DEFINITION
*---------------------------------------------------------------------*
* Debugger Script to View BOL content
*---------------------------------------------------------------------*
class lcl_debugger_script definition inheriting from  cl_tpda_script_class_super  .
  public section.
    " Replace the 'lr_entity' with the name of your BOL entity
    data bol_entity TYPE TPDA_VAR_NAME VALUE 'lr_entity'.

    methods: prologue  redefinition,
      init    redefinition,
      script  redefinition,
      end     redefinition.
    interfaces: if_tpda_script_w_input,
      if_tpda_script_w_output.

  private section.
    data: entity_name type string.
    data: value type string.
    data: output type tpda_transfer_it_unsorted.
    data: bol_object_name type crmt_ext_obj_name.
    methods get_attribute
      importing io_oref_descr     type ref to cl_tpda_script_orefdescr
                iv_attribute_name type string
      returning value(ro_descr)   type ref to cl_tpda_script_data_descr.
endclass.                    "lcl_debugger_script DEFINITION


*---------------------------------------------------------------------*
*       CLASS lcl_debugger_script IMPLEMENTATION
*---------------------------------------------------------------------*
* Debugger Script to View BOL content
*---------------------------------------------------------------------*
class lcl_debugger_script implementation.
  method prologue.
*** generate abap_source (source handler for ABAP)
    super->prologue( ).
  endmethod.                    "prolog

  method if_tpda_script_w_input~get_parameters.

    data lt_input      type tpda_transfer_it.
    data ls_input      type tpda_transfer_struc.

    ls_input-id   = 'ENTITY'.
    append ls_input to lt_input.
    p_parameters_it = lt_input.

  endmethod.                    "if_tpda_script_w_input~get_parameters

  method if_tpda_script_w_input~set_parameter_values.

*   Tabelle mit Inputparameter und Wert
    data lt_input     type tpda_transfer_it.
    data ls_input     type tpda_transfer_struc.

    lt_input = p_parameter_values_it.
    loop at lt_input into ls_input.
      if ls_input-id = 'ENTITY'.
        entity_name = ls_input-value.
      endif.
    endloop.

  endmethod.                    "if_tpda_script_w_input~set_parameter_values


  method init.
*** insert your initialization code here
  endmethod.                    "init


  method script.
    data lr_data_descr      type ref to cl_tpda_script_data_descr.
    data lr_struct_descr    type ref to cl_tpda_script_structdescr.
    data lr_cx              type ref to cx_root.
    data ls_quick           type tpda_scr_quick_info.
    data lv_name            type string.
    data lt_struct          type tpda_scr_struct_comp_it.
    data ls_struct          type tpda_scr_struct_comp.
    data ls_output          type tpda_transfer_struc.
    data lr_symbsimple      type ref to tpda_sys_symbsimple.
    data ls_varinfo         type tpda_quick_vars.

    field-symbols: <lv_value> type any.

    try.
        clear output.

        ls_varinfo = cl_tpda_script_data_descr=>get_variable_info( bol_entity ).
*        ls_varinfo = cl_tpda_script_data_descr=>get_variable_info( 'LO_PRODUCT' ).

*       get object type name
        if ls_varinfo-varvalue = 'OBJECT'.
*         class instance passed directly
          lv_name = entity_name && '-CONTAINER_PROXY->DATA_REF->OBJECT_NAME'.
        else.
*         variable of class instance passed
          lv_name = ls_varinfo-varvalue && '-CONTAINER_PROXY->DATA_REF->OBJECT_NAME'.
        endif.

        ls_quick = cl_tpda_script_data_descr=>get_quick_info( lv_name ).
        assign ls_quick-quickdata to <lv_value>.
        lr_symbsimple ?= <lv_value>.
        bol_object_name = lr_symbsimple->valstring.

*       get content
        if ls_varinfo-varvalue = 'OBJECT'.
          lv_name = entity_name && '-CONTAINER_PROXY->DATA_REF->ATTRIBUTE_REF->*'.
        else.
          lv_name = ls_varinfo-varvalue && '-CONTAINER_PROXY->DATA_REF->ATTRIBUTE_REF->*'.
        endif.

        lr_data_descr = cl_tpda_script_data_descr=>factory( lv_name ).
        lr_struct_descr ?= lr_data_descr.

        lr_struct_descr->components(
          importing
            p_components_full_it =  lt_struct
        ).

        loop at lt_struct into ls_struct.
          ls_output-id = ls_struct-compname.
          try.
              assign ls_struct-symbquick-quickdata to <lv_value>.
              lr_symbsimple ?= <lv_value>.
              ls_output-value = lr_symbsimple->valstring.
            catch cx_root into lr_cx.
              ls_output-value = lr_cx->get_text( ).
          endtry.
          append ls_output to output.
        endloop.

        data lt_col_alv                   type tpda_script_service_source_tab.
        data ls_col_alv                   like line of lt_col_alv.
        ls_col_alv-fieldname = ls_col_alv-content = 'ID'.
        append ls_col_alv to lt_col_alv.
        ls_col_alv-fieldname = ls_col_alv-content = 'VALUE'.
        append ls_col_alv to lt_col_alv.

        call method cl_tpda_script_data_display=>data_display
          exporting
            p_list_header = 'Query Selection Parameters'
            p_column_it   = lt_col_alv
            p_popup       = 'X'
          changing
            p_data_it     = output.

      catch cx_root into lr_cx.
        " if the debugger script is here, check if you have
        " really entered a variable of type CL_CRM_BOL_ENTITY
        break-point.                                       "#EC NOBREAK
        value = lr_cx->get_text( ).
    endtry.
  endmethod.                    "script


  method end.
    " insert your code which shall be executed at the end of the scripting (before trace is saved)
    " here

  endmethod.                    "end

  method if_tpda_script_w_output~get_parameter_values.
    data lt_param type tpda_transfer_it_unsorted.
    data ls_param type tpda_transfer_struc.

    ls_param-id = 'VARIABLE'.
    ls_param-value = entity_name.
    append ls_param to lt_param.
    ls_param-id = 'OBJECT_NAME'.
    ls_param-value = bol_object_name.
    append ls_param to lt_param.

    append initial line to lt_param.

    append lines of output to lt_param.

    p_parameter_values_it = lt_param.
  endmethod.                    "if_tpda_script_w_output~get_parameter_values


  method get_attribute.
    data lr_oref_descr     type ref to cl_tpda_script_orefdescr.
    data lr_object_descr   type ref to cl_tpda_script_objectdescr.
    data ls_varinfo        type tpda_quick_vars.
    data lv_longname       type string.
    data lt_attributes     type tpda_script_object_attribut_it.

    lr_oref_descr   = io_oref_descr.
    lr_object_descr = lr_oref_descr->get_object_handle( ).

    lt_attributes = lr_object_descr->attributes( ).

    ro_descr = lr_object_descr->get_attribut_handle( lv_longname  ).
  endmethod.                    "get_oref_attribute
endclass.                    "lcl_debugger_script IMPLEMENTATION

然后在debug 模式下,断点设在你想要查的bol的代码块,最后一个页签,script, 输入我们这个report name:

 

然后替完bol_entity的值为你想获取的bol名:

Click start script 就可以得到BOL里的值