‎2011 Aug 11 1:35 PM
Hi,
I'm implementing a BAdI to enhance a CRM datasource. I need to check if a specific field - 'Status' is present in a range of values based on which I will populate the field in the DataSource.
I've defined a RANGE table and populated the values that I would like to check for in it:
r_status type range of crm_j_stsma, "range table for status
wa_status like line of r_status, "work area for range table
populate status range table to receive entries within a range
clear r_status[].
wa_status-sign = 'I'.
wa_status-option = 'BT'.
wa_status-low = 'Z0001'.
wa_status-high = 'Z0007'.
append wa_status to r_status.
My question is, as this is constant and will be used in every iteration of each record, is there a possibility of defining this range table globally? If so, where can I define it?
Thanks,
Sri.
‎2011 Aug 12 8:23 PM
Hi,
a BAdI implementation is made of an implementing class (ABAP Objects). So, to initialize a constant, you just have to define a class attribute (aka static attribute) in this class, and you initialize it in the CLASS_CONSTRUCTOR method (that you have to create), which will be called only once implicitly by the system when the class is loaded into memory.
BR
Sandra
‎2011 Aug 11 2:00 PM
Hi Sri,
you could create a table type in DDIC and define it as range table. (TA SE11)
Regards
REA
‎2011 Aug 12 8:00 PM
Hi Sri,
You can create this range table in public section of class in BADI.If there is any INIT method in this class,fill the values in the range table.Otherwise, you can create DDIC table and use it in BADI.
Thanks,
Prasad GVK.
‎2011 Aug 12 8:23 PM
Hi,
a BAdI implementation is made of an implementing class (ABAP Objects). So, to initialize a constant, you just have to define a class attribute (aka static attribute) in this class, and you initialize it in the CLASS_CONSTRUCTOR method (that you have to create), which will be called only once implicitly by the system when the class is loaded into memory.
BR
Sandra
‎2011 Aug 15 11:25 AM
Hi REA and Prasad: Thanks for your responses. Yes, DDIC is one way of doing it. But the range table 'R_STATUS' will have different values in different BAdI implementations. Hence, it may not work for me in this instance.
Sandra: Thanks for your suggestion of static attribute in a CLASS CONSTRUCTOR. I think this should work for me. I have 'R_STATUS' range table in different implementations for different datasource enhancements. Each implementation has different values too. So, static attribute in the specific to each implementation should solve it and also improve the performance of the implementation.
Could you please provide an example of how and where to define the static attribute?
Regards,
Sri.
‎2011 Aug 15 11:35 AM
Hi
In the class generated for BADI implementation you can define an attribute (and choose STATIC option)
Now I don't know (but I suppose yes) if you have used different class for every implementation, if it's so you need to repeat the action above for every BADI
Max
‎2011 Aug 15 11:40 AM
Hey Sandra,
If it were a normal ABAP class i would definitely do it via the static CLASS_CONSTRUCTOR. But since it's a BAdI implementing class i had my reservations proposing this to the OP
I'll test it in my sandbox & check how it behaves!
Cheers,
Suhas
‎2011 Aug 15 11:40 AM
Hi Sri,
when you display a class using the class browser (through SE24, SE80, or even from the method you can start the class browser by an option in the menu Goto -> Class definition, or by a button "hierarchy" in the application toolbar), you have several tabs in the tabstrip: class properties, interfaces, attributes, methods, events, types ... I think you have to define the type first ((TYPES) mytype TYPE RANGE OF ...) then define the static attribute ((CLASS-DATA) myrange TYPE mytype).
Sandra
‎2011 Aug 15 11:52 AM
Hi
In several BADI implementation I've defined new attributes or methods in order to move some data from method to another one of the BADI, but I've always used INSTANACE attribute, because in generally only one custom implemantation is called in a standard program.
It has olways worked fine, so I'm sure a CLASS_CONSTRUCTOR will work fine, it'll be called as soon as the badi will be instanced
Max
Edited by: max bianchi on Aug 15, 2011 12:52 PM
‎2011 Aug 15 12:02 PM
Hi Max,
In several BADI implementation I've defined new attributes or methods in order to move some data from method to another one of the BADI, but I've always used INSTANACE attribute
Ditto Max!
I am not worried about old BAdIs instantiated by CL_EXITHANDLER class but for the newer ones instantiated by the GET BADI command.
Theoritically the CLASS_CONSTRUCTOR should not pose a problem. I was just curious how it behaves at runtime for these new BAdIs.
BR,
Suhas
‎2011 Aug 15 1:55 PM
Hi All,
Thanks a lot for your responses. I'm now in the Class Builder screen for the implementing class of BAdI.
I need to now create a static range table and a work area for that table:
r_status type range of crm_j_stsma, "range table for status
wa_status like line of r_status, "work area for range table
Could you please let me know where shall I create these? I've tried in the 'Attributes' tab and also 'Types' tab but there is no option to create a 'type range of' available (or am I missing something?)
Once done, I also need to enter the following values for this table:
Z0001
Z0004
Z0005
Z0007
Thanks a lot.
Regards,
Sri.
‎2011 Aug 15 2:05 PM
when you define a type in the types tab, there is a button on the right of the type to enter the type freely.
Sandra
‎2011 Aug 15 2:16 PM
Hi
You can't create that type directly in the class, but range is like a (internal) table so you should create it in dictionary.
So:
A) Create a STRUCTURE arranged like a range, 4 fields:
SIGN - Like SIGN
OPTION - Like OPTION
LOW - Like CRM_J_STSMA
HIGH - Like CRM_J_STSMA
B) Create a TABLE TYPE based on the strcuture above
After defining the TABLE TYPE in dictionary you can use it in your class in order to define the range
Now you can create the static attribute R_STATUS type the <table type above>.
The you need to define the method class_constructor to fill your range (you should see a push button in the toolbar in order to create this method)
Max
P.s.: you can also try to define a local type (instead of a dictionary type) in the class, but I don't remeber if the local type can be used for the definition of the attribute.....try
Edited by: max bianchi on Aug 15, 2011 3:18 PM
‎2011 Aug 15 2:22 PM
Hello Sri,
As Sandra has mentioned you can define class "types" freely in the class builder using the yellow button to the right of the type.
Alternatively you can go to the respective visibility section of the class(Menu->Go To ->PUBLIC, PRIVATES & PROTECTED) & define your type/data there directly.
BR,
Suhas
‎2011 Aug 15 4:05 PM
Hi,
I've created the types directly in the 'Private Section' of the implementation as:
private section.
class-data:
r_status type range of crm_j_stsma.
class-data:
wa_status like line of r_status.
And then in the actual implementation, I've entered the values:
populate status range table to receive entries within a range
clear r_status[].
wa_status-sign = 'I'.
wa_status-option = 'BT'.
wa_status-low = 'Z0001'.
wa_status-high = 'Z0007'.
append wa_status to r_status.
By doing this, I assume that the range table is created and initialised only 'once' when the implementing class is invoked.
Thanks,
Sri.
‎2011 Aug 15 4:24 PM
And then in the actual implementation, I've entered the values
...
By doing this, I assume that the range table is created and initialised only 'once' when the implementing class is invoked
By "actual implementation", you mean in CLASS_CONSTRUCTOR method? Only this one is sure to be called once.
sandra
‎2011 Aug 15 4:24 PM
I guess my code above is correct. Please confirm.
Also, can I check anywhere (debugger etc) if the 'r_status' is created only once by the implementation?
Thanks a lot.
Regards,
Sri.
‎2011 Aug 15 4:27 PM
It depends on where you've placed the code to initialize your range.
If you've implemented the method CLASS_CONSTRUCTOR, yes it'll be initialized once as soon as the BADI will be instanced,
If you've inserted it in a method of a BADI, it'll be initialized once everytime that method will be called,
Max
‎2011 Aug 15 4:27 PM
Hi Sandra,
By actual implementation I mean the method 'IF_EX_CRM_BWA_MFLOW~ENHANCE_DATA_SOURCE' and not the CLASS_CONSTRUCTOR.
Do I have to create a class constructor to ensure this is called only once?
Thanks,
Sri.
‎2011 Aug 15 4:40 PM
Sorry
but if you don't move code from the original place, the method of the BADI, where is the difference?
Just only to define your range as global data instead of a local one of the method
As Sandra says if you want to run it once you need to place it in the constructor method
Max
‎2011 Aug 15 4:46 PM
Hi All,
Yes, I've now created a Class Constructor.
So, here is what I've done:
1) In the Private section the BAdI implementation, I've defined the class-data variables:
class-data:
r_status type range of crm_j_stsma .
class-data:
wa_status like line of r_status .
2) I've created a 'Class Constructor' and initialised the values for this range table:
populate status range table to receive entries within a range
clear r_status[].
wa_status-sign = 'I'.
wa_status-option = 'BT'.
wa_status-low = 'Z0001'.
wa_status-high = 'Z0007'.
append wa_status to r_status.
I hope this should ensure that the r_status is created as a Static range table and initialised only once.
Thanks a lot for all your help.
Regards,
Sri.