A template for the same is put up in the wiki parts of which are explained in this Blog
Key things to look out for when designing a generic extractor based on a function module :
The delta relevant field is passed back to the function module if the infopackage triggering the load is a delta load.
For example if your delta field is AEDAT or the changed at field – then the value for the field is sent back by SAP BW when requesting for a delta.
g_datasource = ‘Z_PE_TRAN_D_PO_ACTUALS’.
LOOP AT I_T_SELECT INTO WA_SELECT
WHERE FIELDNM = ‘ZZCPUDT’.
select single deltaid from roosgendlm
where oltpsource = g_datasource.
If Record Exists – Deltas Exist else this is the first Delta load
if sy-subrc = 0.
I_UPDMODE = ‘D’.
I_UPDMODE = ‘I’.
The above loop will let you know if the load was a delta load or a full load. If the field is blank then it is a full load.
Significance of the ROOSGENDLM table.</p><p><br />The ROOSGENDLM table maintains the delta pointers for all generic extractors. Entries in ROOSGENDLM will appear is a successful init took place and be updated based on the deltas done for the extractor.<br />If there is no entry in ROOSGENDLM for the datasource – this would mean that only full loads were done till date and or no init took place till date.<br />The deltaID field in ROOSGENDLM against the extractor will specify the repeat point for your datasource. This is after taking into account the safety limits set in the generic delta managemenbt screen. <br /><br />In this example I have hardcoded the datasource value in the function module , but have not found a way to automatically get the same from somewhere within R/3 – will update the same if I find one. It should be ideally in the import fields but am yet to figure out the same.<br />After finding the delta – the logic for identification of the changed fields is to be done by the function module – there is not automatic delta field determination.<br />* Check for update Mode Delta<br /> if I_UPDMODE = ‘D’ . </p><p> <Delta record Identification></p><p> endif. </p><p>*The way the extraction program is called *
The program is called twice. The first time it is called , the extraction parameters are retrieved and then the function module is called once again when the actual data extraction takes place. You should not extract any data the first time the program is called and should extract data only when it is called the second time.
This is handled by
IF I_INITFLAG = SBIWA_C_FLAG_ON.
IF NOT G_FLAG_INTERFACE_INITIALIZED IS INITIAL.
IF 1 = 2. MESSAGE E008(R3). ENDIF.
LOG_WRITE ‘E’ “message type
‘R3’ “message class
‘008’ “message number
‘ ‘ “message variable 1
‘ ‘. “message variable 2
The above statement ensures that it is the first time the extractor is called and not otherwise. Accordingly messages are handled.
process the selection parameters
extract the data.
All the extraction and processing should be done within the else condition and the extractor is not called again.
The selection parameters are sent through the structure that is in the tables parameters and should be handled as follows :
* Fill range tables for fixed InfoSources.
LOOP AT G_T_SELECT INTO WA_SELECT WHERE FIELDNM = ‘ZZEBELN’.
MOVE-CORRESPONDING WA_SELECT TO GR_EBELN.
Here make sure that you have declared the range variables in the function modules or in the global data include.
Extraction should start with an OPEN CURSOR and then you cannot open multiple cursors when the previous one is already open.
This is handled by the datapackid variable:
* First data package -> OPEN CURSOR
IF G_COUNTER_DATAPAKID = 0.
This is when extraction begins – look at the open cursor as something like a select statement with an endselect statement – only that the into parameter is not required.
The cursor variable holds the records required or the position of the record and the next record is fetched using the fetch next cursor statement.
What happens here is that the data is transferred into E_T_DATA and then it goes through post processing to check for any exits etc and then gets packetized. However it is important to use the open cursor statement instead of a simple select statement into e_t_data. If you choose to directly select data into e_t_data then you should keep in mind the number of records and usually if you select more than 1 million records into the table without using an open cursor your will get a dump for table size. Also since it is an open cursor – you will not run into memory problems unlike selecting data into an internal table.
Packetization of data :
SV_MAXSIZE = G_S_INTERFACE-MAXSIZE.
This is retrieved from the I_MAXSIZE parameter that is sent from the calling system – in this case the packet size is set through the infopackage settings in BW or from the package size specified in RSA3 when testing the extractor.
Closing the cursor after data extraction is complete.
* Last record reached!!!
IF LV_LOCALSIZE LT SV_MAXSIZE.
CLOSE CURSOR G_CURSOR.
SV_LAST_DATA_FLAG = CON_ANGEKREUZT.
Let me know what you think. This was a template that came aboutthrough some serious experimentation , want to know if any simpler templates or templates that do more are also available which might be used across projects…
The full template for the function module extractor is given as a link in the first statement in the blog </p>