Anda di halaman 1dari 15

SAP Custom BAPI Creation

ERPsim lab 3000, chemin de la Cte-Sainte-Catherine Montral (Qubec)


1

Creation of a custom, remotely callable function (BAPI)


This document describes the process to create an SAP function that is remote enabled (otherwise known as an RFC or BAPI in SAP terminology), which will return some data from the SAP repository for reporting or other purposes. The process overview is as follows: Assess the nature of the data at the field level that will be returned by the function. Create a custom structure that will hold the data that is to be returned. Create a function module (a grouping structure for functions in SAP) Implement the function in ABAP to retrieve the source data, populate the structure, and return.

For the purpose of providing an example, independent requirements history information will be used (tables PBHI and PBIM).

Data discovery and design


We first need to determine which data our structure is going to hold so that we can define it properly. We also need to know what kind of data it is (e.g. dates, times, text, quantity values). Transaction code SAP Menu Path SE11 Tools / ABAP Workbench / Development / ABAP Dictionary

1. Run transaction SE11. 2. Select Database table and enter the name of the table : PBHI 3. Click on Display

4. You now get the list of fields in this table. 5. Take note of the fields that you are interested in, and the data element associated with each. For our example PDATU, PLNMG, DBMNG, LAEDA, UZEIT, and AENAM.

6. We are also interested in the WERKS and MATNR fields from the PBIM table. Repeat steps 1 through 5 above and take note of the data elements associated with those fields.

Creating the structure


We will now create a new structure that will hold the data to be returned by the function. The definition of a structure appears similar to that of a database table, but in terms of behavior they are quite different. A table exists in the database, and the data inside it is permanent unless explicitly deleted. It is also visible to all users of a system. A structure on the other hand is really a complex data type that is to say, a set of data items (fields) that are related. The data in a structure only exists for the duration of the running of a program or function, and is only available to a single user running that program at that time. Transaction code SAP Menu Path SE11 Tools / ABAP Workbench / Development / ABAP Dictionary

1. Run transaction SE11. 2. Select Data type. 3. Give your structure a name. Custom objects in SAP must start with Z. So for example, Z505_INDREQHISTORY. 4. Click on Create. 5. When prompted, select Structure.

6. Enter a description of the purpose of the structure in the Short description field. 7. Click on the Components tab if it is not already selected. 8. Enter the component fields that are in the structure. You can name these however you wish, or simple use the same names as the fields from the table which holds the source data. 9. Specify the component types for each of these fields, based on the data elements that you recorded during the design and dicovery phase. 10. Press enter and you should see a result similar to the figure at right.

In SAP, some data types such as QUAN and CURR represent numerical values that only make sense in the context of the associated unit of measure. With CURR for example, the unit of measure is the currency (EUR, CAD, USD etc.) SAP requires that fields of this type be linked to the data fields that hold the unit of measure. With our example here, the forecast amount fields relate to the unit of measure for the material master. 11. Click on the Currency / Quantity fields tab 12. Enter the reference table where the unit of measure is stored. If you are going to include the unit of measure in the structure definition, you can self-reference the structure here. For our example, the referenced table is the material master MARA. 13. Enter the reference field from the referenced table that contains the unit of measure. For our example, the referenced field is MEINS.

14. Click on to save the structure. When prompted, provide package $tmp to place the object in your users local object space. 15. Click on to activate the structure. This effectively publishes your structure and allows other users and programs to use it. You may be prompted Warnings Occurred During Activation. You can typically ignore these, but errors that prevent activation must be resolved.

Creating the function


We will now create our function. Functions cannot exist by themselves in SAP they must be collected together in related groups of functions. To create a function you must either assign it to an existing group, or create a new group. All custom development should be assigned to a custom group. Transaction code SAP Menu Path SE37 Tools / ABAP Workbench / Development / Function Builder

1. Run transaction SE37. 2. From the menu select Goto / Function Groups / Create Group 3. Enter a name, again starting with Z as all custom objects must. 4. Enter a description of the group of functions. 5. Click on Save. The Create Object Directory Entry dialog appears. 6. Click on Local Object.

7. You are returned to the Function Builder: Initial screen. 8. Enter a name for the function we will create, again starting with Z. For example Z505_GET_INDREQHIST. 9. Click on Create.

The Create Function Module dialog appears. 10. Enter the function group that this function will belong to. Use the function group created in steps 2 through 6 above. 11. Enter a description of the purpose of the function in the Short Text field. 12. Click on Save. 13. Click past the information message that appears.

The Function Builder: Change screen appears. 14. Click on the Attributes tab. 15. Under Processing Type select the Remote-Enabled Module option. This setting is what allows a regular ABAP function to be called remotely.

