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

Function Module versus Object Oriented Programming(OOP's)

Former Member
0 Likes
3,081

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.

1 ACCEPTED SOLUTION
Read only

Former Member
0 Likes
2,026
10 REPLIES 10
Read only

Former Member
0 Likes
2,025

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..

Read only

Former Member
0 Likes
2,027
Read only

uwe_schieferstein
Active Contributor
0 Likes
2,025

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 Enhancements

Thus, 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

Read only

0 Likes
2,025

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

Read only

Former Member
0 Likes
2,025

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.

Read only

0 Likes
2,025

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.

Read only

Former Member
0 Likes
2,025

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.

Read only

Former Member
0 Likes
2,025

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

Read only

RichHeilman
Developer Advocate
Developer Advocate
0 Likes
2,025

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

Read only

0 Likes
2,025

Thanks evryone for the replies. I am much better understanding now!