SAP BW ODS無效字元自動處理程式

leniz發表於2010-04-14

      這程式寫得真不容易!

       因為一直找不到讀取BALDAT這個表的RAW型別資料的程式,只能把標準程式扣出來用。標準程式是彈出視窗顯示錯誤日誌的,一直沒找到或沒讀懂讀取RAW的程式段,所以我採用讀取ALV的方式把資料讀入內表,因為有好多段,看不懂,所以可能有幾個Function是不需要的,我儘量採用註釋掉看結果的方法,不斷縮短程式碼。  最終留下本程式的上半段。 下半段把日誌分解開來,因為要寫成通用的程式,所以需要提取 ODS名稱,FieldName,以及出錯的值。  

       前後花了三天的時間,不知道是否值得。 總覺得自己好像把自己一步一步趕到某個深淵。

        程式有三個變數:

       1. 是否只顯示異常資訊

       2. ODS名稱  (因為實在分辨不出日誌中的錯誤日誌,只能採用這個條件來控制日誌數量,比較失敗。)

       3. 發生日期

*&---------------------------------------------------------------------*
*& Report  Z1RD0017
*&
*&---------------------------------------------------------------------*
*& Created By: Reed Lei (20100401)
*& todo: Replace the inValid character in ODS New Data Table
*&---------------------------------------------------------------------*

REPORT  z1rd0017.

TYPES:
  BEGIN OF bal_s_lout,

*   handle of this control representation
    handle              TYPE balcnthndl,
*   initial input
    profile             TYPE bal_s_prof,
    log_hndl            TYPE bal_t_logh,
    msg_hndl            TYPE bal_t_msgh,
    log_filt            TYPE bal_s_lfil,
    log_cfil            TYPE bal_t_cfil,
    msg_filt            TYPE bal_s_mfil,
    msg_cfil            TYPE bal_t_cfil,

*   controls
    container           TYPE REF TO cl_gui_container,
    splitter            TYPE REF TO cl_gui_splitter_container,
    tree                TYPE REF TO cl_gui_column_tree,
    grid                TYPE REF TO cl_gui_alv_grid,
    event_rec           TYPE REF TO object,

*   converted profile
    use_grid            TYPE boolean,
    prof_int            TYPE bal_s_iprf,

*   data to be displayed
    t_log_hndl          TYPE bal_t_logh,
    t_msg_hndl          TYPE bal_t_msgh,

*   data for tree
    t_columns           TYPE bal_t_hdrs,
    t_node              TYPE bal_t_node,
    t_item              TYPE bal_t_item,
    tree_logs           TYPE bal_t_trlg,
    tree_msgs           TYPE bal_t_trms,

*   current state
    count_all           TYPE bal_s_scnt,
    cur_node            TYPE tv_nodekey,
    longtexts_exist     TYPE boolean,
    params_exist        TYPE boolean,
    sel_msgty           TYPE bal_s_smty,
    ucomm_data          TYPE bal_s_cbuc,

* tabname for the flat ALV-table for using in REUSE_ALV_LIST_DISPLAY
    tabname_alv         TYPE tabname,
  END OF bal_s_lout,
  bal_t_lout TYPE SORTED TABLE OF bal_s_lout
                  WITH UNIQUE KEY handle
                  INITIAL SIZE    1.
*PARAMETERS:l_c.
DATA: log_handle TYPE balloghndl.
DATA: l_s_prof TYPE bal_s_prof,
      l_t_logh TYPE bal_t_logh.
DATA: l_sx_display_profile TYPE bal_s_prof,
      ls_display_profile TYPE bal_s_prof.
* Get display profile for popup
CONSTANTS:
  true                    TYPE boolean         VALUE 'X',
  false                   TYPE boolean         VALUE ' '.
DATA:
  g_access_control_done    TYPE boolean.

DATA:
  BEGIN OF g OCCURS 0,
    control_handle      TYPE balcnthndl,
    profile             TYPE bal_s_prof,
    prof_int            TYPE bal_s_iprf,
    sel_msgty           TYPE bal_s_smty,
    custom_container    TYPE REF TO cl_gui_custom_container,
    docking_container   TYPE REF TO cl_gui_docking_container,
  END OF g.
DATA:
BEGIN OF wa_ods,
  odsobject TYPE  rsdodsobject,
  fieldname(20),
  value(20),
