在Start routine里替换掉source package里面的non-ASCII字符
这个标题我是这么取的,实际的应用场景就是把ERP那边的有些编号里面的特殊字符给清理掉。如果不清理,就是那边有什么我们就拿什么。但是有时候它那边别人输入的时候不知道给了个啥符号,比如客户编号里本来应该都是数字或字母,它给了个&这种符号,首先主数据这里就不给通过,于是得现在Start Routine里面给清掉。
目录
对所有列进行清理
对固定列进行清理
对一部分列(知道列名)进行清理
BW里允许的默认字符在RSKC这里能看到:
默认是ALL CAPITAL,也就是ASCII码表里的大写字母,其他的特殊字符,就得自己加了。
额外允许的这些字符也就存在下面这个表里。
如果我想对source package的所有列进行清理,可以这么写:
对所有列进行清理
用While进行列循环。对每一列都进行处理。
METHOD GLOBAL_START.FIELD-SYMBOLS:<SOURCE_FIELDS> TYPE _ty_s_SC_1.DATA: MONITOR_REC TYPE RSTMONITOR.* Note the _M class are not considered for DTP execution.
* ABAP Breakpoints must be set in the generated program instead**** begin of routine - insert your code only below this line ****DATA:lo_descr TYPE REF TO cl_abap_typedescr,lv_type(1) TYPE c.FIELD-SYMBOLS: <comp> TYPE any.LOOP AT SOURCE_PACKAGE ASSIGNING <source_fields>.CLEAR sy-subrc.WHILE sy-subrc = 0.ASSIGN COMPONENT sy-index OF STRUCTURE <source_fields> TO <comp>.CHECK sy-subrc = 0.lo_descr = cl_abap_typedescr=>describe_by_data( <comp> ).lv_type = lo_descr->type_kind.IF lv_type = 'C'.<COMP> = ZCL_BW_GENERAL=>REMOVE_INVALID_CHARACTERS(IV_CHARACTERISTIC = <COMP>IV_LOWERCASE_PERMITTED = ABAP_TRUE ).ENDIF.ENDWHILE.ENDLOOP.**** end of routine - insert your code only before this line ****
ENDMETHOD.
类里面这么写:
method REMOVE_INVALID_CHARACTERS.data:LV_UPPERCASE_CHARACTER type C,LV_REPLACING_CHARACTER type C,LV_INDEX type I,LV_STRLEN type I.LV_STRLEN = strlen( IV_CHARACTERISTIC ). check 0 < LV_STRLEN.if '#' = IV_CHARACTERISTIC.RV_CHARACTERISTIC = IV_REPLACED_BY.else.do LV_STRLEN times.LV_INDEX = SY-INDEX - 1. if 0 = LV_INDEX and '!' = IV_CHARACTERISTIC+LV_INDEX(1).LV_REPLACING_CHARACTER = IV_REPLACED_BY.else.LV_UPPERCASE_CHARACTER = IV_CHARACTERISTIC+LV_INDEX(1).translate LV_UPPERCASE_CHARACTER to upper case.if LV_UPPERCASE_CHARACTER co MV_ALLOWED_CHARACTERS. "这个MV_ALLOWED_CHARACTERS 就是开头那个表里的额外允许的字符if ABAP_TRUE = IV_LOWERCASE_PERMITTED.LV_REPLACING_CHARACTER = IV_CHARACTERISTIC+LV_INDEX(1).else.LV_REPLACING_CHARACTER = LV_UPPERCASE_CHARACTER.endif.else. LV_REPLACING_CHARACTER = IV_REPLACED_BY.endif.endif.concatenate RV_CHARACTERISTIC LV_REPLACING_CHARACTERinto RV_CHARACTERISTIC respecting blanks.enddo.endif.endmethod.
对固定列进行清理
如果仅仅相对一个特定的列进行清理,就直接把方法里的while循环去掉,sy-index 换成固定列,比如第二列,就直接写 2 :
ASSIGN COMPONENT 2 OF STRUCTURE <source_fields> TO <comp>
对一部分列(知道列名)进行清理
那就得把列名都列出来,然后进行循环处理。
METHOD GLOBAL_START.FIELD-SYMBOLS:<SOURCE_FIELDS> TYPE _ty_s_SC_1.DATA: MONITOR_REC TYPE rstmonitor.DATA:lv_type(1) TYPE c,"需要处理的列名lt_fields_to_process TYPE TABLE OF fieldname.lt_fields_to_process = VALUE #( ( 'LOGSYS' ) ( 'KUNNR' ) ( 'ADRNR' ) ( 'BRSCH' ) ).FIELD-SYMBOLS: <comp> TYPE any.LOOP AT SOURCE_PACKAGE ASSIGNING <source_fields>.LOOP AT lt_fields_to_process INTO DATA(lv_fieldname).ASSIGN COMPONENT lv_fieldname OF STRUCTURE <source_fields> TO <comp>.IF sy-subrc = 0.DATA(lo_descr) = cl_abap_typedescr=>describe_by_data( <comp> ).IF lo_descr->type_kind = 'C'.<comp> = ZCL_BW_GENERAL=>REMOVE_INVALID_CHARACTERS(IV_CHARACTERISTIC = <comp> ).IV_LOWERCASE_PERMITTED = ABAP_TRUE ).ENDIF.ENDIF.ENDLOOP.ENDLOOP.
还有另外一种是动态处理,效率低一点。
LOOP AT SOURCE_PACKAGE ASSIGNING <source_fields>.
*
* DATA(lo_struct_descr) = CAST cl_abap_structdescr( cl_abap_typedescr=>describe_by_data( <source_fields> ) ).
*
*
* LOOP AT lo_struct_descr->components ASSIGNING FIELD-SYMBOL(<ls_comp>).
* "动态列名
* ASSIGN COMPONENT <ls_comp>-name OF STRUCTURE <source_fields> TO <comp>.
* IF sy-subrc = 0.
* IF <ls_comp>-type_kind ='C'
* AND LINE_EXISTS( lt_fields_to_process[ table_line = <ls_comp>-name ] ).
* <COMP> = ZCL_BW_GENERAL=>REMOVE_INVALID_CHARACTERS(
* IV_CHARACTERISTIC = <COMP> ).
** IV_LOWERCASE_PERMITTED = ABAP_TRUE ).
* ENDIF.
* ENDIF.
* ENDLOOP.
*
* ENDLOOP.