最近比较忙,稍微介绍一下。
本程序的作用是查找并删除数据库表内包含的特殊字符。
通过接口或者Excel上载创建的主数据描述,凭证数据的文本字段等,偶尔会有包含特殊字符的情况,且大部分时候是不可见字符,比如制表符,回车换行,0x0000等等。如果没有工具程序,只用SE16等查找或者更改非常困难,所以特意做了一个程序来干这个事情。
辅助功能1、显示可见字符的ASCII码
辅助功能2、自动创建日志表
辅助功能3、自定义的更新功能(有更改日志)
程序的运行界面:
下面是优美的代码~
*&---------------------------------------------------------------------*
*& Report ZCHECKSPECIALHEX
*& 检查/修正表内的CNDT类型字段值包含的特殊字符
*&---------------------------------------------------------------------*
*& Baitianzhen
*& 2022.04.16
*&---------------------------------------------------------------------*
REPORT zcheckspecialhex NO STANDARD PAGE HEADING .
TYPE-POOLS: sscr,slis.
TABLES: dd02v,dd03l,tadir,sscrfields.
DATA: fldct TYPE lvc_t_fcat WITH HEADER LINE,
slayt TYPE lvc_s_layo,
repid TYPE sy-repid,
subrc TYPE sy-subrc,
char45 TYPE char45,
tabix TYPE sy-tabix,
fmname TYPE funcname,
whstr TYPE string,
tmpstr TYPE string,
numstr TYPE string,
keystr TYPE string,
cspace TYPE char4,
tmpint TYPE i,
percnt TYPE i,
cflag.
DATA: set_str TYPE string,
con_str TYPE string.
DATA: cxroot TYPE REF TO cx_root,
excmsg TYPE char255.
DATA: paraname TYPE char40,
stru_type TYPE REF TO cl_abap_structdescr,
itab_type TYPE REF TO cl_abap_tabledescr,
comp_des TYPE abap_componentdescr,
comp_tab TYPE abap_component_tab WITH HEADER LINE.
DATA: logtname TYPE tablename VALUE 'ZCSL'.
DATA: BEGIN OF wa_value ,
fldname TYPE string,
fldtype TYPE string,
fldvalue TYPE string,
hexvalue TYPE string,
END OF wa_value.
DATA: BEGIN OF it_flds OCCURS 0 ,
fldname TYPE fieldname,
ref_tab TYPE tabname,
ref_fld TYPE fieldname,
convext TYPE convexit,
inttype TYPE inttype,
END OF it_flds.
DATA: BEGIN OF wa_log,
mandt TYPE mandt ,
tabname TYPE tabname,
objectid TYPE cdobjectv,
fieldname TYPE fieldname,
erdat TYPE erdat ,
erzet TYPE erzet ,
ernam TYPE ernam ,
value_old TYPE cdfldvalo,
value_new TYPE cdfldvaln,
END OF wa_log.
DATA: it_fkey LIKE TABLE OF it_flds WITH HEADER LINE.
DATA: it_fnok LIKE TABLE OF it_flds WITH HEADER LINE.
DATA: it_dd03 TYPE TABLE OF dd03p WITH HEADER LINE.
DATA: rf_tabl TYPE REF TO data,
rf_twa TYPE REF TO data,
rf_out TYPE REF TO data,
rf_owa TYPE REF TO data.
FIELD-SYMBOLS: <fs_out> TYPE STANDARD TABLE,
<fs_tabl> TYPE STANDARD TABLE,
<fsx> TYPE x, <fs_owa>, <fs_twa>, <fs_fld>, <fs>.
SELECTION-SCREEN FUNCTION KEY 1.
SELECTION-SCREEN FUNCTION KEY 2.
SELECTION-SCREEN FUNCTION KEY 3.
SELECTION-SCREEN FUNCTION KEY 4.
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE t01.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT (31) ctxt0 FOR FIELD p_tname .
PARAMETERS: p_tname TYPE tabname16 MEMORY ID dtb .
SELECTION-SCREEN COMMENT 52(31) ctxtl .
SELECTION-SCREEN END OF LINE.
SELECT-OPTIONS s_type FOR cflag NO INTERVALS.
SELECT-OPTIONS s_flds FOR dd03l-fieldname NO INTERVALS MATCHCODE OBJECT dd_fieldname.
SELECT-OPTIONS s_conl FOR char45 NO INTERVALS LOWER CASE.
SELECT-OPTIONS s_sfld FOR dd03l-fieldname NO INTERVALS MATCHCODE OBJECT dd_fieldname.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT (31) ctxt1 FOR FIELD p_hchar .
PARAMETERS: p_hchar TYPE char18 DEFAULT '0000'.
SELECTION-SCREEN PUSHBUTTON 52(9) but03 USER-COMMAND space .
SELECTION-SCREEN PUSHBUTTON 62(9) but04 USER-COMMAND newline .
SELECTION-SCREEN PUSHBUTTON 72(9) but00 USER-COMMAND minchar .
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN PUSHBUTTON 52(9) but02 USER-COMMAND tab .
SELECTION-SCREEN PUSHBUTTON 62(9) but05 USER-COMMAND cr_lf .
SELECTION-SCREEN PUSHBUTTON 72(9) but01 USER-COMMAND maxchar .
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN END OF BLOCK b1.
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE t02.
PARAMETERS p_proind AS CHECKBOX .
PARAMETERS p_update AS CHECKBOX USER-COMMAND updchk.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN POSITION 4.
PARAMETERS pr_rep RADIOBUTTON GROUP typ DEFAULT 'X' MODIF ID a.
SELECTION-SCREEN COMMENT (30) ctxt3 FOR FIELD pr_rep MODIF ID a.
PARAMETERS p_conv AS CHECKBOX MODIF ID a.
SELECTION-SCREEN COMMENT (14) ctxt6 FOR FIELD p_conv MODIF ID a.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN POSITION 4.
PARAMETERS pr_clr RADIOBUTTON GROUP typ MODIF ID a.
SELECTION-SCREEN COMMENT (12) ctxt5 FOR FIELD pr_clr MODIF ID a.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN END OF BLOCK b2.
SELECTION-SCREEN BEGIN OF BLOCK b3 WITH FRAME TITLE t03.
SELECTION-SCREEN COMMENT /1(79): txt1,txt2,txt3,txt4,txt5,txt6,txt7,txt8.
SELECTION-SCREEN END OF BLOCK b3.
SELECTION-SCREEN BEGIN OF SCREEN 1100 AS WINDOW .
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT (8) ctxt7 FOR FIELD p_fval.
PARAMETERS: p_fval TYPE char255 .
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN END OF SCREEN 1100.
SELECTION-SCREEN BEGIN OF SCREEN 1200 AS WINDOW .
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT (6) ctxt8 FOR FIELD p_fval.
PARAMETERS: p_uptab TYPE tabname16 OBLIGATORY.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT (6) ctxt9 FOR FIELD p_fval.
PARAMETERS: p_upfld TYPE fieldname VISIBLE LENGTH 10 OBLIGATORY .
SELECTION-SCREEN COMMENT (3) ctxta FOR FIELD p_upval.
PARAMETERS: p_upval TYPE string VISIBLE LENGTH 24 LOWER CASE.
PARAMETERS: p_astxt AS CHECKBOX DEFAULT 'X'.
SELECTION-SCREEN COMMENT (6) ctxtc FOR FIELD p_astxt.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT (6) ctxtb FOR FIELD p_fval.
PARAMETERS: p_upwhe TYPE string LOWER CASE OBLIGATORY.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN END OF SCREEN 1200.
AT SELECTION-SCREEN OUTPUT.
sscrfields-functxt_01 = 'ASCII码'.
sscrfields-functxt_02 = '创建日志表'.
sscrfields-functxt_03 = '查看日志'.
sscrfields-functxt_04 = '单个字段更新'.
t01 = '数据'.
t02 = '选项'.
t03 = '使用说明'.
ctxt0 = '表名'.
ctxt1 = '特殊字符的HEX'.
ctxt3 = 'C类型过滤掉特殊字符,NDT类型改为初始值'.
ctxt5 = '字段数据清空为初始值'.
ctxt6 = '并将C类型数据转为内部格式'.
ctxt7 = '外部格式:'.
ctxt8 = 'UPDATE'.
ctxt9 = 'SET'.
ctxta = ' = '.
ctxtb = 'WHERE'.
ctxtc = '常量'.
but00 = 'MinChar'.
but01 = 'MaxChar'.
but02 = 'Tab'.
but03 = 'Space'.
but04 = 'NewLine'.
but05 = 'CR_LF'.
%_p_proind_%_app_%-text = '显示查找进度'.
%_p_update_%_app_%-text = '更改数据库数据'.
%_p_tname_%_app_%-text = '表名'.
%_p_hchar_%_app_%-text = '特殊字符的HEX'.
%_s_type_%_app_%-text = '字段类型(C/N/D/T)'.
%_s_flds_%_app_%-text = '字段名'.
%_s_conl_%_app_%-text = 'WHERE语句'.
%_s_sfld_%_app_%-text = '额外输出字段'.
txt1 = `1、如果不输入要检查字段,则检查表内所有C/N/D/T类型的非KEY字段`.
txt2 = `2、WHERE语句可以不填写,也可以填写多行,每行不要超过45字符`.
txt3 = `3、默认输出KEY字段和包含特殊字符的字段,如果想要输出其他字段,可以放到“额外输出字段”`.
txt4 = `4、如果不勾中"更新数据库数据",则只列出数据,不更新数据库`.
txt5 = `5、更新数据库的时候,使用INITIAL值覆盖或者只去掉特殊字符`.
txt6 = `6、如果勾中数据转为内部格式,则先去掉特殊字符然后根据表内字段对应域的转换例程转换为内部格式`.
txt7 = `7、HEX为空会列出所有在数据库取出的CNDT类型数据,排查错误使用,不支持更新模式`.
txt8 = `8、HEX为Space有特殊用法,可以查出非INITIAL字段包含空格的情况,比如日期或时间值为空格的,不可以使用过滤模式`.
CLEAR ctxtl.
SELECT SINGLE ddtext INTO ctxtl
FROM dd02t
WHERE tabname = p_tname AND
ddlanguage = sy-langu.
LOOP AT SCREEN.
IF p_update = ''.
IF screen-group1 CA 'A'.
screen-active = '0'.
ENDIF.
ENDIF.
IF screen-name CS 'P_PROIND'.
screen-input = '0'.
ENDIF.
MODIFY SCREEN.
ENDLOOP.
IF sy-dynnr = '1100'.
LOOP AT SCREEN.
screen-input = '0'.
MODIFY SCREEN.
ENDLOOP.
SET CURSOR FIELD 'CTXT7'.
ENDIF.
IF sy-dynnr = '1200'.
PERFORM selscreen_ext USING 'GET SPOS'.
ENDIF.
INITIALIZATION.
PERFORM get_hchar USING space CHANGING cspace.
AT SELECTION-SCREEN.
CASE sscrfields-ucomm.
WHEN 'FC01'.
LEAVE TO LIST-PROCESSING .
NEW-PAGE NO-HEADING NO-TITLE.
SET PF-STATUS space.
SUPPRESS DIALOG.
PERFORM ascii.
WHEN 'FC02'.
PERFORM fill_dd03 USING : 'MANDT ' 'MANDT' 'X',
'TABNAME ' 'TABNAME' 'X',
'OBJECTID ' 'CDOBJECTV' 'X',
'FIELDNAME' 'FIELDNAME' 'X',
'ERDAT ' 'ERDAT' 'X',
'ERZET ' 'ERZET' 'X',
'ERNAM ' 'ERNAM' 'X',
'VALUE_OLD' 'CDFLDVALO' '',
'VALUE_NEW' 'CDFLDVALN' ''.
SELECT SINGLE * FROM tadir
WHERE pgmid = 'R3TR' AND
object = 'PROG' AND
obj_name = sy-repid.
PERFORM create_table TABLES it_dd03
USING 'ZCSL' 'ZCHECKSPECIALHEX日志' tadir-devclass .
WHEN 'FC03'.
CONCATENATE '/1BCDWB/DB' logtname INTO char45 .
SUBMIT (char45) VIA SELECTION-SCREEN AND RETURN .
WHEN 'FC04'.
CALL SELECTION-SCREEN 1200 STARTING AT 32 6 .
CHECK sy-subrc = 0 .
PERFORM update_single_fld USING p_uptab p_upfld p_upval p_upwhe p_astxt .
WHEN 'MINCHAR'.
PERFORM get_hchar USING %_minchar CHANGING p_hchar.
WHEN 'MAXCHAR'.
PERFORM get_hchar USING %_maxchar CHANGING p_hchar.
WHEN 'TAB'.
PERFORM get_hchar USING %_horizontal_tab CHANGING p_hchar.
WHEN 'SPACE'.
PERFORM get_hchar USING space CHANGING p_hchar.
WHEN 'NEWLINE'.
PERFORM get_hchar USING %_newline CHANGING p_hchar.
WHEN 'CR_LF'.
PERFORM get_hchar USING %_cr_lf CHANGING p_hchar.
WHEN 'UPDCHK'.
CHECK p_update = 'X'.
CALL FUNCTION 'POPUP_TO_CONFIRM'
EXPORTING
titlebar = '确认'
text_question = '本程序会直接更改数据库数据!请在专业人员指导下使用,继续选择更改吗?'
default_button = 'A'
IMPORTING
answer = cflag.
IF cflag <> '1'.
p_update = ''.
ENDIF.
ENDCASE.
START-OF-SELECTION.
PERFORM checkinput.
PERFORM savelog(zreplog) USING sy-repid '' IF FOUND.
PERFORM get_dd03 USING p_tname.
PERFORM create_itab.
PERFORM getdata.
PERFORM updatelog(zreplog) IF FOUND.
CHECK <fs_out> IS NOT INITIAL.
PERFORM outdata.
*&---------------------------------------------------------------------*
*& Form checkinput
*&---------------------------------------------------------------------*
FORM checkinput.
SELECT SINGLE * FROM dd02v WHERE tabname = logtname.
IF sy-subrc <> 0 AND p_update = 'X'.
MESSAGE s000(oo) WITH '请先创建日志表'.
STOP.
ENDIF.
IF p_tname IS INITIAL.
MESSAGE s000(oo) WITH '表名必输'.
STOP.
ENDIF.
tmpint = strlen( p_hchar ) MOD 4.
IF tmpint <> 0.
MESSAGE s000(oo) WITH 'HEX长度必须是4的倍数'.
STOP.
ENDIF.
IF p_hchar CN '0123456789ABCDEF '.
MESSAGE s000(oo) WITH 'HEX只能是数字或者A-F'.
STOP.
ENDIF.
IF p_update = 'X' AND p_hchar = '' .
MESSAGE s000(oo) WITH 'HEX为空不可以使用更新模式'.
STOP.
ENDIF.
IF p_update = 'X' AND pr_rep = 'X' AND p_hchar = cspace.
MESSAGE s000(oo) WITH 'HEX为Space不可以使用过滤模式'.
STOP.
ENDIF.
ENDFORM. "checkinput
*&---------------------------------------------------------------------*
*& Form get_dd03
*&---------------------------------------------------------------------*
FORM get_dd03 USING in_tabname.
DATA tabname TYPE ddobjname.
DELETE s_flds WHERE low = ''.
DELETE s_sfld WHERE low = ''.
CLEAR: it_dd03[],it_flds[],it_fkey[],it_fnok[].
tabname = in_tabname.
CALL FUNCTION 'DDIF_TABL_GET'
EXPORTING
name = tabname
langu = sy-langu
IMPORTING
dd02v_wa = dd02v
TABLES
dd03p_tab = it_dd03
EXCEPTIONS
illegal_input = 1
OTHERS = 2.
IF it_dd03[] IS INITIAL.
MESSAGE s000(oo) WITH '表' tabname '不存在'.
STOP.
ELSE.
IF 'TRANSP POOL CLUSTER' CS dd02v-tabclass.
DELETE it_dd03 WHERE datatype = 'CLNT' OR datatype = ''.
LOOP AT it_dd03 WHERE fieldname IN s_flds AND
inttype CA 'CNDT' AND
inttype IN s_type
OR keyflag = 'X'.
it_flds-fldname = it_dd03-fieldname.
it_flds-ref_tab = tabname.
it_flds-ref_fld = it_dd03-fieldname.
it_flds-convext = it_dd03-convexit.
it_flds-inttype = it_dd03-inttype.
APPEND it_flds.
IF it_dd03-keyflag = 'X'.
APPEND it_flds TO it_fkey.
ELSE.
APPEND it_flds TO it_fnok.
ENDIF.
ENDLOOP.
IF it_fnok[] IS INITIAL.
MESSAGE s000(oo) WITH '未找到CNDT类型的非KEY字段'.
STOP.
ENDIF.
ELSE.
MESSAGE s000(oo) WITH '只支持透明表/簇表/池表' DISPLAY LIKE 'E'.
STOP.
ENDIF.
ENDIF.
ENDFORM. "get_dd03
*&---------------------------------------------------------------------*
*& Form create_itab
*&---------------------------------------------------------------------*
FORM create_itab.
LOOP AT it_flds .
CONCATENATE it_flds-ref_tab '-' it_flds-ref_fld INTO paraname.
comp_des-type ?= cl_abap_datadescr=>describe_by_name( paraname ).
comp_des-name = it_flds-fldname.
APPEND comp_des TO comp_tab.
ENDLOOP.
LOOP AT s_sfld.
READ TABLE it_dd03 WITH KEY fieldname = s_sfld-low.
CHECK sy-subrc = 0.
READ TABLE it_flds WITH KEY fldname = s_sfld-low.
CHECK sy-subrc <> 0.
CONCATENATE p_tname '-' s_sfld-low INTO paraname.
comp_des-type ?= cl_abap_datadescr=>describe_by_name( paraname ).
comp_des-name = s_sfld-low.
APPEND comp_des TO comp_tab.
ENDLOOP.
stru_type = cl_abap_structdescr=>create( comp_tab[] ).
CREATE DATA rf_twa TYPE HANDLE stru_type.
ASSIGN rf_twa->* TO <fs_twa>.
itab_type = cl_abap_tabledescr=>create( stru_type ).
CREATE DATA rf_tabl TYPE HANDLE itab_type.
ASSIGN rf_tabl->* TO <fs_tabl>.
LOOP AT it_fkey.
PERFORM catset TABLES fldct
USING it_fkey-fldname 'RSREF' 'STRING' it_fkey-fldname.
ENDLOOP.
LOOP AT s_sfld.
READ TABLE it_dd03 WITH KEY fieldname = s_sfld-low.
CHECK sy-subrc = 0.
READ TABLE it_fkey WITH KEY fldname = s_sfld-low.
CHECK sy-subrc <> 0.
PERFORM catset TABLES fldct
USING s_sfld-low 'RSREF' 'STRING' s_sfld-low.
ENDLOOP.
PERFORM catset TABLES fldct
USING: 'FLDNAME' 'DD03L' 'FIELDNAME' '字段',
'FLDTYPE' 'DD03L' 'INTTYPE' '数据类型',
'FLDVALUE' 'RSREF' 'STRING' '字段值',
'HEXVALUE' 'RSREF' 'STRING' 'HEX'.
CALL METHOD cl_alv_table_create=>create_dynamic_table
EXPORTING
it_fieldcatalog = fldct[]
IMPORTING
ep_table = rf_out.
ASSIGN rf_out->* TO <fs_out>.
CREATE DATA rf_owa LIKE LINE OF <fs_out>.
ASSIGN rf_owa->* TO <fs_owa>.
ENDFORM. "create_itab
*&---------------------------------------------------------------------*
*& Form getdata
*&---------------------------------------------------------------------*
FORM getdata.
CLEAR whstr.
LOOP AT s_conl.
CONCATENATE whstr s_conl-low INTO whstr SEPARATED BY space.
ENDLOOP.
CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
EXPORTING
text = '开始在数据库取数...'.
TRY.
SELECT * INTO CORRESPONDING FIELDS OF TABLE <fs_tabl>
FROM (p_tname)
WHERE (whstr).
CATCH cx_root INTO cxroot.
excmsg = cxroot->get_text( ).
MESSAGE s000(oo) WITH '取数错误:' excmsg(50) excmsg+50(50) DISPLAY LIKE 'E'.
RETURN.
ENDTRY.
IF <fs_tabl> IS INITIAL.
MESSAGE s000(oo) WITH '数据库未取到数据'.
RETURN.
ENDIF.
WRITE sy-dbcnt TO char45 LEFT-JUSTIFIED.
numstr = lines( it_fnok ).
CONCATENATE '开始在' char45 '条记录,' numstr '个字段中查找...' INTO tmpstr.
CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
EXPORTING
text = tmpstr.
LOOP AT <fs_tabl> ASSIGNING <fs_twa>.
tabix = sy-tabix.
LOOP AT it_fnok .
ASSIGN COMPONENT it_fnok-fldname OF STRUCTURE <fs_twa> TO <fs_fld>.
IF p_hchar IS NOT INITIAL AND <fs_fld> IS INITIAL.
CONTINUE.
ENDIF.
IF p_hchar <> '' .
PERFORM findx USING p_hchar <fs_fld> CHANGING subrc.
ENDIF.
IF subrc = 0 OR p_hchar = '' .
MOVE-CORRESPONDING <fs_twa> TO <fs_owa>.
ASSIGN <fs_fld> TO <fsx> CASTING.
wa_value-fldname = it_fnok-fldname.
wa_value-fldtype = it_fnok-inttype.
wa_value-fldvalue = <fs_fld>.
wa_value-hexvalue = <fsx>.
MOVE-CORRESPONDING wa_value TO <fs_owa>.
APPEND <fs_owa> TO <fs_out>.
IF p_proind = 'X'.
tmpstr = sy-tabix.
percnt = tabix * 100 / sy-dbcnt.
CONCATENATE '已经找到' tmpstr '条' INTO tmpstr.
CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
EXPORTING
percentage = percnt
text = tmpstr.
ENDIF.
IF p_update = 'X' AND p_hchar <> ''.
CLEAR: keystr,wa_log.
wa_log-tabname = p_tname.
wa_log-fieldname = it_fnok-fldname.
wa_log-erdat = sy-datum.
wa_log-erzet = sy-uzeit.
wa_log-ernam = sy-uname.
wa_log-value_old = <fs_fld>.
IF pr_clr = 'X' OR it_fnok-inttype CA 'NDT'.
CLEAR <fs_fld>.
ELSE .
PERFORM replacex USING p_hchar <fs_fld> .
IF it_fnok-convext IS NOT INITIAL AND p_conv = 'X'.
CONCATENATE 'CONVERSION_EXIT_' it_fnok-convext '_INPUT' INTO fmname.
CALL FUNCTION fmname
EXPORTING
input = <fs_fld>
IMPORTING
output = <fs_fld>
EXCEPTIONS
OTHERS = 1.
ENDIF.
ENDIF.
wa_log-value_new = <fs_fld>.
CLEAR: con_str,set_str.
CONCATENATE it_fnok-fldname ` = <fs_fld>` INTO set_str.
LOOP AT it_fkey.
ASSIGN COMPONENT it_fkey-fldname OF STRUCTURE <fs_twa> TO <fs>.
tmpstr = <fs>.
IF sy-tabix = 1.
CONCATENATE it_fkey-fldname ` = '` tmpstr `'` INTO con_str.
ELSE.
CONCATENATE con_str ` AND ` it_fkey-fldname ` = '` tmpstr `'` INTO con_str.
ENDIF.
CONCATENATE keystr <fs> INTO keystr RESPECTING BLANKS.
ENDLOOP.
UPDATE (p_tname) SET (set_str) WHERE (con_str).
wa_log-objectid = keystr.
INSERT (logtname) FROM wa_log.
tmpint = tmpint + 1.
ENDIF.
ENDIF.
ENDLOOP.
IF tmpint > 1000. "超过1000条提交一次
COMMIT WORK.
CLEAR tmpint.
ENDIF.
ENDLOOP.
IF <fs_out> IS INITIAL.
MESSAGE s000(oo) WITH '未找到符合条件的数据'.
ELSEIF tmpint > 0.
COMMIT WORK.
ENDIF.
ENDFORM. "getdata
*&---------------------------------------------------------------------*
*& Form set_zero
*&---------------------------------------------------------------------*
FORM set_zero CHANGING char.
FIELD-SYMBOLS <fs_x> TYPE x.
ASSIGN char TO <fs_x> CASTING.
CLEAR <fs_x>.
ENDFORM. "set_zero
*&---------------------------------------------------------------------*
*& Form get_hchar
*&---------------------------------------------------------------------*
FORM get_hchar USING char CHANGING hchar.
FIELD-SYMBOLS <fs_x> TYPE x.
ASSIGN char TO <fs_x> CASTING.
hchar = <fs_x>.
ENDFORM. "get_hchar
*&---------------------------------------------------------------------*
*& Form findx
*&---------------------------------------------------------------------*
FORM findx USING value(xchar) str CHANGING subrc.
DATA len TYPE i.
FIELD-SYMBOLS <fs_x> TYPE x.
IF xchar = cspace.
IF str CA ''.
subrc = 0.
ELSE.
subrc = 4.
ENDIF.
ELSE.
len = strlen( xchar ) / 4.
ASSIGN xchar TO <fs_x> CASTING.
<fs_x> = xchar.
FIND xchar(len) IN str .
subrc = sy-subrc.
ENDIF.
ENDFORM. "findx
*&---------------------------------------------------------------------*
*& 替换字符串的二进制数据,仅用于UNICODE系统
*& 比如PERFORM replacex USING '000D000A' CHANGING str.
*& PERFORM replacex USING '0009' CHANGING str.
*&---------------------------------------------------------------------*
FORM replacex USING value(xchar) CHANGING value(str).
DATA len TYPE i.
FIELD-SYMBOLS <fs_x> TYPE x.
CHECK xchar <> ''.
len = strlen( xchar ) / 4.
ASSIGN xchar TO <fs_x> CASTING.
<fs_x> = xchar.
REPLACE ALL OCCURRENCES OF xchar(len) IN str WITH ''.
ENDFORM. "replacex
*&---------------------------------------------------------------------*
*& Form ASCII
*&---------------------------------------------------------------------*
FORM ascii .
DATA hex4 TYPE x LENGTH 4.
DATA hex1 TYPE x VALUE '20'.
DATA inta TYPE i.
FIELD-SYMBOLS <fc> TYPE c.
ASSIGN hex4 TO <fc> CASTING.
WHILE hex1 < '7F'.
IF %_endian = 'B'.
hex4+3 = hex1.
ELSE.
hex4+2 = hex1.
ENDIF.
WRITE: hex4+2, AT (8) <fc>+1 COLOR 6 INTENSIFIED ON INVERSE ON.
hex1 = hex1 + 1.
inta = sy-index MOD 8.
IF inta = 0. SKIP. ENDIF.
ENDWHILE.
ENDFORM. "ascii
*&---------------------------------------------------------------------*
*& Form replace_0x00
*&---------------------------------------------------------------------*
FORM replace_0x00 CHANGING data.
DATA dtype.
FIELD-SYMBOLS <fs>.
DESCRIBE FIELD data TYPE dtype.
CASE dtype.
WHEN 'C' OR 'N' OR 'D' OR 'T' OR 'g'.
REPLACE ALL OCCURRENCES OF %_minchar IN data WITH ''.
WHEN 'u' OR 'v'.
DO .
ASSIGN COMPONENT sy-index OF STRUCTURE data TO <fs>.
IF sy-subrc <> 0.
EXIT.
ELSE.
DESCRIBE FIELD <fs> TYPE dtype.
CHECK dtype CA 'CNDTg'.
REPLACE ALL OCCURRENCES OF %_minchar IN <fs> WITH ''.
ENDIF.
ENDDO.
WHEN 'h'.
MESSAGE e000(oo) WITH '输入对象不支持内表'.
WHEN OTHERS.
ENDCASE.
ENDFORM. "replace_0x00
*&---------------------------------------------------------------------*
*& Form outdata
*&---------------------------------------------------------------------*
FORM outdata.
slayt-zebra = 'X'.
slayt-no_toolbar = 'X'.
repid = sy-repid.
tmpstr = lines( <fs_out> ).
IF p_update = 'X'.
MESSAGE s000(oo) WITH '记录数:' tmpstr '. 数据库数据已更改'.
ELSE.
MESSAGE s000(oo) WITH '记录数:' tmpstr.
ENDIF.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
it_fieldcat_lvc = fldct[]
is_layout_lvc = slayt
i_callback_program = repid
i_callback_user_command = 'USER_COMMAND'
TABLES
t_outtab = <fs_out>.
ENDFORM. " outdata
*---------------------------------------------------------------------*
* FORM catset *
*---------------------------------------------------------------------*
FORM catset TABLES fldcat USING p_field p_reftab p_reffld p_text.
DATA: ls_fldcat TYPE lvc_s_fcat.
ls_fldcat-fieldname = p_field.
ls_fldcat-scrtext_l = p_text.
ls_fldcat-coltext = p_text.
ls_fldcat-ref_table = p_reftab.
ls_fldcat-ref_field = p_reffld.
IF p_field = 'HEXVALUE'.
ls_fldcat-outputlen = '60'.
ELSE.
ls_fldcat-col_opt = 'A'.
ENDIF.
IF 'FLDNAME FLDVALUE HEXVALUE FLDTYPE' CS p_field.
ls_fldcat-emphasize = 'C300'.
ENDIF.
READ TABLE it_fkey WITH KEY fldname = p_field.
IF sy-subrc = 0.
ls_fldcat-key = 'X'.
ENDIF.
APPEND ls_fldcat TO fldcat .
CLEAR ls_fldcat .
ENDFORM. "catset
*&--------------------------------------------------------------------*
*& Form user_command
*&--------------------------------------------------------------------*
FORM user_command USING r_ucomm TYPE sy-ucomm
r_field TYPE slis_selfield.
DATA: lr_fld TYPE REF TO data.
CASE r_ucomm.
WHEN '&IC1'.
READ TABLE <fs_out> INTO <fs_owa> INDEX r_field-tabindex.
MOVE-CORRESPONDING <fs_owa> TO wa_value.
CASE r_field-fieldname.
WHEN 'FLDNAME' OR 'FLDTYPE'.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = p_tname
object_type = 'TABL'
position = wa_value-fldname
EXCEPTIONS
not_executed = 01.
WHEN 'FLDVALUE'.
PERFORM selscreen_ext USING 'GET CRET NONE SPOS'.
CONCATENATE p_tname '-' wa_value-fldname INTO paraname.
CREATE DATA lr_fld TYPE (paraname).
ASSIGN lr_fld->* TO <fs_fld>.
<fs_fld> = wa_value-fldvalue.
WRITE <fs_fld> TO p_fval LEFT-JUSTIFIED .
CALL SELECTION-SCREEN 1100 STARTING AT 32 6 .
WHEN 'HEXVALUE'.
PERFORM show_hex USING wa_value-fldvalue wa_value-hexvalue.
WHEN OTHERS .
PERFORM se16_single_show USING <fs_owa>.
ENDCASE.
ENDCASE.
ENDFORM. "user_command
*&---------------------------------------------------------------------*
*& Form show_hex
*&---------------------------------------------------------------------*
FORM show_hex USING fldvalue hexvalue.
DATA: char255 TYPE char255.
DATA: lt_txt TYPE TABLE OF char4 WITH HEADER LINE.
DATA: lt_cat TYPE lvc_t_fcat WITH HEADER LINE.
DATA: BEGIN OF lt_out OCCURS 0,
index TYPE sy-index,
hchar TYPE char4,
cchar TYPE char2,
END OF lt_out.
CHECK hexvalue IS NOT INITIAL.
char255 = fldvalue.
CALL FUNCTION 'SCMS_STRING_TO_FTEXT'
EXPORTING
text = hexvalue
TABLES
ftext_tab = lt_txt.
LOOP AT lt_txt.
tabix = sy-tabix - 1.
lt_out-index = sy-tabix.
lt_out-hchar = lt_txt.
lt_out-cchar = char255+tabix(1).
APPEND lt_out.
ENDLOOP.
PERFORM catset TABLES lt_cat
USING: 'INDEX' '' '' 'INDEX',
'HCHAR' '' '' 'HCHAR',
'CCHAR' '' '' 'CCHAR'.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
it_fieldcat_lvc = lt_cat[]
i_screen_start_column = 60
i_screen_start_line = 1
i_screen_end_column = 84
i_screen_end_line = 20
TABLES
t_outtab = lt_out
EXCEPTIONS
program_error = 1.
ENDFORM. "show_hex
*&---------------------------------------------------------------------*
*& Form se16_single_show
*&---------------------------------------------------------------------*
FORM se16_single_show USING wa.
DATA: dba_sellist TYPE TABLE OF tbsellist WITH HEADER LINE.
DATA: action(4) VALUE 'EANZ'.
DATA: prog TYPE rsnewleng-programm.
DATA: mem_id(32) VALUE 'TABELLENANZEIGER'.
FIELD-SYMBOLS <ls_fld>.
LOOP AT it_fkey.
ASSIGN COMPONENT it_fkey-fldname OF STRUCTURE wa TO <ls_fld>.
dba_sellist-tablefield = it_fkey-fldname.
dba_sellist-operator = 'EQ'.
dba_sellist-value = <ls_fld>.
APPEND dba_sellist.
ENDLOOP.
EXPORT action dba_sellist TO MEMORY ID mem_id.
CONCATENATE '/1BCDWB/DB' p_tname INTO prog.
SUBMIT (prog) AND RETURN.
ENDFORM. "se16_single_show
*&---------------------------------------------------------------------*
*& 创建透明表
*&---------------------------------------------------------------------*
FORM create_table TABLES transfld STRUCTURE dd03p
USING transtab ddtext devclass .
DATA: objstr(40),
reqnum TYPE trkorr.
DATA: wa_02v TYPE dd02v ,
wa_09l TYPE dd09v ,
subrc TYPE sy-subrc.
DATA: lt_03p TYPE TABLE OF dd03p WITH HEADER LINE .
SELECT SINGLE * INTO wa_02v FROM dd02v
WHERE tabname = transtab AND
tabclass = 'TRANSP'.
IF sy-subrc = 0.
MESSAGE s000(oo) WITH '透明表' transtab '已存在'.
RETURN.
ENDIF.
***传输请求
CONCATENATE 'TABL' transtab INTO objstr.
CALL FUNCTION 'RS_CORR_INSERT'
EXPORTING
object = objstr
object_class = 'DICT'
devclass = devclass
korrnum = reqnum
master_language = sy-langu
global_lock = 'X'
mode = 'I'
suppress_dialog = ''
IMPORTING
ordernum = reqnum
EXCEPTIONS
cancelled = 1
permission_failure = 2
unknown_objectclass = 3
OTHERS = 4.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 .
ENDIF.
***创建透明表并激活
wa_02v-tabname = transtab.
wa_02v-ddtext = ddtext.
wa_02v-ddlanguage = sy-langu.
wa_02v-tabclass = 'TRANSP'.
wa_02v-as4user = sy-uname.
wa_02v-contflag = 'C'.
wa_02v-mainflag = 'X'.
wa_09l-tabname = transtab.
wa_09l-tabart = 'APPL1'.
wa_09l-tabkat = 6.
LOOP AT transfld.
lt_03p-tabname = transtab.
lt_03p-ddlanguage = sy-langu.
lt_03p-position = sy-tabix.
lt_03p-fieldname = transfld-fieldname.
lt_03p-rollname = transfld-rollname.
lt_03p-notnull = 'X'.
lt_03p-keyflag = transfld-keyflag.
APPEND lt_03p.
CLEAR lt_03p.
ENDLOOP.
CALL FUNCTION 'DDIF_TABL_PUT'
EXPORTING
name = transtab
dd02v_wa = wa_02v
dd09l_wa = wa_09l
TABLES
dd03p_tab = lt_03p
EXCEPTIONS
tabl_not_found = 1
name_inconsistent = 2
tabl_inconsistent = 3
put_failure = 4
put_refused = 5
OTHERS = 6.
IF sy-subrc = 0.
CALL FUNCTION 'DDIF_TABL_ACTIVATE'
EXPORTING
name = transtab
IMPORTING
rc = subrc
EXCEPTIONS
not_found = 1
put_failure = 2
OTHERS = 3.
IF sy-subrc <> 0 OR ( subrc > 4 ).
MESSAGE s000(oo) WITH '创建成功,激活失败,请手工激活表ZCSL'.
ELSE.
MESSAGE s000(oo) WITH '创建成功,激活成功'.
ENDIF.
ELSE.
MESSAGE s000(oo) WITH '创建失败'.
ENDIF.
ENDFORM. "create_table
*&---------------------------------------------------------------------*
*& Form fill_dd03
*&---------------------------------------------------------------------*
FORM fill_dd03 USING fldname rollname key.
it_dd03-fieldname = fldname.
it_dd03-rollname = rollname.
it_dd03-keyflag = key.
APPEND it_dd03. CLEAR it_dd03.
ENDFORM. "fill_dd03
*&---------------------------------------------------------------------*
*& Form UPDATE_SINGLE_FLD
*&---------------------------------------------------------------------*
FORM update_single_fld USING tabname fldname fldval whestr astxt.
DATA: lt_setstr TYPE string.
DATA: lr_table TYPE REF TO data,
lr_line TYPE REF TO data.
FIELD-SYMBOLS: <lfs_tab> TYPE STANDARD TABLE, <lfs_wa>, <lfs>.
PERFORM get_dd03 USING tabname.
TRY.
CREATE DATA lr_table TYPE TABLE OF (tabname).
ASSIGN lr_table->* TO <lfs_tab>.
CREATE DATA lr_line LIKE LINE OF <lfs_tab>.
ASSIGN lr_line->* TO <lfs_wa>.
SELECT * INTO TABLE <lfs_tab> FROM (p_uptab) WHERE (p_upwhe).
IF sy-subrc <> 0.
MESSAGE e000(oo) WITH '未找到数据'.
ENDIF.
LOOP AT <lfs_tab> INTO <lfs_wa>.
CLEAR: keystr,wa_log.
LOOP AT it_fkey.
ASSIGN COMPONENT it_fkey-fldname OF STRUCTURE <lfs_wa> TO <lfs>.
CONCATENATE keystr <lfs> INTO keystr RESPECTING BLANKS.
ENDLOOP.
ASSIGN COMPONENT fldname OF STRUCTURE <lfs_wa> TO <lfs>.
IF sy-subrc <> 0.
MESSAGE e000(oo) WITH `数据库列'` fldname `'未知`.
ENDIF.
tmpstr = fldval.
wa_log-tabname = tabname.
wa_log-objectid = keystr.
wa_log-fieldname = fldname.
wa_log-erdat = sy-datum.
wa_log-erzet = sy-uzeit.
wa_log-ernam = sy-uname.
wa_log-value_old = <lfs>.
wa_log-value_new = tmpstr.
INSERT (logtname) FROM wa_log.
ENDLOOP.
IF astxt = 'X'.
CONCATENATE fldname ` = tmpstr ` INTO lt_setstr.
ELSE.
CONCATENATE fldname ` = ` tmpstr INTO lt_setstr.
ENDIF.
UPDATE (p_uptab) SET (lt_setstr) WHERE (p_upwhe).
IF sy-subrc = 0.
COMMIT WORK.
MESSAGE s000(oo) WITH '更新数据条数:' sy-dbcnt .
ELSE.
ROLLBACK WORK.
MESSAGE e000(oo) WITH '更新失败'.
ENDIF.
CATCH cx_root INTO cxroot.
ROLLBACK WORK.
excmsg = cxroot->get_text( ).
MESSAGE e000(oo) WITH excmsg.
ENDTRY.
ENDFORM. " UPDATE_SINGLE_FLD
*&---------------------------------------------------------------------*
*& 弹出选择屏幕屏蔽按钮
*&---------------------------------------------------------------------*
FORM selscreen_ext USING extfcode.
DATA: exttab TYPE slis_t_extab.
SPLIT extfcode AT space INTO TABLE exttab.
CALL FUNCTION 'RS_SET_SELSCREEN_STATUS'
EXPORTING
p_status = '%_CSP'
TABLES
p_exclude = exttab.
ENDFORM. "selscreen_ext