END OF wa_ods.
DATA:it_ods LIKE TABLE OF wa_ods.
DATA g_log_handles TYPE bal_t_logh .
DATA: g_log_profile TYPE  bal_s_prof,l_retcode                  TYPE i.
DATA: l_ln TYPE balloghndl.
DATA: l_log_filter  TYPE bal_s_lfil,
      l_log_headers TYPE balhdr_t WITH HEADER LINE.
DATA: l_lognumber TYPE  bal_r_logn WITH HEADER LINE.
DATA: l_aldate    TYPE bal_r_date WITH HEADER LINE.

DATA: l_object TYPE LINE OF  bal_r_obj ,
      l_subobject  TYPE LINE OF bal_r_sub,
      l_extnumber  TYPE LINE OF bal_r_extn.

DATA: l_msgid(10),l_msgno(10),
      l_rsm1187_msg(100) VALUE 'Error getting SID for ODS object',
      l_brain060_msg(100) VALUE 'Value (hex. ) of characteristic contains invalid characters',
      l_str(255),
      l_msg(255).
DATA: citab LIKE TABLE OF l_str.
DATA: l_index LIKE sy-index.
DATA: l_lines TYPE i .
FIELD-SYMBOLS:
                      TYPE bal_t_lout,
                        TYPE bal_s_lout,
               TYPE table,
     TYPE ANY,
  TYPE ANY,
               TYPE table.

PARAMETERS:l_list  AS CHECKBOX DEFAULT 'X'.
*SELECT-OPTIONS: l_c FOR l_lognumber-low NO INTERVALS.
PARAMETERS:l_ods(12) OBLIGATORY.
SELECT-OPTIONS: l_d FOR l_aldate-low OBLIGATORY.


*APPEND LINES OF l_c TO l_log_filter-lognumber.
APPEND LINES OF l_d TO l_log_filter-aldate.

l_object-sign = 'I'.
l_object-option = 'EQ'.
l_object-low = 'RSSM'.
APPEND l_object TO l_log_filter-object.

l_subobject-sign = 'I'.
l_subobject-option = 'EQ'.
l_subobject-low = 'MON'.
APPEND l_subobject TO l_log_filter-subobject.

l_extnumber-sign = 'I'.
l_extnumber-option = 'EQ'.

CONCATENATE 'MON:PROTOCOLL_ACTION-ODSAC-' l_ods INTO l_extnumber-low .
APPEND l_extnumber TO l_log_filter-extnumber.

CALL FUNCTION 'BAL_DB_SEARCH'
  EXPORTING
    i_s_log_filter = l_log_filter
  IMPORTING
    e_t_log_header = l_log_headers[]
  EXCEPTIONS
    log_not_found  = 1.

DESCRIBE TABLE l_log_headers LINES l_lines.

IF l_lines EQ 0 .
  WRITE: 'Without Error Log'.
  EXIT.
ENDIF.


LOOP AT  l_log_headers .
  CLEAR:g_log_handles[].
  l_ln = l_log_headers-log_handle.
  INSERT l_ln INTO TABLE g_log_handles.
  CALL FUNCTION 'BAL_DSP_PROFILE_SINGLE_LOG_GET'
    IMPORTING
      e_s_display_profile = l_sx_display_profile
    EXCEPTIONS
      OTHERS              = 0.

  CALL FUNCTION 'BAL_DB_LOAD'
    EXPORTING
      i_t_log_handle                = g_log_handles
      i_exception_if_already_loaded = space
    EXCEPTIONS
      OTHERS                        = 1.

*********************************************************************
* set data to be displayed
*********************************************************************

  CALL FUNCTION 'BAL_CNTL_CREATE'
    EXPORTING
      i_container          = g-custom_container
      i_s_display_profile  = g-profile
      i_t_log_handle       = g_log_handles
    IMPORTING
      e_control_handle     = g-control_handle
    EXCEPTIONS
      profile_inconsistent = 1
      OTHERS               = 2.

  PERFORM. load(saplsbal_cntl).
  ASSIGN ('(SAPLSBAL_CNTL)D_T[]') TO .
  IF NOT IS ASSIGNED.
*     251(BL): "Control does not exist."
    MESSAGE e251(bl) INTO sy-msgli.
    EXIT.
  ENDIF.

ENDLOOP.

