Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

BAPI Help

Former Member
0 Likes
3,157

Hi All,

I have this BAPI which is getting data from tstc and tstct tables. The data has 200k+ records, I need to display 50K at a time. Can someone please help me with this.

Thanks,

SNReddy


FUNCTION bptcoddata_extract.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     VALUE(FILEPATH) TYPE  RLGRAP-FILENAME OPTIONAL
*"     VALUE(STANDARD_TABLES) TYPE  FLAG DEFAULT 'X'
*"     VALUE(CONNECTOR) TYPE  CHAR5 OPTIONAL
*"     VALUE(TCODE_DATA) TYPE  FLAG DEFAULT 'X'
*"     VALUE(TCODE_SELECT) TYPE  STRING OPTIONAL
*"  TABLES
*"      TBL_BAPIRET STRUCTURE  BAPIRET2 OPTIONAL
*"      TCODES STRUCTURE  TWBTCODE OPTIONAL
*"      TCODES_DESC STRUCTURE  TSTCT OPTIONAL
*"----------------------------------------------------------------------

  DATA : t_tcodes_tstc TYPE STANDARD TABLE OF twbtcode,
         wa_bapiret TYPE bapiret2,
         t_tcodes TYPE STANDARD TABLE OF ty_tcodes,
         wa_tcodes TYPE ty_tcodes,
         lv_filename TYPE string,
         t_tcodes_script TYPE tt_tcodes_script,
         wa_tcodes_script TYPE stcodes_script,
         t_bapiret TYPE STANDARD TABLE OF bapiret2,
         wa_tstct TYPE tstct,
         t_seluserstr TYPE STANDARD TABLE OF ssel_user_str.


*If there is any pattern sent for Transaction codes then use the same for fetching Transaction codes
  IF NOT tcode_select IS INITIAL.
    PERFORM process_tcodepattern TABLES t_seluserstr
                                  USING tcode_select.
  ENDIF.

  IF tcode_data = 'X'.
* Fetch All Transaction codes from the SAP system
    IF standard_tables = 'X'.
      IF t_seluserstr[] IS INITIAL.
        select * into corresponding fields of table tcodes from tstc.
        select * into corresponding fields of table tcodes_desc from
          tstct where sprsl = 'E'.
      ELSE.
        select * into corresponding fields of table tcodes from tstc
          where tcode in t_seluserstr[].
        select * into corresponding fields of table tcodes_desc from
          tstct where sprsl = 'E' and tcode in t_seluserstr[].
      ENDIF.

    ELSE.
      IF t_seluserstr[] IS INITIAL.
        SELECT tcode FROM (lv_alrttstc) INTO TABLE t_tcodes_tstc WHERE tcode NE space AND sprsl = 'E'.
      ELSE.
        SELECT tcode FROM (lv_alrttstc) INTO TABLE t_tcodes_tstc WHERE tcode IN t_seluserstr[] AND sprsl = 'E'.
      ENDIF.

      SELECT sprsl tcode ttext FROM (lv_alrttstct)
      INTO CORRESPONDING FIELDS OF TABLE t_tcodes
      FOR ALL ENTRIES IN t_tcodes_tstc
      WHERE   sprsl = 'E' AND
              tcode = t_tcodes_tstc-tcode.

    ENDIF.

    IF sy-subrc <> 0.
      wa_bapiret-type = 'E'.
      wa_bapiret-id = 'MSG'.
      wa_bapiret-number = '000'.
      wa_bapiret-message = 'There are no Transaction Codes available in the System'."#EC NOTEXT
      APPEND wa_bapiret TO tbl_bapiret.
      CLEAR wa_bapiret.
      EXIT.
    ENDIF.


    FREE : t_tcodes_tstc.
  ENDIF.

ENDFUNCTION.



1 ACCEPTED SOLUTION
Read only

former_member186741
Active Contributor
0 Likes
3,109

I think you may be able to make use of the 'tcode_select' parameter. The first time you call the fm it will return more than you want but you can just use the first 50k and save the key of the 50001th record and pass that in the parameter to the next call to the FM(telling it to give you records >= that key value) and then repeat this process until you have no records coming back.

