WHILE n SECONDS – An alternative to WAIT UP TO n SECONDS
Well, I’ve try to find any article, blog or help to this and I wasn’t able to find anything so I decide to share it.
I was in this project where I had to load an Excel with about 20.000 rows and each row should create a Purchase Order, a Delivery, split this delivery, do the picking, create the Shipment and create the Nota Fiscal (a Brazilian document created after the invoice).
As usual, if you create or change a document even the BAPI returns ok with a document number it doesn’t mean that the document exists in the database. It took some time to fully end the whole process.
Since I need to create a lot of documents I need a solution that was more performance-friendly as the usual WAIT UP TO n SECONDS after the creation/change of each of those documents.
So, I after few researches I decide do create something like a WHILE command but using TIME as the logical condition.
The basic concept is very simple, something like this:
GET TIME. CONVERT DATE sy-datum TIME sy-uzeit INTO TIME STAMP DATA(l_time_ini) TIME ZONE sy-zonlo. GET TIME. DATA(l_time2) = sy-uzeit + 1. "1 second in the future CONVERT DATE sy-datum TIME l_time2 INTO TIME STAMP DATA(l_time_fim) TIME ZONE sy-zonlo. WHILE l_time_ini LE l_time_fim. GET TIME. CONVERT DATE sy-datum TIME sy-uzeit INTO TIME STAMP l_time_ini TIME ZONE sy-zonlo. *** Do your thing here WRITE / sy-index. *** End your thing here ENDWHILE.
In this very example the WHILE runs in my development environment something like 120.000 to 180.000 times depending on how loaded is the server.
Well, a very simple SELECT on EKKO (in my example) takes 38ms using a document number that doesn’t exists (yet) and 29ms when the number already exists in the database. So, why I need to wait 1 “endless” second to check if my record was created in the database?
By using this simple technique allows my loop to run only the time I needed until the creation of the record on database was completed, no more no less. This loop is more performance-friendly against the old the performance-killer WAIT UP TO n SECONDS.
The final code is this:
*********************************** GET TIME. CONVERT DATE sy-datum TIME sy-uzeit INTO TIME STAMP DATA(l_time_ini) TIME ZONE sy-zonlo. GET TIME. DATA(l_time2) = sy-uzeit + 10. "wait up to 10 seconds CONVERT DATE sy-datum TIME l_time2 INTO TIME STAMP DATA(l_time_fim) TIME ZONE sy-zonlo. WHILE l_time_ini LE l_time_fim. GET TIME. CONVERT DATE sy-datum TIME sy-uzeit INTO TIME STAMP l_time_ini TIME ZONE sy-zonlo. SELECT ebeln, ebelp, matnr INTO TABLE @DATA(tl_purchase) FROM ekpo WHERE ebeln EQ @ebeln_new. IF tl_purchase IS NOT INITIAL. EXIT. ENDIF. ENDWHILE. ***********************************
You can change the time you want to make the loop “waits” and the WHILE will stay in loop only the necessary time until the records get saved in the database, in my case EKPO.
Bigger the amount of data you need to process bigger will be the TIME you will save.
WHILE n SECONDS in practice
Well, after my project finish I could do some tests using the comments you shared in this post and there is the result.
To run this test I used a XLS file with 4758 line from this XLS the following happened:
- 687 Purchase Orders was created using BAPI_PO_CREATE1
- 656 Deliveries was created using BAPI_OUTB_DELIVERY_CREATE_STO
- All deliveries was modified (to update STORAGE LOCATION info) using BAPI_OUTB_DELIVERY_CHANGE
- All deliveries was modified again to split the items by CHARG field using BAPI_OUTB_DELIVERY_CHANGE a second time
- For every delivery a “Z” customer table was update
- And finally the PICKING was made for all of them using WS_DELIVERY_UPDATE function
I created a copy of my program changing my WHILE to a WAIT ‘0.1’ SECONDS in the same WHILE between every single step of this process but I still needed a LOOP to check if the record exists in the corresponding database tables.
UPDATE TO TASK didn’t work with those BAPIs and functions.
*I have to edit the image to fit in the article window width.
As you can see this “method” WHILE n SECONDS have his value and was faster almost an hour (48 minutes to be more precise).
You have to understand that I made this test in QA environment/server and problably this resutls are not too precise.
I hope you enjoy it !!
I know you problably have a better solution for this issue, so please share !!
If you find any problem with this code please correct me !