2013 Sep 19 10:35 AM
Hi All.
I looking for a solution for below task.
JOB_OPEN
SUBMIT ... VIA JOB jobname NUMBER jobcount
AND RETURN.
JOB_CLOSE
I need a technology to call a subroutine in main (dialog) program from called in Job.
Could somebody provide an approach for the task ?
Regards,
Anuser.
2013 Sep 19 11:20 AM
If you need values from your main program why cant you export / import from memory?
Or, you could write your subroutine as a method in a class, implement the serializable interface and pass the instance as a argument to programmed called in the background job.
In the program in the background job, deseralise and access its methods. (you can actually do away with the whole seralisation if you want, you could simply pass the object by value instead).
Hope this helps.
2013 Sep 19 10:45 AM
Not sure what your exact requirement is, but PERFORM <Form Name> ( <Program Name > ) IF FOUND. might help you.
2013 Sep 19 10:59 AM
It seems to me, the approach isn't correct.
BJob must see ID the dialog instance and call subroutine in the calling program of the instance.
2013 Sep 19 11:02 AM
Why is that ?
Is it because you need values in variables in the main program ?
In that case it will not work and you need to redesign your program into one program
2013 Sep 19 11:30 AM
I cannot redesign the program because the customer decide to do it by this method.
Main program (Cover) submits chain BJobs and needs to know about finish each one.
Result of the BJobs is stored in cluster INDX like table.
Main program is cover only for long time required program (Slave program).
The Slave program interrupts to time out dump in dialog mode.
Slave cannot be resigned - it is the decision of the customer.
After finish all Bjobs Cover reads INDX and perform GRID.
So nevertheless theoretical question:
Does exist an approach then BJob called program calls a method or subroutine in calling (dialog) program?
2013 Sep 19 11:40 AM
I dont think you can go from a background job to a foreground job. If anyone knows how I would love to see an example.
My only approach would be as mentioned, to pass an instantiated class object to the background job. This would mean the background job has access to everything it needs from the passed class object and doesnt need to go back to the dialog process.
2013 Sep 19 11:55 AM
2013 Sep 19 12:12 PM
2013 Sep 19 11:20 AM
If you need values from your main program why cant you export / import from memory?
Or, you could write your subroutine as a method in a class, implement the serializable interface and pass the instance as a argument to programmed called in the background job.
In the program in the background job, deseralise and access its methods. (you can actually do away with the whole seralisation if you want, you could simply pass the object by value instead).
Hope this helps.
2013 Sep 19 11:41 AM
Did you try do it?
I did.
It is not possible between Dialog running program and background Job.
2013 Sep 19 11:49 AM
Yeah, I have many examples of this. When you pass the serialised & instantiated class object have you implemented the seralisable interface?
IF_SERIALIZABLE_OBJECT
This should be implemented in your custom class otherwise when passing the object around the values are lost.
I can provide you an example of what I have done and how I have something similar working. Your requirements might be slightly, but fundamentally different.
2013 Sep 19 12:03 PM
I will be pleased to see an example which reach my targets by IF_SERIALIZABLE_OBJECT or any method.
2013 Sep 19 1:33 PM
Hello,
I am not sure if i have understood your requirement clearly or not.
1. If you wish to re-use the logic of the subroutine , you can put the logic in FM and use it in both main pgm and backgroun job pgm.
2. If you wish to use the values that are there in the main progam, then you can use shared memory techniques or persistent objects.
I hope you are able to succeed in your development.
BR
Nilesh Puranik
2013 Sep 19 1:47 PM
Hi,
I have written two programs to show you how this works. Its just a demo program and so would need to be tailor specifically, but when I tested it here, it all worked fine.
Program Z_ADAM_TEST6 is the main dialog program.
Program Z_ADAM_TEST7 is the background program.
Z_ADAM_TEST6 calls Z_ADAM_TEST7 using submit.
The example makes use of persistent classes and for demonstration purposes I have created 2 z tables.
Z table 1 - ZADAM_TEST2
This table is soly used to proivde evidence that the background process actually ran. An entry is made to this table based on the values that are passed to it via the object. i.e. if the object failed to pass correctly, the entry in the table would not be correct.
Z Table 2 - ZPERSISTENT_TAB
This table is used to store the persistent object. The GUID and object are both saved to the database. The GUID is passed to the background program so that the object can later be recalled.
If you would like, once processing has finished, you could call the delete persistent method of the agent class. This would keep the DB clean.
I have provided what is easy here, however if you would like more information than what I have here, please let me know and I will gladly stick more up.
Program - Z_TEST_ADAM6
*&---------------------------------------------------------------------*
*& Report Z_ADAM_TEST6
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT z_adam_test6.
DATA: zcl_test_class TYPE REF TO zcl_attribute_class,
lv_string TYPE xstring,
lv_number TYPE tbtcjob-jobcount,
lv_name TYPE tbtcjob-jobname,
lv_print_param TYPE pri_params,
lcl_agent TYPE REF TO zca_persistent_class,
lcl_object TYPE REF TO zcl_persistent_class,
lv_guid TYPE guid_32.
lcl_agent = zca_persistent_class=>agent.
CALL FUNCTION 'GUID_CREATE'
IMPORTING
ev_guid_32 = lv_guid.
CALL METHOD lcl_agent->create_persistent
EXPORTING
i_guid = lv_guid
RECEIVING
result = lcl_object.
CREATE OBJECT zcl_test_class.
CALL METHOD zcl_test_class->set_attribute
EXPORTING
test_attribute = 'testing'.
CALL TRANSFORMATION id
SOURCE para = zcl_test_class
RESULT XML lv_string.
CALL METHOD lcl_object->set_object
EXPORTING
i_object = lv_string.
COMMIT WORK AND WAIT.
* Create job and submit as background task
lv_name = 'test_job'.
CALL FUNCTION 'JOB_OPEN'
EXPORTING
jobname = lv_name
IMPORTING
jobcount = lv_number
EXCEPTIONS
cant_create_job = 1
invalid_job_data = 2
jobname_missing = 3
OTHERS = 4.
* SUBMIT z_adam_test7 TO SAP-SPOOL
* SPOOL PARAMETERS lv_print_param
* WITHOUT SPOOL DYNPRO
* VIA JOB lv_name NUMBER lv_number
* WITH object = lv_string
* AND RETURN.
SUBMIT z_adam_test7 WITH guid = lv_guid
AND RETURN.
IF sy-subrc = 0.
CALL FUNCTION 'JOB_CLOSE'
EXPORTING
jobcount = lv_number
jobname = lv_name
strtimmed = 'X'
EXCEPTIONS
cant_start_immediate = 1
invalid_startdate = 2
jobname_missing = 3
job_close_failed = 4
job_nosteps = 5
job_notex = 6
lock_failed = 7
OTHERS = 8.
ENDIF.
Program - Z_ADAM_TEST7
*&---------------------------------------------------------------------*
*& Report Z_ADAM_TEST7
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT z_adam_test7.
PARAMETERS: guid TYPE guid_32.
DATA: zcl_test_class TYPE REF TO zcl_attribute_class,
ls_zadam_test TYPE zadam_test2,
lt_zadam_test TYPE STANDARD TABLE OF zadam_test2,
lcl_agent TYPE REF TO zca_persistent_class,
lcl_object TYPE REF TO zcl_persistent_class,
lv_string TYPE xstring.
lcl_agent = zca_persistent_class=>agent.
CALL METHOD lcl_agent->get_persistent
EXPORTING
i_guid = guid
receiving
result = lcl_object.
CALL METHOD lcl_object->get_object
RECEIVING
result = lv_string.
CREATE OBJECT zcl_test_class.
CALL TRANSFORMATION id
SOURCE XML lv_string
RESULT para = zcl_test_class.
CALL METHOD zcl_test_class->get_attribute
RECEIVING
test_attribute = ls_zadam_test-string.
APPEND ls_zadam_test TO lt_zadam_test.
INSERT zadam_test2 FROM TABLE lt_zadam_test.
2013 Sep 19 1:58 PM
I need get a message in dialog (Main) program from (Slave) one which runs in background Job and take a lot of time.
Slave program saves result in INDX table and after it the Main program can use the result.
Salve an Main my be run in different application servers. So I cannot use general Functional group.
2013 Sep 19 2:09 PM
Hi Adam
It seems to me I can check you idea I like 'GUID_CREATE' usage.
But I need some detail. What is contained in classes:
?
2013 Sep 19 2:31 PM
check
http://wiki.scn.sap.com/wiki/pages/viewpage.action?pageId=279937997
Or in general how to use persistence classes.
But I see you are now "gambling" on another solution (event raised)
see:
2013 Sep 20 9:23 AM
Hi, Sorry for the delay, had work events last night and now paying for it.
The persistent class is a very simple class. If you use SE80, provide a class name (zcl_persistent_class as an example), select persistent class when you are prompted to create the object.
Then from the class definition view, click "Persistence". From here, you map your database table to your persistent class. When you do this, you will notice that GET and SET methods are automatically generated.
So we can see here that I have mapped table ZPERSISTENT_TAB to my persistent class.
The other class I have used, ZCL_ATTRIBUTE class is an arbitrary class that I seralise and store in the database table ZPERSISTENT_TAB~OBJECT.
I then later deseralise the same object, but in the background process.
Hope this makes more sense. If not, let me know and I will try to overcome my sore head and write better english
Cheers,
2013 Sep 20 12:51 PM
2013 Oct 10 9:38 AM
Hi Adam.
I have done my task regarding your proposal.
It works right.
Thank you
2013 Oct 10 2:31 PM