‎2007 May 22 5:21 PM
Hi All,
I was recently thiking about why should i use Function Modules when i can as well work with OOPs concept? Can we do without Function Module? In which scenarios would we prefer a Function Module and why?
Kindly please answer the above questions. I have been confused about ths for quite some time.
Thanks and Regards.
Note: I shall reward all answers which i find helpful.
‎2007 May 22 6:07 PM
Hi,
Go through this link,
http://help.sap.com/saphelp_47x200/helpdata/en/c3/225b5954f411d194a60000e8353423/content.htm
Regards,
Azaz Ali.
‎2007 May 22 5:30 PM
Gayatri,
you are correct,
but sap is introducing OOPs concepet recently , where as there are lot of pre defined function modules existing from beggining. So instead of writing the code again with OOPs its better to go with the existing function modules rite...
It saves lot of time not only that those are sap provided standard function modules you will not get much problems..
‎2007 May 22 6:07 PM
Hi,
Go through this link,
http://help.sap.com/saphelp_47x200/helpdata/en/c3/225b5954f411d194a60000e8353423/content.htm
Regards,
Azaz Ali.
‎2007 May 22 9:26 PM
Hello Gayatri
When I am in need of a functionality where I believe the SAP standard provides this "service" (either as function module or class method) I look
- first for class methods and
- then for function modules
Why? In many cases the classes are more powerful and versatile then the corresponding function modules.
I will give you an example: for reading timesheet data (table CATSDB) we can use either
- BAPI <b>BAPI_CATIMESHEETRECORD_GETLIST</b> or the
- class <b>CL_DBSEL_CATS</b>.
<b>Selection Criteria</b>
The BAPI allows the following selection criteria:
- FROMDATE, TODATE, employees
The CONSTRUCTOR method of class CL_DBSEL_CATS has the following interface:
IM_CALLING_PROGRAM Calling Program
IM_AUTHORITY_CHECK_TYPE Authorization Check R=Reporting, E=Change, D=Approve
IM_FIELD_SELECTION Field Names for DB Seln. Corresponds to GET CATSDB FIELDS ..
IM_SELECTION_CRITERIA Selection Criteria for CATSDB Selection
IM_FREE_SELECTIONS Free Selections for Database Fields
IM_BADI BADI for Customer EnhancementsThus, we can either define multiple selection criteria of our own (using parameters IM_SELECTION_CRITERIA and IM_FREE_SELECTIONS) or we can "link" the selection screen of a report to this class (IM_CALLING_PROGRAM).
In addition, parameter IM_BADI further allows us to modify the selection if necessary.
<b>Authorization Checks</b>
The BAPI strictly checks for 'Reporting' authorization whereas the class allows us to define different authorization levels (using parameter IM_AUTHORITY_CHECK_TYPE: Authorization Check R=Reporting, E=Change, D=Approve)
<b>Messages</b>
If the user does not have 'Reporting' authorization the BAPI simply skips the record:
...
LOOP AT ICATSDB.
MOVE SY-TABIX TO L_TABIX.
CALL FUNCTION 'CATS_CHECK_AUTHORITY'
EXPORTING
PERNR = ICATSDB-PERNR
DATE = ICATSDB-WORKDATE
ACTION = 'R'
EXCEPTIONS
PERNR_NOT_FOUND = 1
INVALID_ACTION = 2
NO_AUTHORITY = 3
OTHERS = 4.
IF SY-SUBRC <> 0.
CONTINUE.
ENDIF.
...In contrast, method GET_REJECT_COUNT returns the Number of Records Skipped Due to Authorization Problems.
I hope you will understand now why it is worth to spend some time and search for the most appropriate classes to realize out applications.
Regards
Uwe
‎2008 Apr 24 12:37 PM
Hi Uwe Schieferstein,
I am really impressed with your answer for the post "Function Module versus Object Oriented Programming(OOP's)".
In this answer you have mentioned following example which says
for reading timesheet data (table CATSDB), we can use either
BAPI BAPI_CATIMESHEETRECORD_GETLIST or the
class CL_DBSEL_CATS.
Well I am totally new to ABAP, so i surprised how can we find a particular BAPI or a CLASS for our relative work?
Can you help in this matter that how can I find any BAPI or CLASS in effectively fast manner?
VIKRANT
‎2007 May 23 5:41 AM
Hi Uwe,
Thanks for the reply. IT has definetely helped me a lot.
Form what you have written.. Classes are definetley more powerful than FM.
Does this mean that Function Modules will be redundant going forward? or are there palces we would still need Function Modules ?
If yes, can you please kindly let me know in which scenarios?
Thanks and Regards,
Soumya.
‎2007 May 23 7:06 AM
Hi,
If you are writing any custom functionality for your requirement, the existing methods not enough to give solutions, in that case, you will introduce FM, in that you can use classes and methods.
Regards,
Ramki.
‎2007 May 23 9:48 AM
Hi Soumya,
Please try to understand that apparently Function Groups and classes are somewhat similar.
Function Groups - > Data + Function Modules
Class -> Data + Methods
Both support encapsulation i.e. data(if defined as private in class) can only be accessed by the methods / function modules of class/function group.
But the area of use of class and function group is different. If you need to simulate a real life scenario where in you require to create several runtime instances of a real world entity, then we cannot use Function groups and have to use classes beacuse class has the property of mutiple instantiation.
But if you need to deal with only one instance then you can use function group.
It is very important to design an object oriented solution and see if it is at all required before writng a piece of code in object oriented manner.
Award points if found useful.
Regards
Indrajit.
‎2007 May 24 12:08 AM
OO is really easy.
All you need to do in your program is just instantiate the object (assuming an Instance type method / attribute) and then you've got ALL the data.
If you need extra methods / attributes you can just define a subclass inheriting EVERYTHING from the main class. So you only need to add your method / attribute coding.
For example say I've got a class ZCL_SALES_ORDER
Build the following via SE24
class ZCL_SALES_ORDER definition
public
final
create public .
" public components of class ZCL_SALES_ORDER
" do not include other source files here!!!
public section.
types:
begin of s_material,
matnr type vbap-matnr,
arktx type vbap-matkl,
kwmeng type vbap-kwmeng,
vrkme type vbap-vrkme,
netwr type vbap-netwr,
end of s_material .
types:
begin of s_partner,
vbeln type vbpa-vbeln,
parvw type vbpa-parvw,
kunnr type vbpa-kunnr,
lifnr type vbpa-lifnr,
pernr type vbpa-pernr,
parnr type vbpa-parnr,
adrnr type vbpa-adrnr,
name1 type sadr-name1,
stras type sadr-stras,
pstlz type sadr-pstlz,
ort01 type sadr-ort01,
end of s_partner .
types:
begin of s_prices,
kschl type konv-kschl,
kbetr type konv-kbetr,
krech type konv-krech,
kpein type konv-kpein,
kmein type konv-kmein,
kwert type konv-kwert,
vtext type t685t-vtext,
end of s_prices .
types:
begin of s_texts,
tdid type stxh-tdid,
lines type lines,
end of s_texts .
types:
begin of s_textids,
tdid type stxh-tdid,
end of s_textids .
types:
begin of s_matord,
matnr type vbap-matnr,
arktx type vbap-arktx,
kunnr type vapma-kunnr,
vbeln type vapma-vbeln,
posnr type vapma-posnr,
audat type vapma-audat,
auart type vapma-auart,
kwmeng type vbap-kwmeng,
vrkme type vbap-vrkme,
netwr type vbap-netwr,
end of s_matord .
types:
zdog type standard table of vbap .
types:
zprices type standard table of s_prices .
types:
zmat type standard table of s_material .
types:
zpartner type standard table of s_partner .
types:
zlines type standard table of tline .
types:
ztexts type standard table of s_texts .
types:
zvbfa type standard table of vbfa .
types:
zmatord type standard table of s_matord .
data V_VBELN type VBAK-VBELN .
data PARTNERS type ZPARTNER .
data MATERIALS type ZMAT .
data POSITIONS type ZDOG .
data DOCFLOW type ZVBFA .
methods CONSTRUCTOR
importing
!VBELN type VBAK-VBELN .
methods DISPLAY .
methods GET_SALES_HEADER_TEXTS
importing
!VBELN type VBAP-VBELN
!POSNR type VBAP-POSNR
exporting
!TEXTS type ZTEXTS .
class-methods GET_CONDITIONS
importing
!VBELN type VBAK-VBELN
!POSNR type VBAP-POSNR
exporting
!PRICES type ZPRICES .
class-methods GET_ORDERS_FOR_MATERIAL
importing
!MATERIAL type VAPMA-MATNR
exporting
!MATORD type ZMATORD .
Methods
Constructor (Fills the attributes on instantiation)
method CONSTRUCTOR.
we can fill the (instance) attributes in this method.
*
Demo Get line items and partners
data S_PARTNERS type S_PARTNER .
data S_NR type VBPA-KUNNR .
data S_ADRNR type KNA1-ADRNR .
data S_ADDR1 type ADDR1_SEL .
data OLD_FORMAT type VBADR .
data KNVK_WA type KNVK .
data S_SADR type SADR .
data POS type VBAP .
data DOCTYP type VBUK-VBTYP .
data VBCO6 type VBCO6 .
data MAT type S_MATERIAL .
v_vbeln = vbeln.
select * from vbap
into table positions
where vbeln = v_vbeln.
loop at positions into pos..
move-corresponding pos to mat.
append mat to materials.
endloop.
Document flow
clear vbco6.
vbco6-vbeln = V_vbeln.
CALL FUNCTION 'RV_ORDER_FLOW_INFORMATION'
EXPORTING
COMWA = vbco6
IMPORTING
BELEGTYP_BACK = doctyp
TABLES
VBFA_TAB = docflow
EXCEPTIONS
NO_VBFA = 1
NO_VBUK_FOUND = 2
OTHERS = 3 .
.
IF SY-SUBRC <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
select * from vbpa
into corresponding fields of table partners
where vbeln = v_vbeln.
get address numbers
loop at partners into s_partners.
if s_partners-pernr is initial.
clear s_nr.
clear s_adrnr.
if not s_partners-kunnr is initial.
s_nr = s_partners-kunnr.
select single adrnr from kna1
into s_adrnr
where kunnr eq s_partners-kunnr.
s_partners-adrnr = s_adrnr.
endif.
if not s_partners-lifnr is initial.
s_nr = s_partners-lifnr.
select single adrnr from lfa1
into s_adrnr
where lifnr eq s_partners-lifnr.
endif.
if s_partners-parvw = 'EK'.
s_nr = s_partners-adrnr.
s_adrnr = s_partners-adrnr.
endif.
if not s_partners-pernr is initial.
s_nr = s_partners-pernr.
endif.
if not s_adrnr is initial.
s_addr1-addrnumber = s_adrnr.
CALL FUNCTION 'ADDR_GET'
EXPORTING
ADDRESS_SELECTION = s_addr1
IMPORTING
SADR = s_sadr.
.
IF SY-SUBRC <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
move-corresponding s_sadr to s_partners.
endif.
modify partners from s_partners.
else.
get address from personnel number
Note this way of retrieving the address is likely to be
deprecated in the future
You should really get it via the appropriate infotype
and new BAS services.
clear old_format.
CALL FUNCTION 'VIEW_VBADR'
EXPORTING
NRART = 'PE'
PARTNERNUMMER = s_partners-pernr
IMPORTING
ADRESSE = OLD_FORMAT
EXCEPTIONS
ERROR = 1
OTHERS = 2
.
IF SY-SUBRC <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
move-corresponding old_format to s_partners.
modify partners from s_partners.
endif.
endloop.
endmethod.
* method Display
method DISPLAY.
set parameter id 'AUN' field v_vbeln.
call transaction 'VA03' and skip first screen.
endmethod.
* method Get sales order texts
method GET_SALES_HEADER_TEXTS.
types:
t_stxh type standard table of stxh.
data: spras type THEAD-TDSPRAS,
t_lines type standard table of tline,
s_lines type tline,
name type thead-tdname,
s_textid type stxh-tdid,
t_textid type table of s_textids,
t_texts type table of s_texts,
q_texts type s_texts,
object type THEAD-TDOBJECT.
field-symbols <g_texts> type any.
assign q_texts to <g_texts>.
object = 'VBBP'. "Item text"
clear name.
if not posnr is initial.
concatenate v_vbeln posnr into name.
else.
name = v_vbeln.
endif.
select tdid from stxh
into table t_textid
where tdobject = object
and tdname = name.
spras = 'N'.
loop at t_textid into s_textid.
CALL FUNCTION 'READ_TEXT'
EXPORTING
ID = s_textid
LANGUAGE = spras
NAME = name
OBJECT = object
TABLES
LINES = t_lines.
.
IF SY-SUBRC <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
loop at t_lines into s_lines.
q_texts-tdid = s_textid.
q_texts-lines = s_lines-tdline.
append q_texts to t_texts.
endloop.
endloop.
texts[] = t_texts[].
endmethod.
* Method get_conditions ( pricing )
method GET_CONDITIONS.
data: t_prices type standard table of s_prices,
l_prices type s_prices.
data g_knumv type vbak-knumv.
select single knumv
into g_knumv
from vbak
where vbeln eq vbeln.
select kschl kbetr krech kpein kmein kwert
into corresponding fields of table t_prices
from konv
where knumv = g_knumv
and kposn eq posnr.
loop at t_prices into l_prices.
select single vtext into l_prices-vtext
from t685t
where kappl = 'V'
and spras eq sy-langu
and kschl = l_prices-kschl.
modify t_prices from l_prices index sy-tabix.
endloop.
prices[] = t_prices[].
endmethod.
* Method get_orders_for_material
method GET_ORDERS_FOR_MATERIAL.
data: t_matord type standard table of s_matord,
l_matord type s_matord.
select amatnr aauart avbeln aposnr aaudat akunnr
barktx bkwmeng bvrkme bnetwr
into corresponding fields of table t_matord
from ( vapma as a
inner join vbap as b
on avbeln eq bvbeln
and aposnr eq bposnr )
where a~matnr eq material.
matord[] = t_matord[].
endmethod.
Now once the order is instantiated everything is available as per this demo program.
program ZCLASSSALESORD.
*Demo calling sales order class
parameters : p_vbeln like vbap-vbeln obligatory.
data : obj type ref to zcl_sales_order. "Ref to class
types: begin of s_texts,
tdid type stxh-tdid,
lines type lines,
end of s_texts,
begin of s_prices,
kschl type konv-kschl,
kbetr type konv-kbetr,
krech type konv-krech,
kpein type konv-kpein,
kmein type konv-kmein,
kwert type konv-kwert,
vtext type t685t-vtext,
end of s_prices .
data:
t_lines type standard table of s_texts,
t_prices type standard table of s_prices,
s_lines type s_texts,
s_vbap type vbap,
objtyp type thead-tdobject,
ziid type stxh-tdid.
field-symbols: <g_partners> type table,
<g_positions> type table,
<g_lines> type table,
<g_materials> type table,
<g_documents> type table,
<g_prices> type table,
<g_salesdoc>.
Instantiate our Sales order from parameter
create object obj exporting vbeln = p_vbeln.
access the attributes in the sales order class
to access attributes in class just code oref->attribute
*
assign obj->partners to <g_partners>. "Partner addresses
assign obj->positions to <g_positions>. "Line items
assign obj->v_vbeln to <g_salesdoc>. "Sales Doc number
assign obj->materials to <g_materials>. "Material list
assign obj->docflow to <g_documents>. "Document flow
Now test get long text from line item
loop at <g_positions> into s_vbap.
assign t_lines to <g_lines>.
call method obj->get_sales_header_texts
exporting
vbeln = p_vbeln
posnr = s_vbap-posnr
importing
texts = <g_lines>.
loop at <g_lines> into s_lines.
write : / s_lines-tdid, s_lines-lines(80).
endloop.
endloop.
assign t_prices to <g_prices>.
call method obj->get_conditions
exporting
vbeln = p_vbeln
posnr = s_vbap-posnr
importing
prices = <g_prices>.
break-point 2.
It's a lot easier in any case to code in an ABAP this sort of stuff
<b>
Instantiate our Sales order from parameter
data : obj type ref to zcl_sales_order. "Ref to class
create object obj exporting vbeln = p_vbeln.
attributes of Sales Order class
assign obj->partners to <g_partners>. "Partner addresses
assign obj->positions to <g_positions>. "Line items
assign obj->v_vbeln to <g_salesdoc>. "Sales Doc number
assign obj->materials to <g_materials>. "Material list
assign obj->docflow to <g_documents>. "Document flow</b>
rather than mess around with function modules. The code within the method is totally separate from the caller as well.
If I have several sales orders (multiple instances) I can still use the same code by just instantiating the sales order class (create object xxx). Then to get attributes / methods I can use exactly the same code on the new object. (Multiple instances).
Function modules are not designed to be handled by multiple instances. Function modules are OK when you are dealing with a single instance and the code isn't too complex. Also for a while SAP has a load of function modules for which classes aren't available yet --but this will change in the near future.
Now if I need some other data -- for example say Invoices for orders I can just add a method using most of the data I've already got from the existing class (Inheritance). In other words a new class can refer to to an existing class as a "Super Class".
Polymorphism is also another extremely powerful OO concept where you can have identically named methods which behave differently in different classes.
In other words you can have the same method in different child classes but each with a different implementation.
Both the above concepts allow for code re-use and drastically cut development time provided the class structure has been properly thought out and implemented.
Also the scope for programming errors is very much reduced. Coding time is cut significantly as you now only need to worry about the actual business function.
Now all you need to do in the application program is to instantiate an object, define some event handlers, get the attributes / call any relevant methods and produce any required output.
Using a Function Module I'd probably have to re-read a whole slew of data I've already got from the Sales Order Attributes anyway.
(Business objects -- transaction SWO1) were a sort of start to OO abap but genuine classes are the way forward --even in workflow scenarios (rel 6.40 and up).
If you've ever used SWO1 in TEST mode you can see that Business objects also had a load of useful functionality but weren't actually used so much in ordinary ABAP.
OO actually deprecates a lot of the business object stuff so any workflow guys out there you had better get used to OO.
SE24 in test mode gives a similar output to SWO1.
There's so many advantages to using classes that I'm surprised how a lot of shops still won't allow this sort of stuff into production yet even on releases >= 6.40 (Probably old IBM mainframe COBOL programmers).
Cheers
jimbo
‎2007 May 24 2:42 AM
Just to reiterate what others have said, the use of OO moving foward will become more and more important, notice that with Web Dynpro ABAP, it is all OO, but also understand that function modules still have there place. For example, the use of function modules and LUW. Meaning firing a function module in another work process or in an update task. THis kind of thing is not supported by classes, so if you have such a requirement, then a function module is the way to go.
Regards,
RIch Heilman
‎2007 May 24 5:58 AM
Thanks evryone for the replies. I am much better understanding now!