So what is SAP BOPF? firstly it stands for Business objects Process Framework and is basically an objects based frame work. But what does that mean …..errm well it is basically a pre-built bunch of object methods that enable you to maintain your data in a standard way and is represented in a hierarchical node tree, where each node relates to a business object with associated functions (i.e. query, auth check, validation, alternate key, association etc). Maybe from a developers point of view, it can be thought of as the modern OO based HR logical databases. It also provides easier integration into Fiori apps but we will get onto this further down the line.
I will get into the how in a second but imagine you want to create some new tables and then create custom methods/function modules to add, delete, select etc data from these tables. Instead of going to SE11 creating some new tables including their relationships. Then using SE24 to create some methods or SE37 to create some function modules to manipulate the data. You simply create the structures for your new data and then use the BOPF specific transactions BOB and BOBF (note the confusing name BOB instead of BOP…), feed-in your structures and it will automatically create your underlying tables, with built-in GUIDs identification to link all your data together (much like the SAP CRM system if you have used that).
It will also create you an interface class to the standard BOPF functionality that enables you to access and maintain this data in a standard way using ABAP OO. So how do you go about implementing this, in the interests of trying not to replicate information that is already available please see this introductory video put together by the guys at sapyard for a very good full end to end description of how to create one. Below I have also added the basic steps and all the ABAP code you need (cut and pastable, if that even a word) to create a very basic working example in your SAP system
Note you don’t really need to watch the video to be able to follow the steps below but it might help, or you can follow the steps then watch the video to re-enforce you knowledge. Also be aware the video has been upload at 1.5x speed which I think is genius as I could still follow it but saved me a lot of time, if you want to slow it down hit the settings cog At the bottom and choose a slower playback speed.
Creating your first SAP BOPF using tcodes BOB and BOBF
First log into your SAP system and execute transaction BOB and choose Create Custom Business Object
Now you will follow the wizard, first click continue
Enter prefix as Z and give it a Business Object Name, not the name i have give ZTS_BOPF. Now whenever you see this in the code i provide you will need to replace it with the name you choose. Press contiune
Now use the proposed name or choose your own if you prefer
Now it gets a bit messy as you need to provide a root name (i.e. TSROOT) then click the propose name buttons to generate names for you Persistent and transient structures. Don’t worry too much about these yet just know that they need be create before you can get past this screen.
For example if you click continue without creating them you will get and error message.
So double click on each one to create the structure, you should get a popup to confirm you want to create it
Now the same for the transient structure, you can put anything in here but make sure you don’t have the same field name in this structure as the persistent structure above otherwise you business object will dump due to these structure being merged as part of this process.
Now you should be able to press continue. The next screen will ask for a name for your combined structure and table. This will basically create a new structure and database table with fields from both of the structures you created above.
Press continue and them complete and your done. You have created your first Business object
ABAP code to Query, Create, Delete data from BOPF
There is a bit more I probably need to show you within BOBF like how to query, add, delete data manually but if you watched the video above you may have already covered this so to allow you to skip straight to ABAP code here is some example code you should be able to cut and paste into a new program. Note you will need to replace some of the references to TSROOT and ZTS_BOPF with the names you used. See business objects settings for more details on where you can find these details so within the object you have created or a standard SAP one.
You will also want to get to grips with the standard ABAP code completion functionality built into SAP, you might have seen this before but not really used it much but for BOPF development this becomes and almost essential development tool.
DATA lo_svc_mngr TYPE REF TO /bobf/if_tra_service_manager.
DATA lo_txn_mngr TYPE REF TO /bobf/if_tra_transaction_mgr.
DATA: lo_chg TYPE REF TO /bobf/if_tra_change,
lo_mess TYPE REF TO /bobf/if_frw_message.
DATA: lv_rej TYPE boole_d.
DATA mo_bo_conf TYPE REF TO /bobf/if_frw_configuration.
DATA: lt_data TYPE zttsroot,
lt_key TYPE /bobf/t_frw_key,
lt_selparam TYPE /bobf/t_frw_query_selparam.
DATA: lt_mod TYPE /bobf/t_frw_modification.
DATA lr_create TYPE REF TO zstsroot. "Combined structure from your business object node
DATA lr_sdata TYPE REF TO zstsroot. "Combined structure from your business object node
PARAMETERS: p_ebeln TYPE ebeln,
p_crt TYPE c AS CHECKBOX,
p_del TYPE c AS CHECKBOX.
CALL METHOD /bobf/cl_tra_serv_mgr_factory=>get_service_manager
EXPORTING
iv_bo_key = zif_zts_bopf1_c=>sc_bo_key " Business Object
* iv_create_sync_notifications = ABAP_FALSE " Switch on/off sync notifications
* iv_create_assoc_notifications = ABAP_FALSE " Switch on/off association change notifications
* iv_create_prop_notifications = ABAP_FALSE " Switch on/off property change notifications
RECEIVING
eo_service_manager = lo_svc_mngr. " Interface for (Proxy) Service Manager
*Auto complete is ctrl+space, select, tab, ctrl+space, select, tab
CALL METHOD /bobf/cl_tra_trans_mgr_factory=>get_transaction_manager
RECEIVING
eo_transaction_manager = lo_txn_mngr. " Standalone Transaction Manager Instance
IF p_ebeln IS NOT INITIAL.
APPEND INITIAL LINE TO lt_selparam ASSIGNING FIELD-SYMBOL(<fs_sparam>).
<fs_sparam>-attribute_name = 'EBELN'.
<fs_sparam>-sign = 'I'.
<fs_sparam>-option = 'EQ'.
<fs_sparam>-low = p_ebeln.
"<fs_sparam>-HIGH
ENDIF.
*query
lo_svc_mngr->query(
EXPORTING
iv_query_key = zif_zts_bopf1_c=>sc_query-tsroot-select_all " Query
* it_filter_key = " Key Table
it_selection_parameters = lt_selparam " Query Selection Parameters
* is_query_options = " Query Options
iv_fill_data = abap_true "if true fills et_data table if false et_data left blank
* it_requested_attributes = " List of Names (e.g. Fieldnames)
IMPORTING
* eo_message = " Message Object
* es_query_info = " Query Information
et_data = lt_data
et_key = lt_key
).
IF p_crt IS NOT INITIAL.
"create
CREATE DATA lr_create.
lr_create->ebeln = p_ebeln.
lr_create->ebelp = '0001'.
lr_create->key = /bobf/cl_frw_factory=>get_new_key( ).
APPEND INITIAL LINE TO lt_mod ASSIGNING FIELD-SYMBOL(<fs_mod>).
<fs_mod>-node = zif_zts_bopf1_c=>sc_node-tsroot.
<fs_mod>-key = lr_create->key.
<fs_mod>-data = lr_create.
<fs_mod>-change_mode = 'C'.
lo_svc_mngr->modify(
EXPORTING
it_modification = lt_mod " Changes
IMPORTING
eo_change = lo_chg " Interface of Change Object
eo_message = lo_mess " Interface of Message Object
).
ENDIF.
IF p_del IS NOT INITIAL.
"delete
CREATE DATA lr_sdata.
READ TABLE lt_data INDEX 1 REFERENCE INTO lr_sdata .
APPEND INITIAL LINE TO lt_mod ASSIGNING <fs_mod>.
<fs_mod>-node = zif_zts_bopf1_c=>sc_node-tsroot.
<fs_mod>-key = lr_sdata->key.
<fs_mod>-data = lr_sdata.
<fs_mod>-change_mode = 'D'.
lo_svc_mngr->modify(
EXPORTING
it_modification = lt_mod " Changes
IMPORTING
eo_change = lo_chg " Interface of Change Object
eo_message = lo_mess " Interface of Message Object
).
ENDIF.
* Save chnages to table
lo_txn_mngr->save(
* EXPORTING
* iv_transaction_pattern = /BOBF/IF_TRA_C=>GC_TP_SAVE_AND_CONTINUE " Data element for a transaction pattern
IMPORTING
ev_rejected = lv_rej " Data element for domain BOOLE: TRUE (='X') and FALSE (=' ')
* eo_change = " Interface for transaction change objects
eo_message = lo_mess " Interface of Message Object
* et_rejecting_bo_key = " Key table
).