Why are some RFCs restricted by max. number of GUI sessions? - abap

Calling the function ME_INFORECORD_MAINTAIN_MULTI multiple times via RFC fails with the short dump "Maximum number of GUI sessions reached", but other functions don't seem to be subjected to the sessions limit when called in the same way.
The number of parallel calls to this function that I'm allowed to make depends on the number of GUI sessions (SAP GUI windows) that I have currently opened.
For example, the following code fails after 5 calls (I've added >>> at the beginning of the line where the dump occurs):
FORM CALL_BAPI_INFORECORD.
lv_taskname = |PIR-{ lv_sentjobs WIDTH = 3 ALIGN = RIGHT PAD = '0' }|.
DATA: lv_retry TYPE ABAP_BOOL.
lv_retry = ABAP_TRUE.
WHILE lv_retry = ABAP_TRUE.
lv_retry = ABAP_FALSE.
CALL FUNCTION 'ME_INFORECORD_MAINTAIN_MULTI'
STARTING NEW TASK lv_taskname
DESTINATION IN GROUP DEFAULT
PERFORMING RETURN_BAPI_INFORECORD ON END OF TASK
[...]
EXCEPTIONS
system_failure = 1 MESSAGE lv_exceptionmsg
communication_failure = 2 MESSAGE lv_exceptionmsg
resource_failure = 3
CASE sy-subrc.
WHEN 0.
lv_sentjobs = lv_sentjobs + 1.
WHEN 1 OR 2.
MESSAGE lv_exceptionmsg TYPE 'I'.
WRITE: / lv_taskname, ':', lv_exceptionmsg.
WHEN 3.
WAIT FOR ASYNCHRONOUS TASKS UNTIL lv_recvjobs = lv_sentjobs UP TO 300 SECONDS.
lv_retry = ABAP_TRUE.
WHEN OTHERS.
MESSAGE 'Unkown error.' TYPE 'I'.
ENDCASE.
ENDWHILE.
ENDFORM.
FORM RETURN_BAPI_INFORECORD USING TASKNAME.
DATA INFO LIKE RFCSI.
>>> RECEIVE RESULTS FROM FUNCTION 'ME_INFORECORD_MAINTAIN_MULTI'
IMPORTING
RFCSI_EXPORT = INFO
RETURN = GT_ME_INFORECORD_RETURN.
ENDFORM.
... but the following code runs fine with 10 parallel calls:
FORM CALL_BAPI_MATERIAL.
lv_taskname = |MAT-{ lv_sentjobs WIDTH = 3 ALIGN = RIGHT PAD = '0' }|.
DATA: lv_retry TYPE ABAP_BOOL.
lv_retry = ABAP_TRUE.
WHILE lv_retry = ABAP_TRUE.
lv_retry = ABAP_FALSE.
CALL FUNCTION 'BAPI_MATERIAL_SAVEREPLICA'
STARTING NEW TASK lv_taskname
DESTINATION IN GROUP DEFAULT
PERFORMING RETURN_BAPI_MATERIAL ON END OF TASK
[...]
EXCEPTIONS
system_failure = 1 MESSAGE lv_exceptionmsg
communication_failure = 2 MESSAGE lv_exceptionmsg
resource_failure = 3.
CASE sy-subrc.
WHEN 0.
lv_sentjobs = lv_sentjobs + 1.
WHEN 1 OR 2.
MESSAGE lv_exceptionmsg TYPE 'I'.
WRITE: / lv_taskname, ':', lv_exceptionmsg.
WHEN 3.
WAIT FOR ASYNCHRONOUS TASKS UNTIL lv_recvjobs = lv_sentjobs UP TO 300 SECONDS.
lv_retry = ABAP_TRUE.
WHEN OTHERS.
MESSAGE 'Unknown error.' TYPE 'I'.
ENDCASE.
ENDWHILE.
ENDFORM.
FORM RETURN_BAPI_MATERIAL USING TASKNAME.
DATA INFO LIKE RFCSI.
RECEIVE RESULTS FROM FUNCTION 'BAPI_MATERIAL_SAVEREPLICA'
IMPORTING
RFCSI_EXPORT = INFO
RETURNMESSAGES = GT_BAPI_SAVEREPLICA_RETURN.
ENDFORM.
This is the stack when the dump occurs.
Why is function ME_INFORECORD_MAINTAIN_MULTI subject to a limit of GUI sessions and how to bypass it ?

Are you sure you got error
"Maximum number of GUI sessions reached"
due to the function call?
CALL FUNCTION 'BAPI_MATERIAL_SAVEREPLICA'
STARTING NEW TASK lv_taskname
DESTINATION IN GROUP DEFAULT
PERFORMING RETURN_BAPI_MATERIAL ON END OF TASK
Did you include the exceptions on the call function statement?
exceptions resource_failure = 1
others = 2.
When there are no more free resources on the Group you will get a 'resource_failure' exception. I would expect a resource failure error based on your description.
Check the settings in Rz12 of for the server group you are using.
The ability to "start new task" (via rfc) checks these parameter settings.
So if the server was "busy" then the call fails.
Here is a basic shell program you can use to test parallel code behavior.
REPORT ZPARA.
data t type i.
parameters:
cnt type i default 10000000,
packets type i default 10,
para as checkbox default 'X',
waittime type i default 1,
rfcgroup like rzllitab-classname .
data total type f.
data splits type i.
data mod type i.
data packetsize type i.
data: first type i.
data: last type i.
data: this_last type i.
data: this_split type i.
data: ret_splits type i.
data: act_splits type i.
data: taskname type num8 value 0.
data: begin of task occurs 0,
taskname type num8,
uzeit like sy-uzeit,
wpinfo TYPE WPINFO,
end of task.
data max_pbt_wps type i.
data free_pbt_wps type i.
start-of-selection.
PERFORM classic_version.
form classic_version.
**** TO USE THIS CODE,
* create a parallel(rfc) server group in RZ12.
* create the function decribed below
**************************************************
* set run time res low, so measurement in milli not microsecs.
* we are measure BIG runs
refresh task.
set run time clock resolution low.
get run time field t.
total = 0.
check cnt > 0.
if packets = 0.
packets = 5.
endif.
* splits calculated based on packet size
splits = packets.
PACKETSIZE = cnt div PACKETS.
* is parallel mode selected
if para = 'X'.
* parallel processing MUST be initialized first.
call function 'SPBT_INITIALIZE'
exporting
group_name = rfcgroup
importing
max_pbt_wps = max_pbt_wps
free_pbt_wps = free_pbt_wps
exceptions
invalid_group_name = 1
internal_error = 2
pbt_env_already_initialized = 3
currently_no_resources_avail = 4
no_pbt_resources_found = 5
cant_init_different_pbt_groups = 6
others = 7
.
if sy-subrc <> 0.
* if our group failed or the available processes was 0,
* we would exit cleanly here.
* for the demo, just bomb out.
endif.
last = 0.
ret_splits = 0.
act_splits = 0.
* so for each split
do splits times.
* make a jobname
taskname = taskname + 1.
* work out which chunk we are processing
* ie were are we up to ??
first = last + 1.
this_last = first + packetsize - 1.
* for info purposes record which split
this_split = sy-index.
* just in case we have the last split,
* calculated adjust target end,
if this_last > cnt.
this_last = cnt.
endif.
* try a dispatch this split.
* this is where more logic is needed.
* here we set a max of a hundred tries to dispatch
* something. IN VERY LARGE jobs,
* a commit work and a more intelligent wait
* might be appropriate.
* we at least wait, 1 then 2 then 3... secs etc
* until we get a look in.
do 100 times.
* inside a parallel ( new ) task
* do a chunk of work.
* NO importing parameters here. The result is returned
* in the receiving function.
* SPECIAL, extra, exceptions are available to control
* success or otherwise of the dispatch.
write: / 'Split ', this_split, 'dispatch at', sy-uzeit.
call function 'Z_CHUNK' starting new task taskname
destination in group rfcgroup
performing finished on end of task
exporting
from_int = first
to_int = this_last
exceptions
resource_failure = 1
others = 2.
if sy-subrc = 0.
* dispatch ok, record the fact and march on...
act_splits = act_splits + 1.
last = first + PACKETSIZE - 1.
exit. " the retry until dispatched loop.
else.
write: 'No resource free'.
write: / 'Split ', this_split, 'Waits ', waittime, 'secs at',
sy-uzeit.
* wait x seconds, each attempt waits successlively longer
wait up to waittime seconds.
endif.
enddo.
* Actual failure to dispatch is not captured in this version
* your code should consider this issue.
enddo.
*** THE BIG ROUNDUP
* we wait here until ALL splits are returned.
* we do that by waiting until a return counter
* equals the numbers of dispatches.
* this wait does not wait indefinitely if a dispatch above
* fails, since another continue point is NO oustanding
* async tasks.
***
wait until ret_splits >= act_splits.
else.
call function 'Z_CHUNK'
exporting
from_int = 1
to_int = cnt
importing
tot = total.
endif.
get run time field t.
t = t / 1000.
loop at task.
write: / 'Received task', task-taskname, ' at ', task-uzeit, ' in WP:', task-WPINFO-WP_INDEX.
endloop.
write: / 'Parallel', para.
write: / 'Time ms ', t left-justified.
write: / 'Splits ', splits left-justified.
write: / 'Total ', total left-justified.
endform.
*---------------------------------------------------------------------*
* FORM finished *
*---------------------------------------------------------------------*
* ........ *
*---------------------------------------------------------------------*
* --> TASKNAME *
*---------------------------------------------------------------------*
form finished using taskname.
data: ls_wpinfo type WPINFO.
data l_tot type f.
receive results from function 'Z_CHUNK'
importing
tot = l_tot
wp_index = LS_WPINFO-WP_INDEX.
* when receiving a task back, we get out result
* and record that the task returned, by uping a counter.
task-taskname = taskname.
task-uzeit = sy-uzeit.
task-WPINFO = LS_WPINFO.
append task.
total = total + l_tot.
ret_splits = ret_splits + 1.
endform.
*****
* Create this function to test.
FUNCTION Z_CHUNK
IMPORTING
VALUE(FROM_INT) TYPE I
VALUE(TO_INT) TYPE I
EXPORTING
VALUE(TOT) TYPE F
VALUE(WP_INDEX) TYPE WPINFO-WP_INDEX.
data l_i type i.
tot = 0.
check to_int > from_int.
l_i = from_int.
while l_i <= to_int.
tot = tot + l_i.
l_i = l_i + 1.
endwhile.
CALL FUNCTION 'TH_GET_OWN_WP_NO'
IMPORTING
WP_INDEX = WP_INDEX
.
ENDFUNCTION.

Related

BAPI_GOODSMVT_CREATE in parallel mode causes "plant data of the material XXX is locked" error

Currently, We're developing mass GI posting by parallelism, to reduce work time dramatically, because we have to post GI item about 300k+ at one day.
Problem
I know there is a restraint about BAPI_GOODSMVT_CREATE - You can't post same material simutaneously because of table lock, so I grouped materials like this :
It seems reasonable, so I make parallel job for each material number, which total 7 in example.
When I try process this process, SAP refused to process with error :
M3 897 : The plant data of the material XXX is locked by the user XXX
Question
The error is about plant data, not stock data - so it's really confusing about why this error happening.
Is there a more restraint about BAPI_GOODSMVT_CREATE?
Note 369518 won't help about this situation.
Any help would be appreciated!
Program Code
LOOP AT gt_matnr_collect INTO wa_matnr_collect.
WAIT UNTIL g_progs <= pa_wpnum.
g_progs = g_progs + 1.
CALL FUNCTION 'Z_PP_STAMP_PARA_DISTRIBUTE'
STARTING NEW TASK g_task DESTINATION IN GROUP DEFAULT
PERFORMING return_stamp_para ON END OF TASK
EXPORTING
p_matnr = wa_matnr_collect-gi_code
p_spmon = p_spmon
TABLES
p_list = gt_main_para_list
p_item = gt_main.
g_task = g_task + 1.
g_sprog = g_sprog + 1.
ENDLOOP.
gt_matnr_collect looks like this :
gt_main_para_list looks like this :
gt_main looks like this :
FM 'Z_PP_STAMP_PARA_DISTRIBUTE'
FUNCTION z_pp_stamp_para_distribute.
*"----------------------------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" VALUE(P_MATNR) TYPE MATNR_D
*" VALUE(P_SPMON) TYPE SPMON
*" EXPORTING
*" VALUE(E_MATNR) TYPE MATNR_D
*" TABLES
*" P_LIST STRUCTURE ZSPP6030_PA_LIST
*" P_ITEM STRUCTURE ZSPP6030_PA_ITEM
*" R_RESULT STRUCTURE BAPIRET2 OPTIONAL
*"----------------------------------------------------------------------
DATA : gs_head LIKE bapi2017_gm_head_01,
gs_gmcd LIKE bapi2017_gm_code,
gs_doc LIKE bapi2017_gm_head_ret,
gt_item LIKE TABLE OF bapi2017_gm_item_create
WITH HEADER LINE,
gt_return LIKE TABLE OF bapiret2 WITH HEADER LINE,
gs_return LIKE bapiret2,
group_id(22) TYPE c,
l_begda LIKE p0001-begda,
g_last_date TYPE d,
lv_matnr TYPE ztpp5360-gi_code,
lv_batch TYPE ztpp5360-gi_batch,
lv_aufnr TYPE ztpp5360-arbpl,
lv_cnt(3) TYPE c.
CONCATENATE p_spmon '01' INTO l_begda.
e_matnr = p_matnr.
CALL FUNCTION 'RP_LAST_DAY_OF_MONTHS'
EXPORTING
day_in = l_begda
IMPORTING
last_day_of_month = g_last_date
EXCEPTIONS
day_in_no_date = 1
OTHERS = 2.
CONCATENATE p_matnr '*' INTO group_id.
LOOP AT p_list WHERE group_id CP group_id.
CLEAR : lv_matnr, lv_batch, lv_aufnr, lv_cnt.
SPLIT p_list-group_id AT '-' INTO lv_matnr lv_batch lv_aufnr lv_cnt.
CASE lv_batch.
WHEN 'EMPTY'.
lv_batch = ''.
ENDCASE.
p_list-status = 'WIP'.
MODIFY p_list.
LOOP AT p_item WHERE group_id = p_list-group_id.
MOVE : p_item-gi_m_q TO gt_item-entry_qnt,
* 'KG' TO gt_item-entry_uom,
'X' TO gt_item-withdrawn,
'3100' TO gt_item-stge_loc.
MOVE : '261' TO gt_item-move_type,
p_item-gi_code TO gt_item-material,
p_item-werks TO gt_item-plant,
p_item-aufnr TO gt_item-orderid,
lv_batch TO gt_item-batch.
APPEND : gt_item. CLEAR : gt_item.
ENDLOOP.
MOVE : g_last_date TO gs_head-doc_date,
g_last_date TO gs_head-pstng_date,
'03' TO gs_gmcd-gm_code.
REFRESH : gt_return.
CLEAR : gt_return, gs_doc.
CALL FUNCTION 'BAPI_GOODSMVT_CREATE'
EXPORTING
goodsmvt_header = gs_head
goodsmvt_code = gs_gmcd
IMPORTING
goodsmvt_headret = gs_doc
TABLES
goodsmvt_item = gt_item
return = gt_return.
READ TABLE gt_return WITH KEY type = 'E'.
IF sy-subrc = 0 OR gs_doc IS INITIAL.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
LOOP AT p_item WHERE group_id = p_list-group_id.
p_item-ecode = 'E'.
p_item-msgtx = gt_return-message.
p_item-aedat = sy-datum.
p_item-aezet = sy-uzeit.
p_item-aenam = sy-uname.
MODIFY p_item.
ENDLOOP.
p_list-status = 'ERR'.
p_list-msgty = 'E'.
CONCATENATE gt_return-message '/' gt_return-id '/' gt_return-number INTO p_list-msgtx.
MODIFY p_list.
ELSE.
CLEAR : gs_return.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'
IMPORTING
return = gs_return.
IF gs_return-type = 'E'.
p_list-status = 'ERR'.
p_list-msgty = 'E'.
p_list-msgtx = gs_return-message.
ELSE.
LOOP AT p_item WHERE group_id = p_list-group_id.
p_item-gi_m_mblnr = gs_doc-mat_doc.
p_item-gi_m_mjahr = gs_doc-doc_year.
p_item-ecode = 'S'.
p_item-msgtx = ''.
p_item-aedat = sy-datum.
p_item-aezet = sy-uzeit.
p_item-aenam = sy-uname.
MODIFY p_item.
ENDLOOP.
p_list-status = 'FIN'.
p_list-msgty = 'S'.
p_list-msgtx = ''.
MODIFY p_list.
ENDIF.
ENDIF.
REFRESH : gt_item.
CLEAR : gs_head, gs_gmcd.
WAIT UP TO 2 SECONDS.
ENDLOOP.
ENDFUNCTION.

How to update custom fields in PLM project definition?

I am required to create a custom report that bulk uploads the PROJ table, that has around 8 custom fields that have been created by a Fiori app, the data to be updated would be provided as a CSV file and would have the project id for which the data has to be created.
The fields as created are visible in transaction codes CJ20N and CJ02.
The issue is that despite having the data added, the BAPI is not giving any error and no data is getting updated.
Please help me resolve this issue or suggest an alternative solution to achieve the required.
Following is my code so far, based on BAPI_PS_INITIALIZATION, BAPI_BUS2001_CHANGE, BAPI_PS_PRECOMMIT and BAPI_TRANSACTION_COMMIT:
REPORT z_bulk_proj_upload.
TYPES: BEGIN OF ty_data,
project TYPE ps_pspnr,
vip_id(18) TYPE c, "VIP ID
category(30) TYPE c, "LA Category
worktype(30) TYPE c, "LA WorkType
projtype(30) TYPE c, "LA ProjectType
region(30) TYPE c, "Region
alpharisk(20) TYPE c, "AlphaRiskControl
vipcontrol(3) TYPE c, "VIP Control
viprevised(3) TYPE c, "VIP Revised Control
majorproject(1) TYPE c, "Major Project Threshold
dateofinteg(10) TYPE c, "Date of integration
filenumber(16) TYPE c, "File Number Regie
decisiondate(10) TYPE c, "Decision Date Regie
approval(10) TYPE c, "Approval
END OF ty_data,
BEGIN OF lty_rawdata,
rawdata(40000) TYPE c,
END OF lty_rawdata.
DATA: it_data TYPE STANDARD TABLE OF ty_data,
lwa_data TYPE ty_data,
lv_file TYPE string,
it_rawdata TYPE STANDARD TABLE OF lty_rawdata,
lwa_rawdata TYPE lty_rawdata,
lr_csv TYPE REF TO cl_rsda_csv_converter,
lt_fichier TYPE filetable,
l_rc TYPE i,
lv_length TYPE i,
lv_size TYPE i,
ls_proj TYPE proj,
wa_custstr TYPE bapi_te_project_definition,
ls_project_definition TYPE bapi_bus2001_chg,
ls_project_definition_upd TYPE bapi_bus2001_upd,
lt_return TYPE STANDARD TABLE OF bapiret2,
lt_return1 TYPE bapiret2,
lt_extensionin TYPE STANDARD TABLE OF bapiparex INITIAL SIZE 0 WITH HEADER LINE.
INITIALIZATION.
CLEAR: lv_size, it_data.
SELECTION-SCREEN BEGIN OF BLOCK b4 WITH FRAME TITLE TEXT-b05.
PARAMETERS: p_file TYPE rlgrap-filename LOWER CASE,
p_upld RADIOBUTTON GROUP grz DEFAULT 'X',
p_dwnld RADIOBUTTON GROUP grz.
SELECTION-SCREEN END OF BLOCK b4.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.
SELECTION-SCREEN BEGIN OF BLOCK b4 WITH FRAME TITLE TEXT-b05.
PARAMETERS: p_file TYPE rlgrap-filename LOWER CASE,
p_upld RADIOBUTTON GROUP grz DEFAULT 'X',
p_dwnld RADIOBUTTON GROUP grz.
SELECTION-SCREEN END OF BLOCK b4.
START-OF-SELECTION.
IF p_upld IS NOT INITIAL.
lv_file = p_file.
CALL METHOD cl_gui_frontend_services=>gui_upload
EXPORTING
filename = lv_file
CHANGING
data_tab = it_rawdata[]
EXCEPTIONS
file_open_error = 1
file_read_error = 2
no_batch = 3
gui_refuse_filetransfer = 4
invalid_type = 5
no_authority = 6
unknown_error = 7
bad_data_format = 8
header_not_allowed = 9
separator_not_allowed = 10
header_too_long = 11
unknown_dp_error = 12
access_denied = 13
dp_out_of_memory = 14
disk_full = 15
dp_timeout = 16
not_supported_by_gui = 17
error_no_gui = 18
OTHERS = 19.
IF sy-subrc <> 0.
MESSAGE 'Error in Upload' TYPE 'E'.
ELSE.
DESCRIBE TABLE it_data LINES DATA(lv_line).
ENDIF.
CALL METHOD cl_rsda_csv_converter=>create
RECEIVING
r_r_conv = lr_csv.
LOOP AT it_rawdata INTO lwa_rawdata.
TRY.
"Populate raw data into separate fields in structure
CALL METHOD lr_csv->csv_to_structure
EXPORTING
i_data = lwa_rawdata
IMPORTING
e_s_data = lwa_data.
CATCH cx_root ##CATCH_ALL.
"Error during data conversion
MESSAGE TEXT-005 TYPE 'S' DISPLAY LIKE 'E'.
LEAVE LIST-PROCESSING.
ENDTRY.
APPEND lwa_data TO it_data.
ENDLOOP.
ENDIF.
IF it_data IS NOT INITIAL.
LOOP AT it_data INTO lwa_data.
SELECT SINGLE * INTO ls_proj FROM proj WHERE pspid = lwa_data-project.
lt_extensionin-structure = 'BAPI_TE_PROJECT_DEFINITION'.
lt_extensionin-valuepart1+0(24) = ls_proj-pspid.
APPEND lt_extensionin.
CALL FUNCTION 'BAPI_PS_INITIALIZATION'.
ls_project_definition-project_definition = ls_proj-pspid.
ls_project_definition_upd-zz1_vipid_psd = lwa_data-vip_id.
ls_project_definition_upd-zz1_lacategory_psd = lwa_data-category.
ls_project_definition_upd-zz1_laworktype_psd = lwa_data-worktype.
ls_project_definition_upd-zz1_laprojecttype_psd = lwa_data-projtype.
ls_project_definition_upd-zz1_region_psd = lwa_data-region.
ls_project_definition_upd-zz1_alphariskgrade1_psd = lwa_data-alpharisk.
ls_project_definition_upd-zz1_vipcontrolnonc_psd = lwa_data-vipcontrol.
ls_project_definition_upd-zz1_viprevisedcontroln_psd = lwa_data-viprevised.
ls_project_definition_upd-zz1_majorprojectsthres_psd = lwa_data-project.
ls_project_definition_upd-zz1_dateofintegrationi_psd = lwa_data-dateofinteg.
ls_project_definition_upd-zz1_filenumberrgie_psd = lwa_data-filenumber.
ls_project_definition_upd-zz1_decisiondatergie_psd = lwa_data-decisiondate.
ls_project_definition_upd-zz1_approval_psd = lwa_data-approval.
CALL FUNCTION 'BAPI_BUS2001_CHANGE'
EXPORTING
i_project_definition = ls_project_definition
i_project_definition_upd = ls_project_definition_upd
TABLES
et_return = lt_return.
* extensionin = lt_extensionin.
CALL FUNCTION 'BAPI_PS_PRECOMMIT'
TABLES
et_return = lt_return.
REFRESH lt_return.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'
IMPORTING
return = lt_return1.
ENDLOOP.
ENDIF.
i_project_definition is for the update flag not the actual value.
ls_project_definition-fieldxyz = 'SOME VALUE'.
ls_project_definition_upd-fieldxyz = 'X'. " should have the value 'X' !!!
the code you supplied suggests the interface was not called properly.
Furthermore for Z fields normally they are passed in via EXTENSIONIN not via
BAPI_BUS2001_CHG and BAPI_BUS2001_UPD.
FUNCTION BAPI_BUS2001_CHANGE
IMPORTING
VALUE(I_PROJECT_DEFINITION) LIKE BAPI_BUS2001_CHG
VALUE(I_PROJECT_DEFINITION_UPD) LIKE BAPI_BUS2001_UPD
TABLES
ET_RETURN LIKE BAPIRET2 OPTIONAL
EXTENSIONIN LIKE BAPIPAREX OPTIONAL "<<<<<<<<<<<<< HERE
EXTENSIONOUT LIKE BAPIPAREX OPTIONAL.

How to use CRM_STATUS_READ to get product status?

I want to know that How to use the Function Module CRM_STATUS_READ.
In table crmd_orderadm_h have a field GUID and I want to show status by passing the GUID to the FM CRM_STATUS_READ.
I don't know how to fill parameters in this FM.
FORM create_output USING i_t_crmd_orderadm_h TYPE g_tt_orderadm_h
CHANGING e_t_out TYPE g_tt_out.
DATA: l_r_crmd_orderadm_h TYPE g_ty_orderadm_h,
l_r_out TYPE g_ty_out.
.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
LOOP AT i_t_crmd_orderadm_h INTO l_r_crmd_orderadm_h.
CALL FUNCTION 'CRM_STATUS_READ'
EXPORTING
* CLIENT = SY-MANDT
objnr =
* ONLY_ACTIVE = ' '
* IMPORTING
* OBTYP =
* STSMA =
* STONR =
* ET_JEST_BUF =
* TABLES
* STATUS =
ENDFORM.
Best Regards,
Huy Vu
To call this module you gotta know two things: GUID and fragment GUID. The latter can be taken from product attributes (table COMM_PCAT_REL).
Here is the sample:
DATA(lv_guid) = get_guid_by_id( '11111111111' ).
DATA: lv_frg_guid TYPE comm_pr_frg_rod-fragment_type VALUE '37D58F1B772D53A4E10000009B38FA0B',
rt_stat TYPE ttjstat.
DATA: lv_objnr TYPE comm_pr_frg_rod-status_object,
lt_status TYPE STANDARD TABLE OF jstat.
SELECT SINGLE status_object FROM comm_pr_frg_rod
INTO lv_objnr WHERE product_guid = lv_guid AND fragment_type = lv_frg_guid.
CHECK sy-subrc = 0.
CALL FUNCTION 'CRM_STATUS_READ'
EXPORTING
objnr = lv_objnr
TABLES
status = rt_status
EXCEPTIONS
object_not_found = 1.

E:The key specification is incomplete. Generic specification is only completed

When clicking on Check (CTRL + F2) I get the error:
E:The key specification is incomplete. Generic specification is only completed
Unfortunately there I do not see an indicator which line is wrong. Thx SAP :/
Therefore here the relevant code:
SELECT /bic/customer FROM /bic/pcustomer INTO TABLE i_pcustomer
WHERE objvers = c_a.
SELECT /bic/material /bic/sdcsnum FROM /bic/pmaterial INTO TABLE i_pmaterial_s
WHERE objvers = c_a.
SORT i_pmaterial_s BY /bic/material.
i_pmaterial = i_pmaterial_s.
DELETE i_pmaterial_s WHERE /bic/sdcsnum IS INITIAL.
*write to log in infopackage - check double entries material
SORT i_pmaterial_s BY /bic/sdcsnum.
LOOP AT i_pmaterial_s INTO i_pmaterial_s_line.
IF sy-tabix = 1.
CLEAR flg_dup.
ELSE.
IF i_pmaterial_dcs_line-/bic/sdcsnum = i_pmaterial_s_line-/bic/sdcsnum.
"CLEAR p_t_errorlog.
l_cnt = l_cnt + 1.
p_t_errorlog_line-msgid = 'VRS'.
p_t_errorlog_line-msgty = 'I'.
p_t_errorlog_line-msgno = 0.
p_t_errorlog_line-msgv1 = 'Duplic. rec:'.
p_t_errorlog_line-msgv2 = '/BIC/PMATERIAL DCS'.
p_t_errorlog_line-msgv3 = i_pmaterial_dcs_line-/bic/sdcsnum.
p_t_errorlog_line-msgv4 = i_pmaterial_dcs_line-/bic/material.
insert p_t_errorlog_line into table p_t_errorlog.
flg_dup = 'X'.
ELSE.
IF flg_dup IS INITIAL.
INSERT i_pmaterial_dcs_line into i_pmaterial_dcs.
ELSE.
"CLEAR p_t_errorlog.
l_cnt = l_cnt + 1.
p_t_errorlog_line-msgid = 'VRS'.
p_t_errorlog_line-msgty = 'I'.
p_t_errorlog_line-msgno = 0.
p_t_errorlog_line-msgv1 = 'Duplic. rec:'.
p_t_errorlog_line-msgv2 = '/BIC/PMATERIAL DCS'.
p_t_errorlog_line-msgv3 = i_pmaterial_dcs_line-/bic/sdcsnum.
p_t_errorlog_line-msgv4 = i_pmaterial_dcs_line-/bic/material.
insert p_t_errorlog_line into table p_t_errorlog.
CLEAR flg_dup.
ENDIF.
ENDIF.
ENDIF.
i_pmaterial_dcs_line = i_pmaterial_s_line.
ENDLOOP.
The code which triggered the error message was:
data: p_t_errorlog TYPE SORTED TABLE OF rsmonitor
changing the code to
data: p_t_errorlog TYPE STANDARD TABLE OF rsmonitor
fixed the issue.

How to display list of attachments from Generic Object Services

I have a report that should display an attachment list from an object.
For instance, in transaction FI02 (maintenance of banks), the GOS toolbar has the menu Attachment List:
I want to display this list. What is the best way to display it?
REPORT zay_gos_demo.
DATA ls_appl_object TYPE gos_s_obj.
DATA lo_gos_api TYPE REF TO cl_gos_api.
DATA lt_attachment_list TYPE gos_t_atta.
DATA lt_role_filter TYPE gos_t_rol.
DATA ls_attachment TYPE gos_s_atta.
DATA ls_attachm_cont TYPE gos_s_attcont.
DATA ls_atta_key TYPE gos_s_attkey.
ls_appl_object-typeid = 'KNA1'.
ls_appl_object-instid = '0000000001'.
ls_appl_object-catid = 'BO'. "BO - BOR Object
"CL - Persistent Class
START-OF-SELECTION.
* create instance of GOS API providing unique application object
TRY.
lo_gos_api = cl_gos_api=>create_instance( ls_appl_object ).
* get attachment list for this object (if needed restrict selection
* by adding certain roles to filter table; initial table means: get
* attachments in all roles)
APPEND cl_gos_api=>c_attachment TO lt_role_filter.
APPEND cl_gos_api=>c_annotation TO lt_role_filter.
APPEND cl_gos_api=>c_website TO lt_role_filter.
lt_attachment_list = lo_gos_api->get_atta_list( lt_role_filter ).
CATCH cx_gos_api.
* error handling
ENDTRY.
I found other example and I want to test it:
REPORT zay_attachment_list_display.
DATA: go_attachments TYPE REF TO cl_gos_attachments,
g_att_container TYPE REF TO cl_gui_custom_container,
ls_object TYPE borident,
lo_bitem TYPE REF TO cl_sobl_bor_item.
ls_object-objtype = 'KNA1'.
ls_object-objkey = '0000000001'.
IF NOT go_attachments IS INITIAL.
CLEAR go_attachments.
ENDIF.
CREATE OBJECT g_att_container
EXPORTING
container_name = 'ATTS'
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
lifetime_dynpro_dynpro_link = 5.
IF sy-subrc NE 0.
* ADD your handling
ENDIF.
CREATE OBJECT lo_bitem
EXPORTING
is_bor = ls_object.
IF go_attachments IS INITIAL.
CREATE OBJECT go_attachments
EXPORTING
io_object = lo_bitem
ip_check_arl = 'X'
ip_check_bds = 'X'
io_container = g_att_container
* is_layout = ls_layout
* ip_mode = wf_mode
ip_notes = 'X'
ip_attachments = 'X'
ip_urls = 'X'.
ELSE.
go_attachments->set_container( g_att_container ).
ENDIF.
go_attachments->display( ).
I created a custom control in dynpro 0100 and I named it ATTS. I still can't get the attachment list of GOS. Did I miss something?
After weeks of searching and asking. it was really simple. just call the function GOS_ATTACHMENT_LIST_POPUP.
Example:
DATA: ls_object TYPE sibflporb,
save_request TYPE sgs_flag.
ls_object-instid = 'FR 1234567890'.
ls_object-typeid = 'BUS1011'.
ls_object-catid = 'BO'.
CALL FUNCTION 'GOS_ATTACHMENT_LIST_POPUP'
EXPORTING
is_object = ls_object
ip_mode = 'E' " Edit mode
IMPORTING
ep_save_request = save_request.
IF save_request = 'X'.
COMMIT WORK.
ENDIF.