31 REPLIES 31
Read only

Former Member
0 Likes
3,108

Hi All,

I am getting number of lines from internal table like this.

Describe table tcodes lines lv_count.

IF lv_count > 50000.

ELSE.

Tcodes = tcodes.

ENDIF.

But how can I get each time only 50k and display them.

Thanks,

NReddy

Read only

0 Likes
3,108

Hi,

you can use as below:

select * up to 10 rows from ekko where bukrs = '1001'.

write:/ EKKO-ebeln.

endselect.

or after entries in Internal table, you have to write like this:

Loop at ITAB.

If Sy-tabix <= 50000.

endif.

endloop.

Regards,

Ani

Read only

0 Likes
3,108

Hi,

I am trying this code, but is not working. Can any one please help me.

select * into corresponding fields of table tcodes from tstc.

Describe table tcodes lines lv_count.

IF lv_count > 50000.

select * from tcodes

up to 50000 rows

into table tcodes.

ENDIF.

And also how can I loop it so that I will get all the 200k records.

Thanks.

Read only

0 Likes
3,108

Hi,

I tried this.

DATA:

TCODES type table of TWBTCODE,

TCODES1 type table of TWBTCODE.

select * into corresponding fields of table tcodes from tstc.

Describe table tcodes lines lv_count.

IF lv_count > 50000.

LOOP at tcodes.

select up to 50000 rows

into table tcodes1.

ENDLOOP.

ENDIF.

How can I get data in loop stmt and also how do I get remaining entries.

Please help.

Thanks.

Read only

kesavadas_thekkillath
Active Contributor
0 Likes
3,108

Type package size in your editor and hit F1 key.

Read only

0 Likes
3,108

Hi Keshav,

Thank you. If I use INTO package size last few records are staying and if I use APPENDING all the records are comming. How can I get each time 50,000 until all records are done.

Thanks.

Read only

0 Likes
3,108

Hi,

I tried this, but the program is getting teminated.

DATA: dbcur1 TYPE cursor.

OPEN CURSOR dbcur1 FOR

select * from tstc.

DO.

FETCH NEXT CURSOR dbcur1

INTO TABLE tcodes PACKAGE SIZE 50000.

ENDDO.

CLOSE CURSOR: dbcur1.

Can any one please help me.

Thanks.

Read only

0 Likes
3,108

>

> Thank you. If I use INTO package size last few records are staying and if I use APPENDING all the records are comming. How can I get each time 50,000 until all records are done.

.

What do you mean last few records are staying? For me, package size seems to working and it returns the last package correctly..


SELECT * FROM VBAK INTO TABLE T_VBAK
       PACKAGE SIZE 20.
  LOOP AT T_VBAK INTO S_VBAK. 
     write: / s_vbak-vbeln
  ENDLOOP.
  WRITE: / 'END OF PACKAGE'.
ENDSELECT. 

Read only

Former Member
0 Likes
3,108

Are you calling this function remotely?

Rob

Read only

0 Likes
3,108

Hi Rob,

We call this BAPI from Java.

Thanks.

Read only

0 Likes
3,108

>

> We call this BAPI from Java.

So is it correct to say that you want to call this function repeatedly? The first time you pick up the first 50,000 records, the second time the next 50,000 records and so on until you have returned all of the records?

Rob

Read only

former_member186741
Active Contributor
0 Likes
3,110

I think you may be able to make use of the 'tcode_select' parameter. The first time you call the fm it will return more than you want but you can just use the first 50k and save the key of the 50001th record and pass that in the parameter to the next call to the FM(telling it to give you records >= that key value) and then repeat this process until you have no records coming back.

Read only

0 Likes
3,108

Thank you Rob and Neil.

The main function module I have bptcoddata_extract is having 200k records. I need to get the data in batches. As I am new this functionality, but can I write a wrapper fuction module to call this function and get data once every 50,000 records until I get all the data.

Can you please give me an example of using tcode_select parameter.

I greatly appriciate all your help.

Thanks.

Read only

0 Likes
3,108

that fm does not exist in my system but assuming this field is a range or select option type field:

