SALV Editable? Yes, as per this Standard SAP Application
Don’t get too excited about the editable SALV solution out of the box, but I think we have a solution.
Recently Paul Hardy published a blog International Editable SALV day as the 8th anniversary of the first SALV Editable question and so far no out of the box solution. To those who hasn’t read the previous so many discussion, out of box solution means a single method to make it editable. As of ABAP 740 SP05, there isn’t any new method in SALV OM which does the same thing or at least sounds like SET_EDITABLE.
I developed an work around in November 2008 and got lot of criticism for that. You can see the solution and read the comments – Power of ABAP Objects: Overcome the Restrictions of SALV Model
Based on the comments, customers should never use these type of workarounds. Obviously, SAP must not use the work around as they say Editable is not intended purpose of SALV OM. But, look what I found >> Standard SAP (yes, standard SAP) has used the almost similar approach to make SALV editable which I used in my solution.
Standard SAP Application
I was replying to some query on CL_SALV_TREE and I did a where used on the adapter object and stumbled upon this function group FOT_RFD_MONI. Usually the adapter is used by only CL_SALV* Classes and my test program. But, suddenly I see a new program popping up in the where used list and that kept me thinking what is this program doing here?
This standard SAP application is developed using this approach – almost same as the approach used in my solution. (Note, that I’m not calling it a workaround anymore 😉 ):
- Inherit the class from the Model class
- Create a method in the inherited class to gain access to the Adapter object – E.g. Grid, Fullscreen, Tree
- Gain access of the underlying object – Grid or Tree
Class definition
Class Implementation
Use of method to make Grid editable / non-editable
Redefined Solution
So, based on this design, I simplified my version of the approach. Created a custom class where I have couple of helper methods to gain access to the adapter and then the underlying object – either Grid or Tree.
- GET_GRID would be used to get the CL_GUI_ALV_GRID object
- GET_TREE would be used to get the CL_GUI_ALV_TREE object
Utility Class
* CLASS ZCL_TEST_NP_SALV_MODEL DEFINITION
*———————————————————————-*
*
*———————————————————————-*
CLASS zcl_test_np_salv_model DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS get_grid
IMPORTING
!io_salv_model TYPE REF TO cl_salv_model
RETURNING
value(eo_grid) TYPE REF TO cl_gui_alv_grid
RAISING
cx_salv_error .
CLASS-METHODS get_tree
IMPORTING
!io_salv_model TYPE REF TO cl_salv_model
RETURNING
value(ro_tree) TYPE REF TO cl_gui_alv_tree
RAISING
cx_salv_error .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS ZCL_TEST_NP_SALV_MODEL IMPLEMENTATION.
* <SIGNATURE>—————————————————————————————+
* | Static Public Method ZCL_TEST_NP_SALV_MODEL=>GET_GRID
* +————————————————————————————————-+
* | [—>] IO_SALV_MODEL TYPE REF TO CL_SALV_MODEL
* | [<-()] EO_GRID TYPE REF TO CL_GUI_ALV_GRID
* | [!CX!] CX_SALV_ERROR
* +————————————————————————————–</SIGNATURE>
METHOD get_grid.
DATA: lo_error TYPE REF TO cx_salv_msg.
IF io_salv_model->model NE if_salv_c_model=>table.
RAISE EXCEPTION TYPE cx_salv_msg
EXPORTING
msgid = ’00’
msgno = ‘001’
msgty = ‘E’
msgv1 = ‘Incorrect SALV Type’.
ENDIF.
eo_grid = lcl_salv_model_list=>get_grid( io_salv_model ).
ENDMETHOD. “get_grid
* <SIGNATURE>—————————————————————————————+
* | Static Public Method ZCL_TEST_NP_SALV_MODEL=>GET_TREE
* +————————————————————————————————-+
* | [—>] IO_SALV_MODEL TYPE REF TO CL_SALV_MODEL
* | [<-()] RO_TREE TYPE REF TO CL_GUI_ALV_TREE
* | [!CX!] CX_SALV_ERROR
* +————————————————————————————–</SIGNATURE>
METHOD get_tree.
DATA: lo_error TYPE REF TO cx_salv_msg.
IF io_salv_model->model NE if_salv_c_model=>tree.
RAISE EXCEPTION TYPE cx_salv_msg
EXPORTING
msgid = ’00’
msgno = ‘001’
msgty = ‘E’
msgv1 = ‘Incorrect SALV Type’.
ENDIF.
ro_tree = lcl_salv_model_list=>get_tree( io_salv_model ).
ENDMETHOD. “GET_TREE
ENDCLASS.
To get the CL_GUI_ALV_GRID:
DATA: lo_msg TYPE REF TO cx_salv_msg.
TRY .
lo_grid = zcl_test_np_salv_model=>get_grid( o_salv ).
CATCH cx_salv_msg INTO lo_msg.
“appropriate handling
ENDTRY.
Local class LCL_SALV_MODEL_LIST which is inherited from CL_SALV_MODEL_BASE. Previously, I used the CL_SALV_MODEL_LIST to inherit my helper class, which wouldn’t provide me the instance for the TREE. Thus, moved higher in the class hierarchy.
*”* local helper classes, interface definitions and type
*”* declarations
*
CLASS lcl_salv_model_list DEFINITION INHERITING FROM cl_salv_model_base.
PUBLIC SECTION.
CLASS-METHODS:
get_grid
IMPORTING
io_salv_model TYPE REF TO cl_salv_model
RETURNING
value(ro_gui_alv_grid) TYPE REF TO cl_gui_alv_grid
RAISING
cx_salv_msg,
get_tree
IMPORTING
io_salv_model TYPE REF TO cl_salv_model
RETURNING
value(ro_tree) TYPE REF TO cl_gui_alv_tree
RAISING
cx_salv_msg.
ENDCLASS. “lcl_salv_model_list DEFINITION
*
CLASS lcl_salv_model_list IMPLEMENTATION.
METHOD get_grid.
DATA:
lo_grid_adap TYPE REF TO cl_salv_grid_adapter,
lo_fs_adap TYPE REF TO cl_salv_fullscreen_adapter,
lo_root TYPE REF TO cx_root.
TRY .
lo_grid_adap ?= io_salv_model->r_controller->r_adapter.
CATCH cx_root INTO lo_root.
“could be fullscreen adaptper
TRY .
lo_fs_adap ?= io_salv_model->r_controller->r_adapter.
CATCH cx_root INTO lo_root.
RAISE EXCEPTION TYPE cx_salv_msg
EXPORTING
previous = lo_root
msgid = ’00’
msgno = ‘001’
msgty = ‘E’
msgv1 = ‘Check PREVIOUS exception’.
ENDTRY.
ENDTRY.
IF lo_grid_adap IS NOT INITIAL.
ro_gui_alv_grid = lo_grid_adap->get_grid( ).
ELSEIF lo_fs_adap IS NOT INITIAL.
ro_gui_alv_grid = lo_fs_adap->get_grid( ).
ELSE.
RAISE EXCEPTION TYPE cx_salv_msg
EXPORTING
msgid = ’00’
msgno = ‘001’
msgty = ‘W’
msgv1 = ‘Adapter is not bound yet’.
ENDIF.
ENDMETHOD. “get_grid
METHOD get_tree.
DATA:
lo_tree_adap TYPE REF TO cl_salv_tree_adapter,
lo_root TYPE REF TO cx_root.
TRY .
lo_tree_adap ?= io_salv_model->r_controller->r_adapter.
CATCH cx_root INTO lo_root.
RAISE EXCEPTION TYPE cx_salv_msg
EXPORTING
previous = lo_root
msgid = ’00’
msgno = ‘001’
msgty = ‘E’
msgv1 = ‘Check PREVIOUS exception’.
ENDTRY.
IF lo_tree_adap IS NOT BOUND.
RAISE EXCEPTION TYPE cx_salv_msg
EXPORTING
msgid = ’00’
msgno = ‘001’
msgty = ‘W’
msgv1 = ‘Adapter is not bound yet’.
ENDIF.
ro_tree = lo_tree_adap->r_tree.
ENDMETHOD. “get_tree
ENDCLASS. “lcl_salv_model_list IMPLEMENTATION
To get the CL_GUI_ALV_TREE:
TRY .
lo_tree = zcl_test_np_salv_model=>get_tree( gr_tree ).
CATCH cx_salv_msg.
ENDTRY.
Updated version of the ON_USER_COMMAND method in the original solution Power of ABAP Objects: Overcome the Restrictions of SALV Model
DATA: lo_grid TYPE REF TO cl_gui_alv_grid.
DATA: ls_layout TYPE lvc_s_layo.
CASE e_salv_function.
* Make ALV as Editable ALV
WHEN ‘MYFUNCTION’.
*>>
TRY .
lo_grid = zcl_test_np_salv_model=>get_grid( lo_report->o_salv ).
CATCH cx_salv_msg.
ENDTRY.
*<<
IF lo_grid IS BOUND.
* Editable ALV
ls_layout–edit = ‘X’.
* Set the front layout of ALV
CALL METHOD lo_grid->set_frontend_layout
EXPORTING
is_layout = ls_layout.
* refresh the table
CALL METHOD lo_grid->refresh_table_display.
ENDIF.
ENDCASE.
ENDMETHOD. “on_user_command
Questions are …
These also raises to these questions:
- Is SAP not planning to have SET_EDITABLE method in OM as they have started using this approach?
- Would SAP now provide support if customer uses the same approach and run into issues?
- If no, than how come SAP approved this design to exist it in customer’s system?
- If yes, As you can see, the application was created in somewhere 2011 by SAP. So, the developer must be aware of the existence of my solution. Shouldn’t I get at least a some credit? Not that I want, but would be good to have, 😉
Please share your thoughts…
updated on 23-Jun-15 at 8:30 AM CST to add the missing local class
Excellent finding, Naimesh!
Yes, they should give you credit. and yes, they should support this solution (actually they should make SALV editable already 🙁 )
Cheers,
Custodio
Well,
Don't be too optimistic.
I guess that this is just a case of one independent SAP Developer who read your blog 😉
Great stuff. I didn't see your original blog at the time, but I've read it now, and I disagree with the nay-sayers. The fact is that if you're using this or your other solution (not workaround!), I find it very hard to see how you could break anything standard. And since SAP don't support anything custom you write anyway - what's the problem?
In the real world, we're using and reusing SAP classes all over the place. If they were never designed to work in the way that we're using them... then perhaps that's design issue - not customer misbehaviour! If you don't intend us to use your classes in a particular way, then you should have written them so we couldn't.
Decently written classes are extendable safely (pathalogical use notwithstanding). I can imagine the Java or C++ communities' response to a complaint that you're not using their libraries the way you want them to!
Agree that they shouldn't allow us - customers or even the internal SAP developers - if the class library is not supposed to be used by "others". Certainly that's not the case with this library.
SAP doesn't support the custom development but they have to at least entertain the customers query when customer is using the so called "released" function modules / classes. For few giant customers, they have to respond to the customer message even customer uses "unreleased" approach. I guess, they want to avoid the load of tickets created by this type of solutions by giving early (false) warnings - "this is not intended use", "we will not support", etc.
Glad you get a chance to read through the original blog.
Regards,
Naimesh Patel
It's true for editable SALV case, but could be dangerous if some reckless programmer use same argument to justify a direct update in a standard table.
Two points:
1. good oo-design should minimise the chance of class misuse (which is the main thrust of my argument and not applicable to directly updating database tables).
2. if you choose to use classes for purposes not designed, unreleased function modules or update tables directly, SAP do not have to support you. (This is counter to the argument presented by the SAP dev team, who said that people will come running to them when it doesn't work). Unless you're updating SAP tables (using SAP classes, FM or directly), you're unlikely to screw anything up that you can't fix yourself.
It occurs to me that SAP programmers are "real" people also. They experiment with things, they read the blogs on the SCN and no doubt use some of the things they read there as indeed I do.
Some SAP developers are also are clearly interns out on their first day with no training provided and no testing of the code they write before it goes into production, clearly the ones who wrote the original release of SAP GUI 740 fall into that category, as did the developers who did the OSS note to enable account assignment on GR for purchase orders with multiple account assignment. That OSS note code mixed up BUKRS and WERKS and put the value for one into the other, and oh dear, the end result was not too good. It would have worked in an IDES system as both BUKRS and WERKS would have both had the value 1000, but not in any "customer" system.
When the code exchange was hosted on SCN SAP reserved the right to use anything put there in the standard product and indeed did so with some JSON handling classes, which surprised (and probably flattered) the original author. He was happy as the SAP developer just copied the classes wholesale using SAPLINK and did not realise the author had a dummy method in one class with just a sort of copyright message in comments saying he had written the class in the first place.
Anyway, the point is that SAP developers are no doubt just as frustrated as us "customer" programmers that the SALV is not editable and seek to work around this in the same way all the companies running SAP do.
Thus I extend the comment I made recently:-
"If a rule made by SAP is broken by all the companies using SAP, and internally by SAP developers i.e. the rule is broken by 100% of people, maybe it is time to look at the logic behind the rule?".
But it won't happen. On the 9th anniversary I will be posting another blog commerating the fact of the non-event.
In the interim I will be beefing up my work-around to try and use the techniques you use above.
The question I would have is this - have you found a way to open a SALV screen in editable mode? Thus far I have always had to open it in read only mode, and then have a button for the user to press to make it editable.
If I could solve that problem I would never need to use CL_GUI_ALV_GRID directly again.
Cheersy Cheers
Paul
SAP developers would even ask some silly questions. I would be surprised to see the question content and the SAP logo next to the name. So, either as you suggested they are interns and don’t have any on the job training, or SAP doesn’t have any Quality Assurance.
Earlier I thought SAP has rigorous check-up, performance tuning, code cleanup, before they ship the code to customers. But now I know that they don’t even follow the standards which we follow at customers. In one DSD solution, there are many SELECT * FROM BSAD, BSID and being executed recurring time. The funny thing, is they don’t even need all 250+ fields as they only are interested in checking if there is any open item or any payment already posted for this customer. Certainly this type of code would have been only tested in IDES and SAP would have decided to include that in the next support pack / upgrade. Customer would have thought the new support pack is great (as SAP advertise) and boy oh boy, they would end up miserably using that. So, ultimately would end up ditching that or enhancing to the certain extend that there wont be a standard call anymore.
The developer of that JSON handling class would be happy as his creation is now part of standard. But he might not had been criticize to create that solution as I had been for this .. Anyways, I think only the out-of-box solution would put an end to this.
Regarding making SALV directly editable, I have few ideas. Let me run them through and would let you know how it goes.
Regards,
Naimesh Patel
I thought the QA department was named "Ramp-up customers" or "Early adopters". 😉 And while to be absolutely fair, much of SAP own code is very well written and designed (especially when you take into account the historical imperatives), there are some really doozies. I remember interviewing a chap and asking how he would improve his own coding. "By looking at SAP standard", he replied. "Oh dear" I thought... 😈
Hi Naimesh,
At what point should someone choose to use a "Implicit enhancement"?
If OK to implement, all you need is to have a few lines of code inserted at the end of CL_SALV_CONTROLLER_METADATA=>GET_SLIS_LAYOUT method, to say S_LAYOUT-EDIT = 'X', correct? That will make the SALV editable directly, without having to go through all this trouble.
Thanks,
Juwin
I think its more than just changing the S_LAYOUT-EDIT = 'X' to make it editable in the method GET_SLIS_LAYOUT. Alongwith this, you would need to make sure toolbar appears with all the required buttons. Also, all required events are registered to handle the changes.
You would need to replicate the similar enhancements for the Grid as the SLIS* methods would only get executed for the Fullscreen ALV. For GRID, the methods would be LVC*
Gaining access to the underlying object (GRID or TREE) allows you to do many other things, like add a wallpaper to the header, register extra events (NODE_CONTEXT_MENU_REQUEST and ITEM_CONTEXT_MENU_REQUEST) for tree.
I would refrain from using the implicit enhancements within the "helper" methods of the SALV OM models, as the architecture may change and enhancement wont be executed anymore. That would be also apply to this approach of gaining access -- but I guess it would at least raise syntax error, if that happens.
Regards,
Naimesh Patel
Hi Naimesh,
I just changed the value of this field to X in debug mode and it gives me what I want - ALV in edit mode, with SAVE, and BACK buttons enabled. Whenever I make changes, press SAVE and clicks BACK, whatever changes I did on the screen, where passed back to the program.
Toolbar can be activated by calling CL_SALV_TABLE->GET_FUNCTIONS( )->SET_ALL( ABAP_TRUE ), correct?
So, which event am I missing?
I understand that access to underlying object gives much more capabilities.
Thanks,
Juwin
Dont have normal "Edit" buttons when using the S_LAYOUT-EDIT = 'X'.
But, have all of them using my approach:
How are you handing event DATA_CHANGED to validate the entries by changing the only S_LAYOUT?
Regards,
Naimesh Patel
Hi Naimesh,
You are right, I don't get DATA_CHANGED event, and the buttons.
Thanks,
Juwin
I didn't try, but I don't believe so, No, see previos comment. since CL_SALV_FUNCTIONS_LIST encapsulates only a subset of ALV functions and the editing functions are to the very least not among those which can be controlled using the named methods of this class. Unless CL_SALV_FUNCTIONS_LIST->ADD_FUNCTION( ) + SET_FUNCTION( ) lets to set up and control editing functions as custom ones, they will have to be activated via some "funky stuff", I feel...
cheers
Janis
Hi Janis,
Although SAP disabled the buttons/ didn't provide the buttons related to edit, the functionality for "Edit" is still present in the classes.
In Edit mode,
Right click on any row, and you get Cut/ Delete option.
Ctrl+C, Ctrl+V etc also works.
Pasting new rows also works.
So, I don't think the functionalities were removed in CL_SALV_TABLE, they were just hidden.
Thanks,
Juwin
Right, and not hidden very well 🙂 SALV does add a whole new layer of, if I understand correctly, "MVC and convenience logic" on top; the potential challenge I don't like in going behind SALV directly to grid is: how to keep grid state "compatible" with that of SALV.
cheers
Janis
Err, yes - real people 🙂 I still feel that on average the level of SAP's ABAP developers, standards and procedures are above those of the custom developments I have seen...
And the resistance to changes has more to do with real peoples real fears to screw up things in too many to count systems, I feel. Part of the response I got to my "
" bug fix proposal for simple sounding "BDT: required field check doesn't process all (field) status changes" problem illustratates:I have no idea about the technical challenges involved in getting to "editable SALV", but what I suspect is: maybe it's not so much unwillingness to do the "right thing", which many customers want - it's the inability to deliver a quality solution. The fear, which of course in turn reflects negatively on the quality of code base, developers, standards and procedures...
cheers
Janis
Naimesh,
Have you yet found a way to get the SALV to open directly in edit mode?
Thus far I have only been able to bring up the grid display for a SALV in read only mode, and have some sort of button so the user can change it into editable mode.
With a real CL_GUI_ALV_GRID report you can display the report directly in editable mode without the user having to do anything, just like in SM30.
And users do want this sort of thing.....
I was sort of thinking this was impossible with a SAV as you cannot get your hands on the underlying object until after the report has been displayed.
What do you think?
Cheersy Cheers
Paul
Hello Paul, I found a way to achieve it.. Almost finalizing the approach and testing it to make sure it works. Would send it out soon..
Thanks for keeping me on my toes 😆
Regards..
The "fullscreen" and "ALV grid in a container" adapters (I assume) seem to handle setting up the toolbars differently - "grid in a container" does not show the editing functions automatically.
I can show CL_SALV_TABLE instance in a container in editmode as simply as calling its display( ), followed by getting and doing the "funky stuff" to grid (get_frontend_layout( ) + set_frontend_layout( )), followed by CL_SALV_TABLE->refresh( ) in PBO. Obviously, ALV at this point is without appropriate toolbar and most likely the events to handle the functionality, but those can likely be set up by doing more "funky stuff".
There may also be a cleverer way without calling standard display( ), by instantiating and setting up the adapter and the grid in the "funky stuff" part... I feel, however, that doing the "funky stuff" to switch on editiable grid alone is already depending on SALV "implementation details" too much... I wish CL_SALV_TABLE was at least programmed to an interface, so it could be kind of "decorated" easier, if SAP didn't want us to inherit this class.
Don't feel good about this solution; SAP should just do the "right thing"...
Another small comment about the old solution: unlike fullscreen, for the grid in container SET_SCREEN_STATUS( ) is not supported for obvious reasons (check is programmed in CL_SALV_MODEL_BASE->SET_SCREEN_STATUS( )).
Test code fragment:
Result:
I liked it when SAP took a very useful class CL_GUI_ALV_GRID and encapsulated it to simplify the interface using CL_SALV_TABLE. But, I haven't quite understood why they disabled some of the basic functionalities of CL_GUI_ALV_GRID, like the events, status, edit etc.
So, would you be able to tell, what are those obvious reasons?
Thanks,
Juwin
Hi,
For one, "phylosophically" there is no real need to try to mess with "GUI status" of the whole application from within and via a "subcomponent" placed in a GUI container - application can control GUI status directly. In addition one can also imagine an application with several grid containers on one screen; then it gets a bit dicey, I feel.
Fullscreen mode with one grid does away with those concerns (the grid IS the whole of application so to speak), but honestly - I don't yet understand the need to control application GUI status via CL_SALV_TABLE... To accomplish what - adding a GUI function and making grid aware of it with single method call..?
cheers
Janis
Hello Jānis,
Correct that the Grid and Fullscreen has different trigger time. For the Grid, you are in PBO of the your own screen so the DISPLAY method doesn't actually bring up the ALV, the end of PBO does. For Fullscreen, ALV handles that so after DISPLAY, you don't have control anymore.
Also the toolbar is tricky. the SALV grid has special functionality for the toolbar and it hides many of those. so, had to put those buttons back.
I just published blog to cover this and make it happen using AFTER_REFRESH event. SALV Editable with Single (custom) Method
Regards,
Naimesh Patel
Hello Paul,
Just to close the loop - SALV Editable with Single (custom) Method the solution without the button ..
Regards,
Naimesh Patel
Excellent Naimesh ! I totally agree with your solution and i remember discussing about this topic in 2008.
this example is way easier:
its just you have to use the adapter attribute of the model class than using r_Controller which is a protected attribute,
http://harelgilor.blogspot.com/2010/11/abap-objects-alv-grid-manipulations.html
Very nice blog.
Please provide full length . All your efforts will be utilized many of us like me.
I am unable to use this code in the program.
If possible can u share the full code . Showing errors get_grid and few . Thank you.
Sreenu.tikku@gmail.com is my mail id
Hello.
I found that post very helpful. The Button is what I needed.
I was also able to set only specific columns editable by changing the frontend_fieldcatalog of the grid object.
But I'm not able to restrict it to specific lines based on some values like shown in BCALV_EDIT_02. It seems that the grid object behind the SALV table ignores the Style tab in the data table (a column with type LVC_T_STYL).
Was anyone able to extend the SALV editable functionality for just specific cells?
Many thanks and regards
Markus
Hi Naimesh,
This is very great!
Would you like to have a look at my issue as below please?
When I used this approach to set salv grid editable, it works fine by setting { layout-edit = 'X' } or { fieldcat-edit = 'X' }.
However, it can not work as editable ( input ready ) when I am coding as { l_layout-stylefname = 'l_layout-stylefname ' and other setting like standard program LFOT_RFD_MONIFE0 }
This cell-level editing is used for primary key fields, so could you help me please?
Thanks a lot.
Michael
Hi Naimesh,
great work and things change. As I noticed today, all get_grid( ) calls on program FOT_RFD_MONI have been comments meanwhile. It looks as if the locak class is not needef any longer. Please have a look and please explain...