The tabs Import, Export, Changing and Tables allow you to define the input and output parameters of the function. We will be returning tabular data in our example function. 16. Click on the Tables tab. 17. Enter a name for the parameter, the Type Specification value of LIKE and in the Associated Type column enter the name of your structure that defines your output data.

Were now ready to write our code! Its a good practice to document code with its purpose and history. 18. Click on the Source code tab. 19. After the comment block that shows the functions parameter interfaces, add another comment block with a description of the purpose of the function, and some information about when and who created it.

FUNCTION Z505_GET_INDREQSHIST. *"---------------------------------------------------------------*"*"Local Interface: *" TABLES *" HISTORY STRUCTURE Z505_ST_INDREQSHIST *"---------------------------------------------------------------* Retrieves the history of independant requirements for all plants ****************************************************************** * 2009-01-29: DVL, Created ****************************************************************** ENDFUNCTION.

To fetch the data we need to write a SELECT statement. We can fetch the data and put it directly into the output table by using the INTO TABLE construct. 20. Write your select statement.Pay attention to the following: Unlike the SELECT construct in SQL, the ABAP SELECT construct does not separate fields with commas. The order of the fields selected is important. The position is matched one for one with the fields of the destination table, so make sure the field selection order is the same as the order of the fields in the table (as defined by the structure we created previously). When selecting data from multiple tables the INNER JOIN construct defines how the data in one table relates to another. Note that the fields are resolved to their associated tables with the use of the ~ character. Before we can use the function, we need to check, save and activate it. 21. Click on or hit CTRL+F2 to check the syntax of your code. Resolve all errors and warnings. Highlight a word and hit the F1 key for extra information. 22. Click on or hit CTRL+S to save the function. 23. Click on or hit CTRL+F3 to activate the function.

FUNCTION Z505_GET_INDREQSHIST. *"---------------------------------------------------------------*"*"Local Interface: *" TABLES *" HISTORY STRUCTURE Z505_ST_INDREQSHIST *"---------------------------------------------------------------* Retrieves the history of independant requirements for all plants ****************************************************************** * 2009-01-29: DVL, Created ****************************************************************** SELECT pbim~werks pbim~matnr pbhi~pdatu pbhi~plnmg pbhi~dbmng pbhi~laeda pbhi~uzeit pbhi~aenam INTO TABLE history FROM pbim INNER JOIN pbhi ON pbhi~bdzei = pbim~bdzei. ENDFUNCTION.

10

Unit testing the function to make sure it behaves as we would like it to, is also a good idea. 24. Click on or hit F8 to enter test/direct execute mode. 25. Click on or hit F8 to execute the function. 26. In the tables section of the output display, to the right of Result: click on to display the content of the results table.

Adding an input parameter and filtering the result set


Often you do not want all the data that is in the system, and may want to filter the results returned at runtime depending on the context or the user. We will now modify the function we created previously to add a plant parameter passed as input, and use this to filter the output. To add a little extra complexity we would like the behaviour to be such that if no value is passed as input then all the records are returned. If a plant value is passed as input, then we would like to return records for that plant only. First we need to change the defined parameters for the function. Transaction code SAP Menu Path SE37 Tools / ABAP Workbench / Development / Function Builder

11

1. Run transaction SE37. 2. Enter the name of the function module to modify.

3. Click on Change 4. Click on the Import tab. Here we will create an input parameter. 5. Enter the Parameter Name as PLANT, the Type as TYPE, and the Associated Type as WERKS_D. This specifies a single value parameter for plant, and links it to the WERKS object in the SAP dictionary. 6. Select (check) the Optional field. This allows the parameter to be unspecified (empty) by the calling code. 7. Select (check) the Pass Value field. All parameters for remotely callable functions must be passed by value.

12

8. Click on the Source code tab. Note the extra IMPORTING parameter in the interface comment block. 9. Revise the description of purpose. 10. Add an entry in the history log for the change.

FUNCTION Z505_GET_INDREQSHIST. *"-------------------------------------------------------------*"*"Local Interface: *" IMPORTING *" VALUE(PLANT) TYPE WERKS_D OPTIONAL *" TABLES *" HISTORY STRUCTURE Z505_ST_INDREQSHIST *"-------------------------------------------------------------* Retrieves the history of independant requirements, for all * plants, or if the PLANT parameter is provided as input, only * the history for that plant. **************************************************************** * 2009-01-29: DVL, Created * 2009-02-12: DVL, Added plant filtering **************************************************************** **************************************************************** * 2009-01-29: DVL, Created * 2009-01-30: DVL, Added plant filtering **************************************************************** DATA: filter TYPE string. SELECT pbim~werks pbim~matnr pbhi~pdatu pbhi~plnmg pbhi~dbmng pbhi~laeda pbhi~uzeit pbhi~aenam INTO TABLE history FROM pbim INNER JOIN pbhi ON pbhi~bdzei = pbim~bdzei WHERE (filter). ENDFUNCTION.

