07-27-2012 9:48 AM
Hi everybody,
Hope somebody can help me here: We have the requirement to identify the highest educatin in Infotype 0022.
We have created a custom field (a flag) to indicate this. To achieve consistency, each time the user ticks the box we need to remove the flag from the old record on the database. Dynamic Actions are not an option as they are not processed in batch input.
I am currently using HR_INFOTYPE_OPERATION to update the other records and I can see on the database that it is working fine, but if I try to edit the old record, the flag is still there, meaning the buffer is apparently not refreshed. I found a function module "HR_PSBUFFER_INITIALIZE", but when I call this in PBO I get a strange error message that the record could not be found. I thought about "manually" rereading the data from the database, but that seems to be also a little bit difficult as the HR_INFOTYPE_OPERATION also processes the dynpro logic. So if I read the data in PBO my update in PAI will no longer work...
Somebody got an idea?
Rgds
Bastian
07-27-2012 8:44 PM
There is a user-exit in which you can perform checks/tasks before the data is saved. Maybe have a look. PBAS0001. EXIT_SAPFP50M_002.
07-27-2012 11:40 AM
Hi Bastian,
Can you show some screen dumps related to this .to know what exactly you have coded???
Regards,
Srini
07-27-2012 2:32 PM
Hi Boosa,
Meanwhile I have found a solution that seems to work. In PBO, I reselect the data from the database into P0022. However, I don't think it's the best solution and I'm also not sure if it really works in all cases, so I am still open for suggestions.
The PBO Module of ZP002200 looks like this:
MODULE MODULE_PBO_0022 OUTPUT.
* First, we need to re-read the data from the database as it could have happened
* that the user changed the flag to another record and the PAI update has
* caused changes to this one. If we do not refresh the data here, the user
* would see something different from what is actually stored in the database
* sy-ucomm is INITIAL in case the infotype logic is called from HR_INFOTYPE_OPERATION
* and we don't want to overwrite the values provided by PAI in this case
IF sy-ucomm IS NOT INITIAL AND psyst-iinit EQ 1.
SELECT SINGLE ZZ_HR_ISHIGHEST FROM PA0022 INTO p0022-ZZ_HR_ISHIGHEST WHERE
BEGDA = p0022-begda AND
ENDDA = p0022-endda AND
SUBTY = p0022-subty AND
OBJPS = p0022-objps AND
SPRPS = p0022-sprps AND
SEQNR = p0022-seqnr.
ENDIF.
* Check if this record is the only one available (or even the first one
* to be created), if so default to "X"
* Check number of records on the database EXCLUDING the current one
SELECT * INTO CORRESPONDING FIELDS OF gs_p0022 FROM PA0022 WHERE
PERNR = p0022-pernr.
CHECK NOT
( gs_p0022-BEGDA = p0022-begda AND
gs_p0022-ENDDA = p0022-endda AND
gs_p0022-SEQNR = p0022-seqnr ).
gf_numrec = gf_numrec + 1.
ENDSELECT.
IF gf_numrec EQ 0.
* in create mode, default to "X"
IF psyst-ioper EQ 'INS'.
p0022-zz_hr_ishighest = 'X'.
ENDIF.
ENDIF.
* It is never allowed to remove the flag, but only to set it.
* If the flag is currently set, then convert field to read-only
IF p0022-zz_hr_ishighest = 'X'.
LOOP AT SCREEN.
IF screen-group2 EQ 'EDU'.
screen-input = 0.
MODIFY SCREEN.
ENDIF.
ENDLOOP.
ENDIF.
ENDMODULE. " MOD_PBO OUTPUT
PAI looks like this:
*&---------------------------------------------------------------------*
*& Module MOD_PAI INPUT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
MODULE MODULE_PAI_0022 INPUT.
* if this is the only record remaining, set highest education flag
IF gf_numrec EQ 0.
p0022-zz_hr_ishighest = 'X'.
ENDIF.
* If we are in save mode and user has set the flag, remove it for the
* other records on the database
IF fcode EQ 'UPD' AND p0022-zz_hr_ishighest = 'X' AND psave-zz_hr_ishighest IS INITIAL.
FREE MEMORY ID 'Z_P0022'.
EXPORT p0022 psave TO MEMORY ID 'Z_P0022'.
SUBMIT ZHR_IT0022_UPDATE AND RETURN.
ENDIF.
ENDMODULE. " MOD_PAI INPUT
And this the code of the report ZHR_IT0022_UPDATE:
*&---------------------------------------------------------------------*
*& Report ZHR_IT0022_UPDATE
*&
*&---------------------------------------------------------------------*
*& This is a technical report used to update other IT0022 records
*& of an employee to remove the "highest education" flag if the user
*& has set it for another record
*&
*& It should not be called directly, but only from the infotype logic!
*&---------------------------------------------------------------------*
REPORT ZHR_IT0022_UPDATE.
DATA:
gs_p0022 TYPE p0022,
gs_psave TYPE p0022,
gs_p0022_oth TYPE p0022,
gt_p0022_oth TYPE TABLE OF p0022.
DATA:
gs_return TYPE BAPIRETURN1,
gs_key TYPE BAPIPAKEY.
IMPORT p0022 = gs_p0022 psave = gs_psave FROM MEMORY ID 'Z_P0022'.
IF gs_p0022 IS INITIAL.
LEAVE PROGRAM.
ENDIF.
PERFORM remove_flag_from_other_record.
**********************************************************************
* Remove highest education flag from other infotype record
**********************************************************************
FORM REMOVE_FLAG_FROM_OTHER_RECORD.
DATA:
ls_p0022_oth TYPE p0022,
lt_p0022_oth TYPE TABLE OF p0022.
DATA:
ls_return TYPE BAPIRETURN1,
ls_key TYPE BAPIPAKEY.
* If the user has set the "highest education" flag, make sure there is no
* other record on the database having the flag set
SELECT * INTO CORRESPONDING FIELDS OF TABLE lt_p0022_oth FROM PA0022 WHERE PERNR = gs_p0022-pernr AND
ZZ_HR_ISHIGHEST EQ 'X'.
LOOP AT lt_p0022_oth INTO ls_p0022_oth.
CHECK NOT
( ls_p0022_oth-SUBTY = gs_psave-subty AND
ls_p0022_oth-BEGDA = gs_psave-begda AND
ls_p0022_oth-ENDDA = gs_psave-endda AND
ls_p0022_oth-SEQNR = gs_psave-seqnr AND
ls_p0022_oth-OBJPS = gs_psave-objps AND
ls_p0022_oth-SPRPS = gs_psave-sprps ).
* Remove flag
CLEAR ls_p0022_oth-zz_hr_ishighest.
ls_p0022_oth-infty = '0022'.
CALL FUNCTION 'HR_INFOTYPE_OPERATION'
EXPORTING
INFTY = '0022'
NUMBER = ls_p0022_oth-pernr
SUBTYPE = ls_p0022_oth-subty
* OBJECTID =
* LOCKINDICATOR =
VALIDITYEND = ls_p0022_oth-endda
VALIDITYBEGIN = ls_p0022_oth-begda
RECORDNUMBER = ls_p0022_oth-seqnr
RECORD = ls_p0022_oth
OPERATION = 'MOD'
TCLAS = 'A'
* DIALOG_MODE = '1'
NOCOMMIT = ' '
* VIEW_IDENTIFIER =
* SECONDARY_RECORD =
IMPORTING
RETURN = ls_return
KEY = ls_key.
ENDLOOP.
ENDFORM.
07-27-2012 8:44 PM
There is a user-exit in which you can perform checks/tasks before the data is saved. Maybe have a look. PBAS0001. EXIT_SAPFP50M_002.
07-30-2012 10:16 AM
Hi Kenneth,
Thanks, but unfortunately that doesn't really help as I only want to do the change when it has actually been saved. Besides that, we would still have the issue of the updated buffer.
For the benefit of everyone, I have found a much better solution now based on some SAP coding for Infotype 0021 Austria:
**********************************************************************
* Remove highest education flag from other infotype record
**********************************************************************
FORM REMOVE_FLAG_FROM_OTHER_RECORD.
DATA:
ls_p0022_oth TYPE p0022,
lt_p0022_oth TYPE TABLE OF p0022,
ls_prelp TYPE prelp.
* If the user has set the "highest education" flag, make sure there is no
* other record on the database having the flag set
PERFORM READ_INFOTYPE(SAPFP50P) USING pspar-pernr '0022' space space space LOW_DATE HIGH_DATE ALL NOP lt_p0022_oth.
* Loop through the global table returned by READ_INFOTYPE and update the corresponding records
LOOP AT SELTAB.
* Convert seltab entry via prelp structure to pnnnn
MOVE-CORRESPONDING seltab TO ls_prelp.
CALL METHOD CL_HR_PNNNN_TYPE_CAST=>PRELP_TO_PNNNN
EXPORTING
PRELP = ls_prelp
IMPORTING
PNNNN = ls_p0022_oth.
* check if this record needs an update
CHECK NOT
( ls_p0022_oth-SUBTY = psave-subty AND
ls_p0022_oth-BEGDA = psave-begda AND
ls_p0022_oth-ENDDA = psave-endda AND
ls_p0022_oth-SEQNR = psave-seqnr AND
ls_p0022_oth-OBJPS = psave-objps AND
ls_p0022_oth-SPRPS = psave-sprps ).
CHECK ls_p0022_oth-zz_hr_ishighest = 'X'.
* if we arrive here, we need to update the record
* Remove flag
CLEAR ls_p0022_oth-zz_hr_ishighest.
* Transfer back to prelp structure
CALL METHOD CL_HR_PNNNN_TYPE_CAST=>PNNNN_TO_PRELP
EXPORTING
PNNNN = ls_p0022_oth
IMPORTING
PRELP = ls_prelp.
* and back to seltab
MOVE-CORRESPONDING ls_prelp TO seltab.
PERFORM UPDATE_INFOTYP(SAPFP50P) USING SELTAB.
ENDLOOP.
ENDFORM.
Much easier then thought, and the SAP standard does all the rest...