tcode_select-option = 'GE'.

tcode_select-sign = 'I'.

tcode_select-low = "your value from the 50001th entry".

APPEND tcode_select.

Read only

0 Likes
3,108

Thank you Neil. I also do not have tcode_select.

In the wrapper function module I am calling the main function module, which contains all the data. How to loop through that data to send 50000 records at a time until all the data is done.

Can some one please help me.

Thanks.

Read only

0 Likes
3,108

actually I see that TCODE_SELECT is listed as a type 'string'.......can you double-click on the function module to view the code? If so you will be able to work out how this string is used by the fm. I think you maybe able to pass a pattern, something like 'TCODE >= 'abcd'.........

another thing you could try is to get your wrapper to have the following parameters:

start_number and end_number

from java you should call your wrapper in a loop, say 4 times so that

start_number is 1, 50001,100001,150001 and end_number is 50000, 100000, 150000 and 200000.

the code from you rwrapper can call the fm and then delete the entries it does not want before sending it back to java.

so it would have something like:

*remove records after your target first

l_first_to_delete = i_end_number + 1.

delete lt_tcode from l_first_to_delete.

*now remove entries before your first target entry

if i_start_number <> 1.

l_last_to_delete = i_start_number - 1.

delete lt_tcode from 1 to l_last_to_delete.

endif.

Read only

0 Likes
3,108

In your java program, you can call the fm in a loop, each time passing a number indicating which group of records you want (1, 2, 3, ...N). Then in the FM, use the package size addition to the SELECT statement to skip the 50,000*(N-1) records.

Rob

Read only

0 Likes
3,108

use the package size addition to the SELECT statement to skip the 50,000*(N-1) records

Hi Rob,

Suppose there are 50,000 thousand records to fetched in 5 loops ... say 5 calls to the fm. The select statement in each hit will always give the first 10000 records in five loops not the records from 20,000 to 50,000.

Assuming that its not possible to skip using package statement.

Read only

0 Likes
3,108

Yes - it's ugly, but what else?

Rob

Read only

0 Likes
3,108

Hi Rob,

We had a similar scenario long back and we used the sql db data before accesing from sap. we selected the latest date field available in sql table . And then selected the data greater than this date from sap. Luckily we had the date field indexed in the sap table. So it went fine. Once in a week the sql table was refreshed with the data from sap.

For OP's scenario even i too dot have any idea.

Keshav

Read only

0 Likes
3,108

Actually I like Neil's suggestion ;

Call the FM in a loop and pass the sy-index (iteration count) to the FM...

Based on the Iteration count, Get the Start index position (IDX1) and From Index position(IDX2)...

Once you retrieve all your data AND sorted the internal table, Using the

APPEND LINES OF ITAB FROM IDX1 TO idx2 to ITAB_OUT...

If the IDX2 is greater than total records in internal table, You can pass a parameter back to the main program to indicate the end?

Not very neat (multiple calls to DB table) and We could miss a TCODE if somebody is deleting a tcode in between calls

Read only

0 Likes
3,108

Unfortunately, I think all the solutions have a problem. If a records is inserted or deleted from the table between calls to the FM, that will mess up the indexing. The correct way will be to process and return all records at once.

Rob

Read only

0 Likes
3,108

Hi Rob,

That was the first thing I thought when I read the problem. Get all the records at once! Deal with the 50K record blocks in Java.

SNREDDY11,

One other thing: based on the wording of the initial post "display" 50,000 records at a time?! Why would it ever be useful to display that many records? I'm curious about the scenario.

Thanks,

Erik

Read only

0 Likes
3,108

Hi,

As the data is big it is taking some time to send all the 200k records to Java once, so my lead asked me if I can send 50k each time.

I really appreciate all your help.

Thanks,

SNReddy.

Read only

0 Likes
3,108

Hi,

This might not be the cause but if you're doing JSP or something like that, anything where you're trying to display all records, you might have significant delays when displaying many records.

It's possible that you could recieve 200K records quickly in Java but then you can't display all of them right away because that's what normally takes a lot of time in my experience. When I did web development, I was to limit any displays of data to 100 records at a time to eliminate this type of problem.