To use this parameter and dynamically filter the results returned from the SELECT statement we will need to build a filter string that has the form similar to an SQL WHERE condition. First we must define a local variable to hold this value. 11. Define a local variable of TYPE string with the DATA construct. 12. Add the WHERE condition to the end of the select statement. Note that ABAP allows for the WHERE condition to be passed from a variable. When you are editing long ABAP statements, pay attention to adding and removing statement terminating periods . so that the syntax remains correct.

13

An empty string passed into the WHERE condition has no effect, just as if no condition was specified. This is the desired behaviour for our function if no plant paramater has been specified. We need to check if a value was provided, and if so build the WHERE condition into the local string variable. 13. Add an IF construct, testing the value of the input parameter plant based on whether a value was provided. The ABAP construct IS INITIAL (and the negation IS NOT INITIAL) returns whether a variable is empty. Its good practice to comment the code block with the nature of the test condition and the intended behaviour of the code executed if the condition is true. Dont forget the ENDIF. to close the code block. It is also good practice to comment which condition the ENDIF corresponds to. For longer code blocks and nested IF conditions, it can be easy to lose track. 14. Populate the value of the filter local variable using the CONCATENATE construct. CONCATENATE assembles multiple source strings into a destination string. The source strings can variables or literals, specified by containing the value of the string within single quotes ' . The WHERE condition must respect the syntax of the SELECT construct so table and field identifiers must match those that are in the actual SELECT itself. For tests of equality against string literals, the literals must be properly encapsulated in quotes. Note that in order to define a string literal that contains the quote character itself, we need to escape it or the ABAP compiler will think we have specified the end of string and not be able to understand the rest of the line. We do this by typing the quote

**************************************************************** * 2009-01-29: DVL, Created * 2009-01-30: DVL, Added plant filtering **************************************************************** DATA: filter TYPE string. IF plant IS NOT INITIAL. " If a plant parameter was supplied, construct a filter " (SQL WHERE condition) to restrict the data selected. ENDIF. "plant parameter provided SELECT pbim~werks pbim~matnr pbhi~pdatu pbhi~plnmg pbhi~dbmng pbhi~laeda pbhi~uzeit pbhi~aenam INTO TABLE history FROM pbim INNER JOIN pbhi ON pbhi~bdzei = pbim~bdzei WHERE (filter). ENDFUNCTION.

FUNCTION Z505_GET_INDREQSHIST. *"-------------------------------------------------------------*"*"Local Interface: *" IMPORTING *" VALUE(PLANT) TYPE WERKS_D OPTIONAL *" TABLES *" HISTORY STRUCTURE Z505_ST_INDREQSHIST *"-------------------------------------------------------------* Retrieves the history of independant requirements, for all * plants, or if the PLANT parameter is provided as input, only * the history for that plant. **************************************************************** * 2009-01-29: DVL, Created * 2009-01-30: DVL, Added plant filtering **************************************************************** DATA: filter TYPE string. IF plant IS NOT INITIAL. " If a plant parameter was supplied, construct a filter " (SQL WHERE clause) to restrict the data selected. CONCATENATE 'pbim~werks = ''' plant '''' INTO filter. ENDIF. SELECT pbim~werks pbim~matnr pbhi~pdatu pbhi~plnmg pbhi~dbmng pbhi~laeda pbhi~uzeit pbhi~aenam

14

character twice where we want it in the string literal. Thus, we arrive at ' ' ' ' to define a string literal that contains a single quote character! Once again, before we can use the function, we need to check, save and activate it. 15. Click on or hit CTRL+F2 to check the syntax of your code. Resolve all errors and warnings. 16. Click on or hit CTRL+S to save the function. 17. Click on or hit CTRL+F3 to activate the function.

INTO TABLE history FROM pbim INNER JOIN pbhi ON pbhi~bdzei = pbim~bdzei WHERE (filter). ENDFUNCTION.

Finally, we need to unit testing the function to make sure it behaves as we would like it to. 18. Click on or hit F8 to enter test/direct execute mode. 19. In the Import parameters section, to the right of PLANT enter a valid plant to return only data for that plant, or leave it empty to return data for all plants. 20. Click on or hit F8 to execute the function and validate the results.

15

Anda mungkin juga menyukai