LOOP AT  ASSIGNING   .
* point to message data table
  IF -prof_int-msgtabname IS INITIAL.
    CONTINUE.
  ENDIF.
  ASSIGN (-prof_int-msgtabname) TO .

  LOOP AT ASSIGNING   .
    ASSIGN COMPONENT '%_MSGID' OF STRUCTURE TO .
    l_msgid = .
    ASSIGN COMPONENT '%_MSGNO' OF STRUCTURE TO .
    l_msgno = .
    IF l_msgid EQ 'RSM1' AND l_msgno EQ '187'.
      CLEAR: citab[].
      ASSIGN COMPONENT 'T_MSG' OF STRUCTURE TO .
      l_str = .
      SPLIT l_rsm1187_msg AT space INTO TABLE citab.
      LOOP AT citab INTO l_msg.
        REPLACE FIRST OCCURRENCE OF l_msg IN l_str WITH ''  .
      ENDLOOP.
      CONDENSE l_str.
      wa_ods-odsobject = l_str.
    ENDIF.
    IF l_msgid EQ 'BRAIN' AND
         ( l_msgno EQ '060' OR  l_msgno EQ '059').
      CLEAR: citab[].
      ASSIGN COMPONENT 'T_MSG' OF STRUCTURE TO .
      l_str = .
      SPLIT l_brain060_msg AT space INTO TABLE citab.
      LOOP AT citab INTO l_msg.
        REPLACE FIRST OCCURRENCE OF l_msg IN l_str WITH ''  .
      ENDLOOP.
      SPLIT l_str AT space INTO TABLE citab.
      LOOP AT citab INTO l_msg.
        l_index = sy-tabix.
        IF l_msg IS INITIAL.
          DELETE citab INDEX l_index.
        ENDIF.
      ENDLOOP.
      READ TABLE citab INDEX 1 INTO l_msg.
      CONDENSE l_msg.
      wa_ods-value = l_msg.
      READ TABLE citab INDEX 3 INTO l_msg.
      CONDENSE l_msg.
      wa_ods-fieldname = l_msg.
    ENDIF.
  ENDLOOP.
  IF NOT wa_ods-fieldname IS INITIAL AND
     NOT wa_ods-odsobject IS INITIAL AND
     NOT wa_ods-value IS INITIAL.
    APPEND wa_ods TO it_ods.
  ENDIF.
ENDLOOP.

DATA:
    l_entries TYPE i.

***********************************************************************
* destroy containers
***********************************************************************
IF NOT g-docking_container IS INITIAL.
  CALL METHOD g-docking_container->free
    EXCEPTIONS
      THERS = 0.
ENDIF.
IF NOT g-custom_container IS INITIAL.
  CALL METHOD g-custom_container->free
    EXCEPTIONS
      THERS = 0.
ENDIF.


***********************************************************************
* reduce stack
***********************************************************************
CLEAR g.
DESCRIBE TABLE g LINES l_entries.
IF l_entries > 0.
  READ TABLE g INDEX l_entries.
  DELETE g INDEX l_entries.
ENDIF.


SORT it_ods.
DELETE ADJACENT DUPLICATES FROM it_ods.
DATA:l_up(200),l_st(200),l_wh(200),l_new(200).
DATA: fieldnm  TYPE rsdiobjfieldnm.
LOOP AT it_ods INTO wa_ods.
  ULINE .
  WRITE:/ wa_ods-odsobject , wa_ods-fieldname,wa_ods-value.
  CALL FUNCTION 'SCP_REPLACE_STRANGE_CHARS'
    EXPORTING
      intext  = wa_ods-value
    IMPORTING
      uttext = l_new.
  IF sy-subrc <> 0.
    l_new = ''.
  ENDIF.
  SELECT SINGLE fieldnm   FROM rsdiobj INTO fieldnm
    WHERE iobjnm = wa_ods-fieldname AND bjvers = 'A'.

  IF sy-subrc EQ 0.

    CONCATENATE '  /BIC/A'  wa_ods-odsobject  '40' INTO l_up.
    CONCATENATE ' ' fieldnm   '  =  '  l_new  ''  INTO l_st.
    CONCATENATE ' ' fieldnm   '  =  ' wa_ods-value '' INTO l_wh.
    IF l_list NE 'X'.
      UPDATE (l_up)
      SET    (l_st)
      WHERE  (l_wh).
      IF sy-subrc EQ 0.
        COMMIT WORK.
      ELSE.
        ROLLBACK WORK.
      ENDIF.
    ELSE.
      WRITE:/ 'UPDATE ' , l_up.
      WRITE:/ 'SET ' , l_st.
      WRITE:/ 'WHERE ', l_wh.
    ENDIF.
  ENDIF.
ENDLOOP.

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/554557/viewspace-659691/,如需轉載,請註明出處,否則將追究法律責任。

相關文章