‎2007 Sep 04 7:01 AM
Hi ,
Can any one explain, How to design a Normal Module Pool program which contain Screen elements ( Like Table Control, Fields, Text etc ) in to Object Oriented Design. Is there any design Approach for ABAP, in which SAP Follows of the standard transaction. B'coz we have a requirement to re-design the old programs into OO programs.
Please Explain or let me know your suggestions. if there is an specific design approach send me the documents.
mail id : naganjaneyuluv@infotechsw.com
Thanks In Advance.
Regards
Nag
‎2007 Sep 04 1:15 PM
Hi There
First if you are doing OO
<b> TOTALLY FORGET THE CLASSICAL APPROACH.
There is ABSOLUTELY NO point in simply "Translating" an old program into OO.</b>
You've got an opportunity here to RE-DESIGN the applications.
If your class design is good the application programs should be really simple with only a few lines of code actually needed. (Easier to maintain as well).
What I would do is go about it this way.
1) Decide what the task you have to do is. Say it's display a sales order. This is an example of an "Instance" class -- i.e the sales order has to have an instance or a specific key --sales order number. (You can also have STATIC classes which don't need a key and work slightly differently but I find for beginners it's actually easier to visualize the concept of "an Instance" class).
2) Decide all the things you want to display in the sales order -- you can include ANYTHING you like here not just stuff in VBAK/VBAP/VBUP etc.
For example you might want to be able to see all the TEXTS associated with an order or related invoices and deliveries and the partners. You might also want to see if the invoice has been passed to accounting (FI) and whether it's been booked or not.
<b>It doesn't matter if this stuff comes from more than one SAP module ( e.g SD, FI, MM, PP) - and it's often more useful if the stuff DOES come from multiple modules.
You have to think in terms of a CLASS -- what are all the things you want to do with the Sales order. Don't think in terms of "Classical SAP transactions" such as VA03 etc or you will immediately limit yourself to doing more work later and reducing the value of the OO approach.</b>
3) Determine what you need as "The Attributes" of the sales order and what further functions you need to be able to do with the Sales Order.
The "attributes" are essentially the properties of the sales order which can be simple data or compicated tables and will be available whenever you reference that particular sales order.
Such things as quantities, material, line items, customers etc". could be considered as "attributes". You can actually use ANYTHING you like simple or complex but you need to chose carefully or you will involve system overhead each time the object is created.
The attributes are created when you first "Instantiate" the sales order i.e give it a key. The Attributes are built up in a special method which is always called the first time you call the class --its called "CONSTRUCTOR".
You don't actually call the constructor method directly -- SAP does that when you code the statement CREATE OBJECT in your application program.
So here really think what you want to be available as soon as you get your sales order class. Don't include stuff here that you don't always need or seldom need .
If you have a lot of complicated attributes the system will incur overhead in building all the required tables but this may be acceptable depending on the nature of your application.
Don't include other functions which you don't need all the time but could be useful occasionally such as characteristics of the materials in the sales order or order item texts.
You can get this stuff when you need it by calling METHODS in the class which will return this data to you.
The difference from a Function Module is that the Object (Sales Order) has already been "Instantiated" so the METHOD will return the specific data pertaining to your Sales Order. (In theory it could return totally non-related data as well but this is going against the whole idea of the CLASS and OBJECT concept).
4) Once you've done this just go into SE24 and build your class.
In the Constructor method build all the tables etc.
5) Now all you have to do is code your application program. This should be reduced to a few lines of simple code. All the complex stuff is done in the class.
Here's a short demo program using a sales order class which has some complex attributes (tables). In practice you would choose different values but this should serve as an easy demo.
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 salse 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
break-point 1.
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.
In the SALES ORDER CLASS here's an example of a constructor method to build the attributes.
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.
Rest of the methods
Method DISPLAY.
set parameter id 'AUN' field v_vbeln.
call transaction 'VA03' and skip first screen.
endmethod.
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.
Get Price conditions
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.
Get Orders for a 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.
You can make the class as complex or as simple as you want -- try and decide what you actually want to do and relate it to a real business process.
<b>Don't try and replicate a standard SAP transaction. This is MOST DEFINITELY not the way to do it.</b>
Note that your results should be displayed using an ALV GRID. This has the advantage of having a standard interface.
For simple Non editable displays you can use the simpler CL_SALV_TABLE class.
For editing data and other more complex functionality you might need with regard to entering text, scrolling, downloading to EXCEL, special event processing etc (note table controls are now redundant when you use an ALV GRID)use the class CL_GUI_ALV_GRID.
If you prefer a Tree display use that class instead.
You just need one blank screen with a custom container. Plenty of documentation on using Grids. Also look at the demo programs BCALV* on ALV GRID usage == also there's loads of threads in this Forum as well.
This approach will work for ANY application program.
For input parameters etc you can still use the old select options etc. There is no need to change these and they are still the best way to do this stuff and will continue to work in your application program.
What you need to do is essentially reduce the complexity of the calling application program to just displaying / manipulating the sales order.
Use the same ideology for any other business process.
SD and FI are the easiest areas to start with since the functionality around the core elements of these modules is relatively simple and the code hasn't been changed for ages (at least 8 - 10 years).
Note however that as SAP still (excluding CRM) relies heavily on Relational Data Bases the object (or OO) methodology is not the best to use when you have to read data from a large number of objects before processing them.
For example if using the sales order class described above say you need to access 2000 sales orders before processing then you will incurr a lot of overhead as the entire set of attributes is created for each individual sales order. This is unlikely to be a problem once genuine "persistent" objects are built in to the SAP system with an OBDMS (Object data base system instead of the current RDBMS - relational data base system where everything is stored in sets of tables with relationships between them) but will incurr a huge overhead with the current system.
So use Classes for clearly defined processes rather than large sequential data accesses.
For OO remember the golden rule for Objects is :
<b>C.R.U.D</b> (should be easy enough to remember even for non Native English speakers !!).
Create
Read
Update
Delete
<b>TIP For successful OO implementation UNLEARN STANDARD ABAP AS QUICK AS POSSIBLE AND THINK IN CLASS CONCEPTS.</b>
Cheers
Jimbo
‎2007 Sep 04 1:15 PM
Hi There
First if you are doing OO
<b> TOTALLY FORGET THE CLASSICAL APPROACH.
There is ABSOLUTELY NO point in simply "Translating" an old program into OO.</b>
You've got an opportunity here to RE-DESIGN the applications.
If your class design is good the application programs should be really simple with only a few lines of code actually needed. (Easier to maintain as well).
What I would do is go about it this way.
1) Decide what the task you have to do is. Say it's display a sales order. This is an example of an "Instance" class -- i.e the sales order has to have an instance or a specific key --sales order number. (You can also have STATIC classes which don't need a key and work slightly differently but I find for beginners it's actually easier to visualize the concept of "an Instance" class).
2) Decide all the things you want to display in the sales order -- you can include ANYTHING you like here not just stuff in VBAK/VBAP/VBUP etc.
For example you might want to be able to see all the TEXTS associated with an order or related invoices and deliveries and the partners. You might also want to see if the invoice has been passed to accounting (FI) and whether it's been booked or not.
<b>It doesn't matter if this stuff comes from more than one SAP module ( e.g SD, FI, MM, PP) - and it's often more useful if the stuff DOES come from multiple modules.
You have to think in terms of a CLASS -- what are all the things you want to do with the Sales order. Don't think in terms of "Classical SAP transactions" such as VA03 etc or you will immediately limit yourself to doing more work later and reducing the value of the OO approach.</b>
3) Determine what you need as "The Attributes" of the sales order and what further functions you need to be able to do with the Sales Order.
The "attributes" are essentially the properties of the sales order which can be simple data or compicated tables and will be available whenever you reference that particular sales order.
Such things as quantities, material, line items, customers etc". could be considered as "attributes". You can actually use ANYTHING you like simple or complex but you need to chose carefully or you will involve system overhead each time the object is created.
The attributes are created when you first "Instantiate" the sales order i.e give it a key. The Attributes are built up in a special method which is always called the first time you call the class --its called "CONSTRUCTOR".
You don't actually call the constructor method directly -- SAP does that when you code the statement CREATE OBJECT in your application program.
So here really think what you want to be available as soon as you get your sales order class. Don't include stuff here that you don't always need or seldom need .
If you have a lot of complicated attributes the system will incur overhead in building all the required tables but this may be acceptable depending on the nature of your application.
Don't include other functions which you don't need all the time but could be useful occasionally such as characteristics of the materials in the sales order or order item texts.
You can get this stuff when you need it by calling METHODS in the class which will return this data to you.
The difference from a Function Module is that the Object (Sales Order) has already been "Instantiated" so the METHOD will return the specific data pertaining to your Sales Order. (In theory it could return totally non-related data as well but this is going against the whole idea of the CLASS and OBJECT concept).
4) Once you've done this just go into SE24 and build your class.
In the Constructor method build all the tables etc.
5) Now all you have to do is code your application program. This should be reduced to a few lines of simple code. All the complex stuff is done in the class.
Here's a short demo program using a sales order class which has some complex attributes (tables). In practice you would choose different values but this should serve as an easy demo.
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 salse 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
break-point 1.
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.
In the SALES ORDER CLASS here's an example of a constructor method to build the attributes.
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.
Rest of the methods
Method DISPLAY.
set parameter id 'AUN' field v_vbeln.
call transaction 'VA03' and skip first screen.
endmethod.
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.
Get Price conditions
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.
Get Orders for a 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.
You can make the class as complex or as simple as you want -- try and decide what you actually want to do and relate it to a real business process.
<b>Don't try and replicate a standard SAP transaction. This is MOST DEFINITELY not the way to do it.</b>
Note that your results should be displayed using an ALV GRID. This has the advantage of having a standard interface.
For simple Non editable displays you can use the simpler CL_SALV_TABLE class.
For editing data and other more complex functionality you might need with regard to entering text, scrolling, downloading to EXCEL, special event processing etc (note table controls are now redundant when you use an ALV GRID)use the class CL_GUI_ALV_GRID.
If you prefer a Tree display use that class instead.
You just need one blank screen with a custom container. Plenty of documentation on using Grids. Also look at the demo programs BCALV* on ALV GRID usage == also there's loads of threads in this Forum as well.
This approach will work for ANY application program.
For input parameters etc you can still use the old select options etc. There is no need to change these and they are still the best way to do this stuff and will continue to work in your application program.
What you need to do is essentially reduce the complexity of the calling application program to just displaying / manipulating the sales order.
Use the same ideology for any other business process.
SD and FI are the easiest areas to start with since the functionality around the core elements of these modules is relatively simple and the code hasn't been changed for ages (at least 8 - 10 years).
Note however that as SAP still (excluding CRM) relies heavily on Relational Data Bases the object (or OO) methodology is not the best to use when you have to read data from a large number of objects before processing them.
For example if using the sales order class described above say you need to access 2000 sales orders before processing then you will incurr a lot of overhead as the entire set of attributes is created for each individual sales order. This is unlikely to be a problem once genuine "persistent" objects are built in to the SAP system with an OBDMS (Object data base system instead of the current RDBMS - relational data base system where everything is stored in sets of tables with relationships between them) but will incurr a huge overhead with the current system.
So use Classes for clearly defined processes rather than large sequential data accesses.
For OO remember the golden rule for Objects is :
<b>C.R.U.D</b> (should be easy enough to remember even for non Native English speakers !!).
Create
Read
Update
Delete
<b>TIP For successful OO implementation UNLEARN STANDARD ABAP AS QUICK AS POSSIBLE AND THINK IN CLASS CONCEPTS.</b>
Cheers
Jimbo
‎2007 Sep 05 9:16 PM
Hello Nag
Forget about "translating" module pools into OO programs. By the way, module pools are out-of-date. I have not used them for more than 5 years.
The (re-)design approach should be to think in terms of <b>responsibilities </b>and how these responsibilites are distributed among clearly different objects.
Last year I had to develop a customer report dealing with the transfer of CATS data of the employees to assessment cycles (Controlling, transaction KSU3). While the program looks like a report I entirely realized it in classes (with an OO-transaction). The screens I needed were placed in a function group.
Based on the function specification I could identify the following objects:
- Object for handling CATS data (CL_DBSEL_CATS)
- Employee (created own class having <a href="https://wiki.sdn.sap.com/wiki/display/Snippets/UnifiedAccesstoAllHR+Infotypes">CL_PT_EMPLOYEE</a> as instance attribute)
- Assessment cycle
- Cost center group hierarchy
- Exception class (dealing with ignoring CATS records at certain conditions)
The "report" itself was realized using a MVC-model approach:
- a Model class which orchestrated everything (corresponding to the classical report)
- a View class which was responsible for displaying the ALV lists and receiving user input
- a Controller class reacting on user input
Using this approach I could find several spots of misplaced coding, e.g. within the model class I found coding dealing with employee details. This coding was shifted to where it belonged (employee class) and a method added to provide access to this data for the model class.
A very nice example of responsibilities can be seen in my Wiki posting
<a href="https://wiki.sdn.sap.com/wiki/display/profile/2007/07/09/UnderstandingABAPObjects">Understanding ABAP Objects</a>
Regards
Uwe