Thanks,

Erik

Read only

0 Likes
3,108

Just a chance :

Are you passing any where clause to the select query , if so you can build a dynamic where clause in your functional module and pass the latest value from previously fetched set while calling the fm from java .

in your query you can add GE the latest value. You can use the upto rows statement in your query.

Read only

0 Likes
3,108

Hi,

In the wrapper function module I am calling the main function module. So I get all the data in Tcode, Tcode_desc and Authobj tables. Now I have to loop on them to send only 50k at a time. Here do I have to call this wrapper function 4 or more times or how to send data in batches?

call FUNCTION '/ART/BPTCODDATA_EXTRACT'

EXPORTING

FILEPATH = FILEPATH

STANDARD_TABLES = S_TABLES

CONNECTOR = CONNEC

TCODE_DATA = TC_DATA

AUTHOBJ_DATA = AOBJDATA

DOWNLOAD_FILE = DL_FILE

TCODE_SELECT = TC_SELE

TABLES

TBL_BAPIRET = T_BAPIRET

TCODES = TCODES

TCODES_DESC = TCODES_DESC

AUTHOBJ = AUTHOBJ.

IF NOT t_bapiret[] IS INITIAL.

APPEND LINES OF t_bapiret TO tbl_bapiret.

ENDIF.

Thanks.

Read only

0 Likes
3,108

Hi,

I have the table Tcodes which has around 200k records, how can I loop through this table and get 50k in to another internal table.

Please help.

DATA: TCODES type table of TWBTCODE.

IF NOT tcodes[] IS INITIAL.

Describe table tcodes lines lv_count.

if lv_count GE 50000.

LOOP AT tcodes into wa_tcodes.

select * from tcodes up to 50000 rows

into table tcodes1.

ENDLOOP.

clear lv_count.

ENDIF.

Thanks.

Read only

0 Likes
3,108

Hi SNR,

Is this a new requirement or same as what you had requested earlier? If it is a same requirement, Basically there were multiple options suggested in this thread and you could potentially go with one of them (none of them are elegant, but there are very few options).

If you have an internal table with 200K records, you can get 50000 records using APPEND LINES OF TABLE ITAB1 IDX1 TO IDX2 TO ITAB2.

Read only

0 Likes
3,108

Try this based on your count of how many entries are in the main table.

  • work out how many iterations of this following DO are needed

l_times_to_do = ( lv_count MOD 50000 ) + 1.

l_start = 1. l_end = 0.

do l_times_to_do.

l_end = l_end + 50000.

append lines of tcodes from l_start to l_end to tcodes_small.

l_start = l_start + 50000.

  • now the table contains the current 50,000 entries you want

  • do something with them here...ie put some code in here or call an rfc or whatever you want

*....and then clear the table for the next iteration

clear tcodes_small.

enddo.

Read only

0 Likes
3,108

Thank you so much Neil. I did the following code and now I am getting the data as I needed.

Thank you so much to everyone who helped me with this request.


Describe table tcodes lines lv_count1.
Describe table tcodes_desc lines lv_count2.
Describe table authobj lines lv_count3.

lv_count =  lv_count1.

if lv_count2 > lv_count.
  lv_count = lv_count2.
endif.

if lv_count3 > lv_count.
  lv_count = lv_count3.
endif.

l_times_to_do = ( lv_count DIV 50000 ) + 1.
l_start = 1. l_end = 0.

do l_times_to_do times.
  l_end = l_end + 50000.

  IF NOT tcodes[] IS INITIAL.
    append lines of tcodes from l_start to l_end to tcodes_small.
  ENDIF.

  IF NOT tcodes_desc[] IS INITIAL.
    append lines of tcodes_desc from l_start to l_end to tcodes_desc_small.
  ENDIF.

  IF NOT authobj[] IS INITIAL.
    append lines of authobj from l_start to l_end to authobj_small.
  ENDIF.

  l_start = l_start + 50000.

*send the data out

  clear tcodes_small.
  clear tcodes_desc_small.
  clear authobj_small.
enddo.

clear lv_count.
clear l_start.
clear l_end.
clear l_times_to_do.