在项目里面,用户需求需要记录自建表写入CDPOS与CDHDR,此处为SM30做更新。
SCDO新建对应的对象
自建表做全部字段域里面更改文档的更改信息
再到SM30修改事件里面定义事件
01 FRM_BEFORE_SAVE
02 FRM_AFTER_SAVE
05 FRM_INITIAL_DATA
21 FRM_INITIAL_DATA
25 CHECK_AUTH
最后代码
*----------------------------------------------------------------------*
***INCLUDE LZTBCA_USERF01 .
*----------------------------------------------------------------------*
FORM check_auth.
* AUTHORITY-CHECK OBJECT 'ZBOC_USER'
* ID 'R_USER' FIELD 'X'.
AUTHORITY-CHECK OBJECT 'S_TCODE'
ID 'TCD' FIELD 'ZBOC_USER'.
IF sy-subrc NE 0 AND sy-ucomm = 'AEND'.
MESSAGE '没有权限' TYPE 'S' DISPLAY LIKE 'E'.
sy-ucomm = function = 'ANZG'.
ENDIF.
ENDFORM. "check_auth
FORM frm_initial_data.
IF ztbca_user-crdat IS INITIAL.
ztbca_user-crdat = sy-datum.
ztbca_user-crnam = sy-uname.
ztbca_user-crtim = sy-uzeit.
ENDIF.
ztbca_user-upnam = sy-uname.
ztbca_user-updat = sy-datum.
ztbca_user-uptim = sy-uzeit.
ztbca_user-uppgm = sy-tcode.
ENDFORM. "check_auth
*&---------------------------------------------------------------------*
*& Form FRM_BEFORE_SAVE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_before_save .
TYPES: BEGIN OF ty_tcdrp,
object TYPE cdobjectcl,
reportname TYPE cdreport,
END OF ty_tcdrp,
BEGIN OF ty_view_tab,
object TYPE cdobjectcl,
tabname TYPE cdtabname,
END OF ty_view_tab.
DATA: lt_ptab TYPE STANDARD TABLE OF string,
lv_prog TYPE string,
lv_mess TYPE string,
lv_sid TYPE string,
lt_obj TYPE STANDARD TABLE OF ty_view_tab,
lt_tcdrp TYPE STANDARD TABLE OF ty_tcdrp,
lv_fugn TYPE funct_pool,
lv_table TYPE cdtabname,
lv_namesfunc TYPE namespace,
lv_funcgroup TYPE progname,
lv_namesprog TYPE namespace,
lv_program TYPE progname,
lrt_tabname TYPE RANGE OF tabname,
lt_dd26v TYPE TABLE OF dd26v,
lv_object TYPE cdobjectcl.
DATA: objectid TYPE cdhdr-objectid,
tcode TYPE cdhdr-tcode,
planned_change_number TYPE cdhdr-planchngnr,
utime TYPE cdhdr-utime,
udate TYPE cdhdr-udate,
username TYPE cdhdr-username,
cdoc_planned_or_real TYPE cdhdr-change_ind,
cdoc_upd_object TYPE cdhdr-change_ind VALUE 'U',
cdoc_no_change_pointers TYPE cdhdr-change_ind.
* declaration for the long text
DATA: BEGIN OF icdtxt_yztbca_user OCCURS 20.
INCLUDE STRUCTURE cdtxt.
DATA: END OF icdtxt_yztbca_user.
DATA: upd_icdtxt_yztbca_user TYPE c.
* table with the NEW content of: ZTBCA_USER
DATA: BEGIN OF xztbca_user OCCURS 20.
INCLUDE STRUCTURE yztbca_user.
DATA: END OF xztbca_user.
* table with the OLD content of: ZTBCA_USER
DATA: BEGIN OF yztbca_user OCCURS 20.
INCLUDE STRUCTURE yztbca_user.
DATA: END OF yztbca_user.
DATA: upd_ztbca_user TYPE c.
" Get tabnames
" DD: Interface for reading a view from the ABAP/4 Dictionary
CALL FUNCTION 'DDIF_VIEW_GET'
EXPORTING
name = vim_view_name
TABLES
dd26v_tab = lt_dd26v
EXCEPTIONS
illegal_input = 1
OTHERS = 2.
IF sy-subrc IS NOT INITIAL.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
IF lt_dd26v IS INITIAL.
APPEND INITIAL LINE TO lrt_tabname ASSIGNING FIELD-SYMBOL(<lrs_tabname>).
<lrs_tabname>-sign = 'I'.
<lrs_tabname>-option = 'EQ'.
<lrs_tabname>-low = vim_view_name.
ELSE.
SORT lt_dd26v BY tabname.
DELETE ADJACENT DUPLICATES FROM lt_dd26v COMPARING tabname.
"*-
LOOP AT lt_dd26v INTO DATA(ls_dd26v).
APPEND INITIAL LINE TO lrt_tabname ASSIGNING <lrs_tabname>.
<lrs_tabname>-sign = 'I'.
<lrs_tabname>-option = 'EQ'.
<lrs_tabname>-low = ls_dd26v-tabname.
ENDLOOP.
ENDIF.
" Objects for change document creation
SELECT object tabname
FROM tcdob
INTO TABLE lt_obj
WHERE tabname IN lrt_tabname
##WARN_OK.
IF sy-subrc IS NOT INITIAL.
" No change document objects found
MESSAGE i899(cd).
RETURN.
ENDIF.
" Information on Include Reports Generated by RSSCD000
SELECT object reportname
FROM tcdrp
INTO TABLE lt_tcdrp
FOR ALL ENTRIES IN lt_obj
WHERE object EQ lt_obj-object
##WARN_OK.
IF sy-subrc IS NOT INITIAL.
" Update program does not yet exist
MESSAGE i446(m2).
RETURN.
ENDIF.
" View Directory
SELECT SINGLE area
FROM tvdir
INTO lv_fugn
WHERE tabname EQ vim_view_name.
"*-
LOOP AT lt_obj ASSIGNING FIELD-SYMBOL(<ls_obj>).
READ TABLE lt_tcdrp ASSIGNING FIELD-SYMBOL(<ls_tcdrp>)
WITH KEY object = <ls_obj>-object.
IF sy-subrc IS NOT INITIAL.
CONTINUE.
ENDIF.
" Split namespace
CLEAR: lv_namesprog, lv_program.
lv_program = <ls_tcdrp>-reportname.
CALL FUNCTION 'RS_NAME_SPLIT_NAMESPACE'
EXPORTING
name_with_namespace = lv_program
IMPORTING
namespace = lv_namesprog
name_without_namespace = lv_program
EXCEPTIONS
delimiter_error = 1
OTHERS = 2.
IF sy-subrc <> 0.
lv_program = <ls_tcdrp>-reportname.
ENDIF.
CLEAR: lv_namesfunc, lv_funcgroup.
lv_funcgroup = lv_fugn.
CALL FUNCTION 'RS_NAME_SPLIT_NAMESPACE'
EXPORTING
name_with_namespace = lv_funcgroup
IMPORTING
namespace = lv_namesfunc
name_without_namespace = lv_funcgroup
EXCEPTIONS
delimiter_error = 1
OTHERS = 2.
IF sy-subrc <> 0.
lv_funcgroup = lv_fugn.
ENDIF.
" Namespace conversion
lv_object = <ls_obj>-object.
IF lv_object(1) = '/'.
SHIFT lv_object LEFT DELETING LEADING '/'.
REPLACE FIRST OCCURRENCE OF '/' IN lv_object WITH '_'.
ENDIF.
lv_table = <ls_obj>-tabname.
IF lv_table(1) = '/'.
SHIFT lv_table LEFT DELETING LEADING '/'.
REPLACE FIRST OCCURRENCE OF '/' IN lv_table WITH '_'.
ENDIF.
TYPES: BEGIN OF total.
INCLUDE STRUCTURE ztbca_user.
INCLUDE STRUCTURE vimflagtab.
TYPES: END OF total.
FIELD-SYMBOLS: <fs_total> TYPE ANY TABLE,
<fs_total_wa> TYPE total,
<fs_x_namtab> TYPE ANY TABLE,
<fs_x_namtab_wa> TYPE vimnamtab,
<fs_field> TYPE any.
DATA: lv_tabname(40) TYPE c VALUE '(SAPLZTBCA_USER)TOTAL[]',
lv_cond_line TYPE string,
lv_cond_line2 TYPE string.
ASSIGN (lv_tabname) TO <fs_total>.
LOOP AT <fs_total> ASSIGNING <fs_total_wa> CASTING.
CASE <fs_total_wa>-action.
WHEN 'U'. " Update
lv_tabname = '(SAPLZTBCA_USER)X_NAMTAB[]'.
ASSIGN (lv_tabname) TO <fs_x_namtab>.
lv_cond_line2 = |keyflag EQ 'X' AND viewfield NE 'MANDT'|.
LOOP AT <fs_x_namtab> ASSIGNING <fs_x_namtab_wa> WHERE (lv_cond_line2).
ASSIGN COMPONENT <fs_x_namtab_wa>-viewfield OF STRUCTURE <fs_total_wa> TO <fs_field>.
IF sy-subrc IS INITIAL.
lv_cond_line = lv_cond_line && |AND | &&
<fs_x_namtab_wa>-viewfield && | EQ '| && <fs_field> && |' |.
objectid = objectid && <fs_field>.
UNASSIGN <fs_field>.
ENDIF.
ENDLOOP.
IF sy-subrc IS INITIAL.
SHIFT lv_cond_line LEFT BY 3 PLACES.
SELECT SINGLE *
FROM ztbca_user
INTO ztbca_user
WHERE (lv_cond_line).
MOVE-CORRESPONDING ztbca_user TO xztbca_user.
APPEND xztbca_user.
MOVE-CORRESPONDING <fs_total_wa> TO yztbca_user.
APPEND yztbca_user.
objectid = objectid.
tcode = sy-tcode.
udate = sy-datum.
utime = sy-uzeit.
username = sy-uname.
cdoc_upd_object = 'U'.
upd_ztbca_user = 'U'.
IF ( upd_ztbca_user NE space )
OR ( upd_icdtxt_yztbca_user NE space )
.
CALL FUNCTION 'YZTBCA_USER_WRITE_DOCUMENT' IN UPDATE TASK
EXPORTING
objectid = objectid
tcode = tcode
utime = utime
udate = udate
username = username
planned_change_number = planned_change_number
object_change_indicator = cdoc_upd_object
planned_or_real_changes = cdoc_planned_or_real
no_change_pointers = cdoc_no_change_pointers
* updateflag of ZTBCA_USER
upd_ztbca_user = upd_ztbca_user
upd_icdtxt_yztbca_user = upd_icdtxt_yztbca_user
TABLES
icdtxt_yztbca_user = icdtxt_yztbca_user
xztbca_user = xztbca_user
yztbca_user = yztbca_user.
ENDIF.
ENDIF.
WHEN 'N'. " New
lv_tabname = '(SAPLZTBCA_USER)X_NAMTAB[]'.
ASSIGN (lv_tabname) TO <fs_x_namtab>.
lv_cond_line2 = |keyflag EQ 'X' AND viewfield NE 'MANDT'|.
LOOP AT <fs_x_namtab> ASSIGNING <fs_x_namtab_wa> WHERE (lv_cond_line2).
ASSIGN COMPONENT <fs_x_namtab_wa>-viewfield OF STRUCTURE <fs_total_wa> TO <fs_field>.
IF sy-subrc IS INITIAL.
objectid = objectid && <fs_field>.
UNASSIGN <fs_field>.
ENDIF.
ENDLOOP.
IF sy-subrc IS INITIAL.
MOVE-CORRESPONDING <fs_total_wa> TO yztbca_user.
APPEND yztbca_user.
objectid = objectid.
tcode = sy-tcode.
udate = sy-datum.
utime = sy-uzeit.
username = sy-uname.
cdoc_upd_object = 'I'.
upd_ztbca_user = 'I'.
IF ( upd_ztbca_user NE space )
OR ( upd_icdtxt_yztbca_user NE space )
.
CALL FUNCTION 'YZTBCA_USER_WRITE_DOCUMENT' IN UPDATE TASK
EXPORTING
objectid = objectid
tcode = tcode
utime = utime
udate = udate
username = username
planned_change_number = planned_change_number
object_change_indicator = cdoc_upd_object
planned_or_real_changes = cdoc_planned_or_real
no_change_pointers = cdoc_no_change_pointers
* updateflag of ZTBCA_USER
upd_ztbca_user = upd_ztbca_user
upd_icdtxt_yztbca_user = upd_icdtxt_yztbca_user
TABLES
icdtxt_yztbca_user = icdtxt_yztbca_user
xztbca_user = xztbca_user
yztbca_user = yztbca_user.
ENDIF.
ENDIF.
WHEN 'D'. " Delete
lv_tabname = '(SAPLZTBCA_USER)X_NAMTAB[]'.
ASSIGN (lv_tabname) TO <fs_x_namtab>.
lv_cond_line2 = |keyflag EQ 'X' AND viewfield NE 'MANDT'|.
LOOP AT <fs_x_namtab> ASSIGNING <fs_x_namtab_wa> WHERE (lv_cond_line2).
ASSIGN COMPONENT <fs_x_namtab_wa>-viewfield OF STRUCTURE <fs_total_wa> TO <fs_field>.
IF sy-subrc IS INITIAL.
objectid = objectid && <fs_field>.
UNASSIGN <fs_field>.
ENDIF.
ENDLOOP.
IF sy-subrc IS INITIAL.
MOVE-CORRESPONDING <fs_total_wa> TO yztbca_user.
APPEND yztbca_user.
objectid = objectid.
tcode = sy-tcode.
udate = sy-datum.
utime = sy-uzeit.
username = sy-uname.
cdoc_upd_object = 'D'.
upd_ztbca_user = 'D'.
IF ( upd_ztbca_user NE space )
OR ( upd_icdtxt_yztbca_user NE space )
.
CALL FUNCTION 'YZTBCA_USER_WRITE_DOCUMENT' IN UPDATE TASK
EXPORTING
objectid = objectid
tcode = tcode
utime = utime
udate = udate
username = username
planned_change_number = planned_change_number
object_change_indicator = cdoc_upd_object
planned_or_real_changes = cdoc_planned_or_real
no_change_pointers = cdoc_no_change_pointers
* updateflag of ZTBCA_USER
upd_ztbca_user = upd_ztbca_user
upd_icdtxt_yztbca_user = upd_icdtxt_yztbca_user
TABLES
icdtxt_yztbca_user = icdtxt_yztbca_user
xztbca_user = xztbca_user
yztbca_user = yztbca_user.
ENDIF.
ENDIF.
ENDCASE.
CLEAR: lv_cond_line, lv_cond_line2, objectid, ztbca_user, *ztbca_user.
ENDLOOP.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_AFTER_SAVE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_after_save .
COMMIT WORK AND WAIT.
ENDFORM.
其次之前另外一个项目也做了程序做整表更新,同样写入底表记录