1.关于前几篇介绍的外挂程序,SAP中的业务单据还是要区分具体的操作人员。如建立财务凭证,工号A,B,C使用相同的SAP账号,那就没办法知道是谁操作的了啊,所以sap的业务单据需要细分到具体人员的都要增强实现以下:
如生产工单:
具体的增强点:
2.辅助程序:SAP账号自动锁定功能
*&---------------------------------------------------------------------*
*& Report ZBA001
*&---------------------------------------------------------------------*
*& 实现人员离职时,SAP账号与外挂账号自动锁定功能,减少手工锁定账号工作量
*&---------------------------------------------------------------------*
REPORT zba001.
TABLES:pa0000,usr02,zjpmf_user.
*PA0000-PERNR 工号
*PA0000-STAT2 人员状态 PA0000-STAT2=0代表:离职
*USR02-ACCNT SAP账号 SAP账号用来维护工号的字段,用PA0000-PERNR关联USR02-ACCNT,得到SAP账号(USR02-BNAME),
* 触发USR02-UFLAG:64=锁定
*zjpmf_user-EMPLYEE_ID SAP外挂表工号字段 SAP外挂账号对应工号字段,用PA0000-PERNR关联zjpmf_user-EMPLYEE_ID,
* 得到外挂账号(zjpmf_user-USER_CODE),触发zjpmf_user-ACTIVE_FLAG=空时为锁定
*
*逻辑:
*1.定期任务,每天执行一次,每天01:00定时执行;
*2.用USR02-ACCNT与zjpmf_user-EMPLYEE_ID分别关联PA0000-PERNR,查询PA0000-STAT2值是否为0
*3.若PA0000-STAT2值是否为0时,将USR02-UFLAG值变更为64与zjpmf_user-ACTIVE_FLAG值变为空
*4.第2点中,当USR02-ACCNT为空时,不进行关联,直接忽略此条数据
*5.第3点中,因账号有SAP账号与外挂账号,故两个表中的数据都要进行关联,程序直接将关联到的数据进行执行锁定操作,关联不到则直接跳过。
*6.BEGDA=前一天日期,ENDDA=当天日期 ,查PA0000,P0000-MASSN=Z9并且P0000-STAT2=0,外面需要增加两个日期begda和endda的查询条件,
* 查询里面要加P0000-MASSN=Z9 并且P0000-STAT2=0 的条件
*BAPI_USER_LOCK
*BAPI_USER_UNLOCK
" DATA:gv_username TYPE bapibname-bapibname.
DATA:BEGIN OF gs_data,
pernr TYPE pa0000-pernr,
bname TYPE usr02-bname,
END OF gs_data,
gt_data LIKE TABLE OF gs_data.
DATA:gs_return TYPE bapiret2,
gt_return TYPE TABLE OF bapiret2.
DATA:lv_begda TYPE p0001-begda.
DATA:gv_user_code TYPE zjpmf_user-user_code.
DATA:gv_code TYPE zjpmf_user-user_code.
***Begin add by IT072 10.05.2021 18:49:24
DATA: gv_name TYPE BAPIBNAME-BAPIBNAME,
gv_mesage TYPE string.
DATA: gt_group TYPE TABLE OF BAPIGROUPS,
gt_returnd TYPE TABLE OF BAPIRET2,
gs_returnd TYPE BAPIRET2.
DATA: lv_memo TYPE string .
***End add by IT072 10.05.2021 18:49:24
PARAMETERS:p_begda TYPE pa0000-begda ,
p_endda TYPE pa0000-endda .
INITIALIZATION.
lv_memo = '离职停用' && sy-datum.
CALL FUNCTION 'RP_CALC_DATE_IN_INTERVAL'
EXPORTING
date = sy-datum
days = 7
months = 0
signum = '-'
years = 0
IMPORTING
calc_date = lv_begda.
IF p_begda IS INITIAL.
p_begda = lv_begda .
ENDIF.
IF p_endda IS INITIAL.
p_endda = sy-datum ."'99991231'
ENDIF.
START-OF-SELECTION.
*-- 取离职状态人员
SELECT pernr
bname
INTO CORRESPONDING FIELDS OF TABLE gt_data FROM pa0000 AS a
LEFT JOIN usr02 AS b ON a~pernr = b~accnt
WHERE stat2 = 0
AND massn = 'Z9'
* AND begda >= p_begda and begda <= p_endda
AND AEDTM >= p_begda AND AEDTM <= p_endda.
* AND endda <= p_endda.
LOOP AT gt_data INTO gs_data.
*-- SAP账号
IF GS_DATA-BNAME IS NOT INITIAL.
CALL FUNCTION 'BAPI_USER_LOCK'
EXPORTING
username = gs_data-bname
TABLES
return = gt_return.
***Begin add by IT072 10.05.2021 18:47:01
* 新增逻辑判断离职被锁定账号是否为 *PLM* 账号,如果是则删除该账号的组参数
IF gs_data-bname CS 'PLM'.
CLEAR: gv_name,gt_group[],gt_returnd[],gs_returnd.
gv_name = gs_data-bname.
CALL FUNCTION 'BAPI_USER_CHANGE'
EXPORTING
username = gv_name
GROUPSX = 'X' " 有标记则表示要根据组内表更新组参数
tables
return = gt_returnd
GROUPS = gt_group . " 将空的组内表更新到账号里
READ TABLE gt_returnd TRANSPORTING NO FIELDS WITH KEY TYPE = 'E'.
IF sy-subrc = 0.
CLEAR: gv_mesage.
gv_mesage = '删除用户' && gv_name && '组参数失败!' .
LOOP AT gt_returnd INTO gs_returnd WHERE TYPE = 'E'.
gv_mesage = gv_mesage && '/' && gs_returnd-message.
ENDLOOP.
MESSAGE gv_mesage TYPE 'S' DISPLAY LIKE 'E'.
ENDIF.
ENDIF.
***End add by IT072 10.05.2021 18:47:01
ENDIF.
*-- 外挂账号
SELECT SINGLE user_code INTO gv_code FROM zjpmf_user WHERE emplyee_id = gs_data-pernr and active_flag = 'X'.
IF sy-subrc = 0.
UPDATE zjpmf_user SET active_flag = '' MEMO = lv_memo LAEDA = SY-DATUM TIMES = SY-UZEIT AENAM = sy-UNAME
WHERE emplyee_id = gs_data-pernr and active_flag = 'X'."AND user_code = gv_code
ENDIF.
ENDLOOP.
3. 辅助程序:SAP外挂账号更新更改凭证
*&---------------------------------------------------------------------*
*& Report ZBA002
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zba002.
*----------------------------------------------------------------------*
* TABLE
*----------------------------------------------------------------------*
TABLES: zjpmf_user,bkk82.
*----------------------------------------------------------------------*
* 结构申明
*----------------------------------------------------------------------*
TYPE-POOLS: p99sg.
TYPES: BEGIN OF ty_user.
INCLUDE STRUCTURE zjpmf_user.
TYPES: END OF ty_user.
*----------------------------------------------------------------------*
* 内表申明
*----------------------------------------------------------------------*
DATA: gt_user TYPE TABLE OF ty_user,
gs_user LIKE LINE OF gt_user.
*----------------------------------------------------------------------*
* 全局变量定义
*----------------------------------------------------------------------*
DATA: days TYPE i,
weeks TYPE i,
months TYPE i,
years TYPE i.
DATA: l_mod TYPE i.
DATA: p_date TYPE i VALUE 90.
DATA: month_tab TYPE STANDARD TABLE OF p99sg_month_tab_row.
*----------------------------------------------------------------------*
* 标准屏幕
*----------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK a1 WITH FRAME TITLE TEXT-001.
SELECT-OPTIONS:
s_userid FOR zjpmf_user-emplyee_id ,
s_sapid FOR zjpmf_user-sap_id,
s_name FOR zjpmf_user-user_name,
s_dept FOR zjpmf_user-user_dept,
s_days FOR bkk82-numbdays NO INTERVALS OBLIGATORY.
SELECTION-SCREEN END OF BLOCK a1.
*----------------------------------------------------------------------*
* 初始化
*----------------------------------------------------------------------*
INITIALIZATION.
s_days-low = 90.
s_days-option = 'EQ'.
s_days-sign = 'I'.
APPEND s_days.
*----------------------------------------------------------------------*
* START-OF-SELECTION
*----------------------------------------------------------------------*
*----选择屏幕事件----------------------------------------------------------------*
AT SELECTION-SCREEN.
*AT SELECTION-SCREEN OUTPUT.
*----------选择事件结束----------------------------------------------------------*
START-OF-SELECTION.
SELECT *
INTO TABLE gt_user
FROM zjpmf_user
WHERE emplyee_id IN s_userid
AND sap_id IN s_sapid
AND user_name IN s_name
AND user_dept IN s_dept.
LOOP AT gt_user INTO gs_user.
IF gs_user-change_date IS INITIAL.
gs_user-flash_psw = 'X'.
ELSE.
CALL FUNCTION 'HR_99S_INTERVAL_BETWEEN_DATES'
EXPORTING
begda = gs_user-change_date "开始日期
endda = sy-datum "截止日期
IMPORTING
days = days. "返回天数
l_mod = days MOD s_days-low.
IF l_mod = 0.
gs_user-flash_psw = 'X'.
ENDIF.
ENDIF.
MODIFY gt_user FROM gs_user.
ENDLOOP.
IF gt_user IS NOT INITIAL.
MODIFY zjpmf_user FROM TABLE gt_user.
ENDIF.
4. 辅助程序:用户清单查看程序
*&---------------------------------------------------------------------*
*& Report ZUSER_LIST
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT zuser_list.
TYPE-POOLS vrm. "输入屏幕下拉框
TABLES: zjpmf_user.
"ALV用到的类型定义
DATA: it_fieldcat TYPE slis_t_fieldcat_alv WITH HEADER LINE,
lt_sort TYPE slis_t_sortinfo_alv WITH HEADER LINE,
it_events TYPE slis_t_event,
lt_event_exit TYPE slis_t_event_exit,
ls_event_exit TYPE slis_event_exit,
gs_print TYPE slis_print_alv,
gs_layout TYPE slis_layout_alv.
DATA: BEGIN OF wa_user.
DATA: box(1).
INCLUDE STRUCTURE zjpmf_user.
DATA: END OF wa_user.
DATA: it_user LIKE TABLE OF wa_user WITH HEADER LINE.
DATA: it_alv LIKE TABLE OF wa_user WITH HEADER LINE.
*--------------------------------------------------------------------*
*增加公司代码区分
DATA: current_user LIKE sy-uname.
DATA: current_companycode LIKE t001-bukrs.
DATA: BEGIN OF wa_usr21,
bname LIKE usr21-bname,
persnumber LIKE usr21-persnumber,
addrnumber LIKE usr21-addrnumber,
END OF wa_usr21.
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.
SELECT-OPTIONS: s_uscode FOR zjpmf_user-user_code,
s_empid FOR zjpmf_user-emplyee_id,
s_sapid FOR zjpmf_user-sap_id,
s_usname FOR zjpmf_user-user_name.
SELECTION-SCREEN END OF BLOCK b1.
AT SELECTION-SCREEN OUTPUT.
current_user = sy-uname.
SELECT SINGLE * INTO CORRESPONDING FIELDS OF wa_usr21 FROM usr21 WHERE bname EQ current_user.
SELECT SINGLE department INTO current_companycode FROM adcp WHERE addrnumber = wa_usr21-addrnumber AND persnumber = wa_usr21-persnumber.
START-OF-SELECTION.
IF current_companycode EQ space.
MESSAGE s000(oo) WITH '当前登陆账户的公司代码有误,请检查!' DISPLAY LIKE 'E'.
STOP.
ENDIF.
PERFORM get_data.
PERFORM show_alv.
*&---------------------------------------------------------------------*
*& Form GET_DATA
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM get_data .
IF current_companycode EQ '1100'.
SELECT * INTO CORRESPONDING FIELDS OF TABLE it_alv
FROM zjpmf_user
WHERE user_code IN s_uscode
AND emplyee_id IN s_empid
AND sap_id IN s_sapid
AND user_name IN s_usname.
ELSE.
SELECT * INTO CORRESPONDING FIELDS OF TABLE it_alv
FROM zjpmf_user
WHERE user_code IN s_uscode
AND emplyee_id IN s_empid
AND sap_id IN s_sapid
AND user_name IN s_usname
AND company_code EQ current_companycode.
ENDIF.
ENDFORM. " GET_DATA
*&---------------------------------------------------------------------*
*& Form SHOW_ALV
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM show_alv .
PERFORM set_fieldcat.
PERFORM set_layout.
PERFORM display_alv.
ENDFORM. " SHOW_ALV
*&---------------------------------------------------------------------*
*& Form SET_FIELDCAT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM set_fieldcat .
*初始化fieldcat
CLEAR it_fieldcat.
*定义宏,用于将相应字段添加到表fieldcat
DEFINE m_fieldcat.
it_fieldcat-fieldname = &1.
translate it_fieldcat-fieldname to upper case.
it_fieldcat-seltext_l = &2.
it_fieldcat-outputlen = &3.
append it_fieldcat.
END-OF-DEFINITION.
m_fieldcat 'USER_CODE' '用户账号' ' '.
m_fieldcat 'EMPLYEE_ID' '工号' ' '.
m_fieldcat 'SAP_ID' 'SAP账号' ' '.
m_fieldcat 'USER_NAME' '用户名' ' '.
m_fieldcat 'USER_DEPT' '部门' ' '.
m_fieldcat 'CREATE_DATE' '建立日期' ' '.
m_fieldcat 'ACTIVE_FLAG' '激活标志' ' '.
m_fieldcat 'FLASH_PSW' '改密码标志' ' '.
m_fieldcat 'MEMO' '备注' ' '.
m_fieldcat 'CHANGE_DATE' '修改日期' ' '.
* m_fieldcat 'EXT_CONN' '本币' ' '.
m_fieldcat 'TEL_NUMBER' '固定电话' ' '.
m_fieldcat 'MOB_NUMBER' '移动电话' ' '.
m_fieldcat 'COMPANY_CODE' '公司代码' ' '.
m_fieldcat 'EXT_CONN' '允许ROUTER' ' '.
ENDFORM. " SET_FIELDCAT
*&---------------------------------------------------------------------*
*& Form SET_LAYOUT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM set_layout .
**实际宽度自动匹配
* gs_layout-colwidth_optimize = 'X'.
**间隔条纹方式显示
* gs_layout-zebra = ''.
***选择模式,选择报表的某列为可选择列
** layout-box_fieldname = 'BOX'.
**通过LAYOUT来设置Grid是否显示列分割线
** layout-no_vline = 'X'.
**通过LAYOUT来设置Grid显示弹出明细显示窗口
* gs_layout-detail_popup = 'X'.
**退出ALV列表的确认对话框
* gs_layout-confirmation_prompt = ' '.
gs_layout-zebra = 'X'.
gs_layout-no_vline = ''.
gs_layout-colwidth_optimize = 'X'.
gs_layout-detail_popup = 'X'.
gs_layout-detail_initial_lines = 'X'.
gs_layout-detail_titlebar = sy-tcode.
gs_layout-confirmation_prompt = ''.
gs_layout-box_fieldname = 'BOX'.
ENDFORM. " SET_LAYOUT
*&---------------------------------------------------------------------*
*& Form DISPLAY_ALV
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM display_alv .
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_callback_program = sy-repid
i_callback_user_command = 'ALV_USER_COMMAND'
i_callback_pf_status_set = 'PF_STATUS_SET'
it_fieldcat = it_fieldcat[]
it_events = it_events[]
i_save = 'A'
is_layout = gs_layout
is_print = gs_print
* it_sort = lt_sort[]
TABLES
t_outtab = it_alv
EXCEPTIONS
program_error = 1
OTHERS = 2.
ENDFORM. " DISPLAY_ALV
*&---------------------------------------------------------------------*
*& Form pf_status_set
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->RT_EXTAB text
*----------------------------------------------------------------------*
FORM pf_status_set USING rt_extab TYPE slis_t_extab.
SET PF-STATUS 'STANDARD_FULLSCREEN'.
ENDFORM. "pf_status_set
*&---------------------------------------------------------------------*
*& Form alv_user_command
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->UCOMM text
* -->SELFIELD text
*----------------------------------------------------------------------*
FORM alv_user_command USING ucomm LIKE sy-ucomm
selfield TYPE slis_selfield.
CASE ucomm.
WHEN '&IC1'.
IF sy-uname = '1030'.
READ TABLE it_alv INDEX selfield-tabindex."读取当前行
SET PARAMETER ID: 'XUS' FIELD it_alv-sap_id.
CALL TRANSACTION 'SU01' AND SKIP FIRST SCREEN.
ENDIF.
ENDCASE.
ENDFORM. "FRM_USER_COMMAND1