‎2009 Jan 08 10:40 AM
Hello fellow ABAPers,
I have problem displaying an internal table using the CL_SALV_TABLE class.
Here's what I do:
First creating a SALV object:
DATA gr_salv_table TYPE REF TO cl_salv_table.
cl_salv_table=>factory( EXPORTING r_container = ref_container
IMPORTING r_salv_table = gr_salv_table
CHANGING t_table = itab ).
Then I want to customize the columns to look nice, so creating a column-object:
DATA lr_columns TYPE REF TO cl_salv_columns_table.
lr_columns = gr_salv_table->get_columns( ).
After that I want the columns to have an optimized width, fortunately the CL_SALV_COLUMNS_TABLE class has a neat method to do that:
lr_columns->set_optimize( 'X' ).
Now I use the display method to show the ALV table on screen:
gr_salv_table->display( ).
... and it works, everything looks great, but now I want a single column to have a specific output length while the other columns are still optimized.
It seems to me that the SET_OPTIMIZED method of CL_SALV_COLUMN_TABLE doesn't work, see the following code:
DATA lr_column TYPE REF TO cl_salv_column_table.
lr_columns->set_optimize( 'X' ).
lr_column ?= lr_columns->get_column( 'MANDT' ).
IF lr_column->is_optimized( ) = ' '.
BREAK-POINT.
ENDIF.
When I debug that piece of code I always end up running into the break-point, which means that this column is not optimized, even though I told the columns class to optimize it.
OK, so I tried to not use the set_optimize method of the columns class at all and do it by myself, optimize every column manually, code:
DATA it_columns TYPE salv_t_column_ref.
FIELD-SYMBOLS <wa_columns> LIKE LINE OF it_columns.
it_columns = ip_ref_columns->get( ).
LOOP AT it_columns ASSIGNING <wa_columns>.
IF <wa_columns>-r_column->get_columnname( ) NE 'MANDT'.
<wa_columns>-r_column->set_optimized( 'X' ).
ENDIF.
ENDLOOP.
This way I check every column that is not mandt and set it optimize = true but that's not working either. No column of the ALV that I see is optimized.
So, it's an SAP SALV_TABLE bug?
Am I doing something wrong?
Is there another way to get what I want? In short: I want to optimize the width of all columns in my table except for one column, where I want do specify its outputlength.
The itab I display is dynamic, I don't know any columns but the one (MANDT) that I want to not being optimized.
Thanks alot, any help would be highly appreciated.
A. Jung
‎2009 Jan 08 11:00 AM
Hi Jung,
I am not sure you can use optimise and Output length together.
Just see the documentation for method set_output_length for class CL_SALV_COLUMN_TABLE
It says
"If you use SET_OUTPUT_LENGTH to optimize the column width for your
output as well, the optimal column width overwrites the ouput
length."
Regards
Edited by: Rajvansh Ravi on Jan 8, 2009 12:00 PM
‎2009 Jan 08 11:28 AM
Thanks for your answer Rajvansh Ravi, that explains why I can't use the SET_OPTIMIZE method of CL_SALV_COLUMNS_TABLE, but in my case SET_OPTIMIZE of CL_SALV_COLUMN_TABLE doesn't do anything.
‎2009 Jan 08 11:36 AM
Hi Jung,
set_optimize method works fine Check the below code by commenting and uncommenting set_optimize method.
DATA
: itab TYPE TABLE OF t000.
SELECT *
FROM t000
INTO TABLE itab.
DATA :
gr_salv_table TYPE REF TO cl_salv_table.
cl_salv_table=>factory( IMPORTING r_salv_table = gr_salv_table
CHANGING t_table = itab ).
DATA
: lr_columns TYPE REF TO cl_salv_columns_table.
lr_columns = gr_salv_table->get_columns( ).
DATA
: lr_column TYPE REF TO cl_salv_column_table.
lr_column ?= lr_columns->get_column( 'MANDT' ).
lr_columns->set_optimize( 'X' ).
gr_salv_table->display( ).Let me know if you still have issues with this method
Regards
‎2009 Jan 08 12:16 PM
Hi Ravi,
yes your example works just fine, but I need to set an output-length of a specific column, while all other columns are still being optimized!
I just modified your code ( "----- NEW -
" ) :
DATA: itab TYPE TABLE OF t000.
SELECT *
FROM t000
INTO TABLE itab.
DATA: gr_salv_table TYPE REF TO cl_salv_table.
cl_salv_table=>factory( IMPORTING r_salv_table = gr_salv_table
CHANGING t_table = itab ).
DATA: lr_columns TYPE REF TO cl_salv_columns_table.
lr_columns = gr_salv_table->get_columns( ).
DATA: lr_column TYPE REF TO cl_salv_column_table.
* ----- NEW ----- *
lr_column ?= lr_columns->get_column( 'MANDT' ).
lr_column->set_optimized( 'X' ).
CLEAR lr_column.
lr_column ?= lr_columns->get_column( 'CCCATEGORY' ).
lr_column->set_output_length( 42 ).
* ----- NEW ----- *
*lr_columns->set_optimize( 'X' ).
gr_salv_table->display( ).
I don't understand why the lines I added don't work.
I understand why set_optimized() of the columnS class overwrites set_output_length(), but in this example I work with a single column only.
I this example want MANDT to be optimized and CCCATEGORY should have a length of 42, but what does the program do? It just ignores the set_optimized statement - looks like an SAP bug to me? And since that's not working, I need a way to archieve that some other way.
‎2009 Jan 09 5:18 AM
Hi Jung,
I still think both methods work.
For SET_OPTIMIZED method of class CL_SALV_COLUMN_TABLE (For a particular column) according to the definition "SET_OPTIMIZED method to set the width of the column so that all values can be displayed in it completely."
This works for the column (MANDT) which we have put. I am able to see the values completely. However the heading of the column appears as Cli... . I think this is the reason why you said the method SET_OPTIMIZED does not work. ?? Is this why you said it does not work ?
Just check the value for variable OPTMI in debugger. The column is indeed optimized. But i think if you want to show the title completely as Client. Then you need to set the output width.
DATA: itab TYPE TABLE OF t000.
SELECT *
FROM t000
INTO TABLE itab.
DATA: gr_salv_table TYPE REF TO cl_salv_table.
cl_salv_table=>factory( IMPORTING r_salv_table = gr_salv_table
CHANGING t_table = itab ).
DATA: lr_columns TYPE REF TO cl_salv_columns_table.
lr_columns = gr_salv_table->get_columns( ).
DATA: lr_column TYPE REF TO cl_salv_column_table.
* ----- NEW ----- *
lr_column ?= lr_columns->get_column( 'MANDT' ).
lr_column->set_optimized( 'X' ).
DATA : OPTMI TYPE C.
CALL METHOD lr_column->is_optimized
receiving
value = OPTMI "Contains X -> Column MANDT is Optimised (Able to see the values completely)
.
CLEAR lr_column.
lr_column ?= lr_columns->get_column( 'ORT01' ).
lr_column->set_output_length( '5' ).
CALL METHOD lr_column->is_optimized
receiving
value = OPTMI "Contains ' ' -> Column ORT01 is not Optimised (Not able to see the values completely)
.
* ----- NEW ----- *
gr_salv_table->display( ).Regards
‎2009 Jan 09 7:54 AM
Hi,
I still think they don't work, atleast they don't work the way they should, IMO.
However the heading of the column appears as Cli... . I think this is the reason why you said the method SET_OPTIMIZED does not work. ?? Is this why you said it does not work?
Well, kind of like that, but not entirely.
My point is, why do both SET_OPTIMIZE() methods of CL_SALV_COLUMN_TABLE and CL_SALV_COLUMNS_TABLE behave differently?
Lets look at our example, the following code (it's the entire report, so it's easier to copy&paste):
REPORT zaj_test_salv_opti.
DATA itab TYPE TABLE OF t000.
SELECT * FROM t000 INTO TABLE itab.
DATA gr_salv_table TYPE REF TO cl_salv_table.
cl_salv_table=>factory( IMPORTING r_salv_table = gr_salv_table
CHANGING t_table = itab ).
DATA lr_columns TYPE REF TO cl_salv_columns_table.
lr_columns = gr_salv_table->get_columns( ).
DATA lr_column TYPE REF TO cl_salv_column_table.
lr_columns->set_optimize( 'X' ).
gr_salv_table->display( ).
... and a screenshot when I run the program on a german system:
[Screenshot 1|http://www.bilder-space.de/show.php?file=09.01lMXoqKhMhxY03KO.PNG]
That looks good, now let's look at the same program without any optimization at all:
REPORT zaj_test_salv_opti.
DATA itab TYPE TABLE OF t000.
SELECT * FROM t000 INTO TABLE itab.
DATA gr_salv_table TYPE REF TO cl_salv_table.
cl_salv_table=>factory( IMPORTING r_salv_table = gr_salv_table
CHANGING t_table = itab ).
DATA lr_columns TYPE REF TO cl_salv_columns_table.
lr_columns = gr_salv_table->get_columns( ).
DATA lr_column TYPE REF TO cl_salv_column_table.
gr_salv_table->display( ).
Output of that report looks like this:
[Screenshot 2|http://www.bilder-space.de/show.php?file=09.01galzlqbRCE63aEz.PNG]
Now the same program, now I'm optimizing just the MANDT-column, all other columns aren't being touched.
REPORT zaj_test_salv_opti.
DATA itab TYPE TABLE OF t000.
SELECT * FROM t000 INTO TABLE itab.
DATA gr_salv_table TYPE REF TO cl_salv_table.
cl_salv_table=>factory( IMPORTING r_salv_table = gr_salv_table
CHANGING t_table = itab ).
DATA lr_columns TYPE REF TO cl_salv_columns_table.
lr_columns = gr_salv_table->get_columns( ).
DATA lr_column TYPE REF TO cl_salv_column_table.
lr_column ?= lr_columns->get_column( 'MANDT' ).
lr_column->set_optimized( 'X' ).
gr_salv_table->display( ).
... and its output:
[Screenshot 3|http://www.bilder-space.de/show.php?file=09.01k8hA35aF3U634Si.PNG]
Looks just like screenshot 2, doesn't it? In this case, the optimization doesn't do anything, looks like no optimizing at all - but when I optimize all columns it's like screenshot 1, the way I want it to look.
Furthermore, when I set SET_OPTIMIZATION() = 'X' for all columns (cl_gui_columns_table) and than I ask a single column if it's optimized with IS_OPTIMIZED(), I get space, meaning that it isn't - that I don't understand either.
Anyway, do you see my dilemma now? The MANDT column is just an example, in my specific case where I actually need it it's a CHAR1 field, not a textfield but a clickable hotspot-link. I want the result of lr_columns->set_optimize( 'X' ) of all columns but one, there I want to set the width with lr_column->set_output_length( 2 ) ... and to me it still looks like I can't get that with the CL_SALV_TABLE classes I'm using, or can I?
Edited by: Andreas Jung on Jan 9, 2009 9:34 AM
‎2009 Jan 09 9:03 AM
Hi Jung,
Can you change the length of the field which has hotspot to 2 characters. So when you optimise all the columns the hotspot column will have length 2. Will that help. See if the below output looks OK.
TYPES : BEGIN OF TY_T000,
MANDT TYPE CHAR5, "---> Length increased from 3 to 5
MTEXT TYPE MTEXT_D,
ORT01 TYPE ORT01,
MWAER TYPE MWAER,
ADRNR TYPE CHAR10,
CCCATEGORY TYPE CCCATEGORY,
CCCORACTIV TYPE CCCORACTIV,
CCNOCLIIND TYPE CCNOCLIIND,
CCCOPYLOCK TYPE CCCOPYLOCK,
CCNOCASCAD TYPE CCNOCASCAD,
CCSOFTLOCK TYPE CCSOFTLOCK,
CCORIGCONT TYPE CCORIGCONT,
CCIMAILDIS TYPE CCIMAILDIS,
CCTEMPLOCK TYPE CCTEMPLOCK,
CHANGEUSER TYPE AS4USER,
CHANGEDATE TYPE AS4DATE,
LOGSYS TYPE LOGSYS,
END OF TY_T000.
DATA itab TYPE TABLE OF ty_t000.
SELECT * FROM t000 INTO corresponding fields of TABLE itab.
DATA gr_salv_table TYPE REF TO cl_salv_table.
cl_salv_table=>factory( IMPORTING r_salv_table = gr_salv_table
CHANGING t_table = itab ).
DATA lr_columns TYPE REF TO cl_salv_columns_table.
lr_columns = gr_salv_table->get_columns( ).
DATA lr_column TYPE REF TO cl_salv_column_table.
lr_columns->set_optimize( 'X' ). "--> Optimise all columns
gr_salv_table->display( ).Regards
‎2009 Jan 09 9:31 AM
No, unfortunately that is not working either.
I modified your example (the "NEW" part) so it's like my productive scenario.
REPORT zaj_test_salv_opti.
TYPES:
BEGIN OF ty_t000,
x_sel TYPE char1, " NEW
mandt TYPE char5, "---> Length increased from 3 to 5
mtext TYPE mtext_d,
ort01 TYPE ort01,
mwaer TYPE mwaer,
adrnr TYPE char10,
cccategory TYPE cccategory,
cccoractiv TYPE cccoractiv,
ccnocliind TYPE ccnocliind,
cccopylock TYPE cccopylock,
ccnocascad TYPE ccnocascad,
ccsoftlock TYPE ccsoftlock,
ccorigcont TYPE ccorigcont,
ccimaildis TYPE ccimaildis,
cctemplock TYPE cctemplock,
changeuser TYPE as4user,
changedate TYPE as4date,
logsys TYPE logsys,
END OF ty_t000.
DATA itab TYPE TABLE OF ty_t000.
SELECT * FROM t000 INTO CORRESPONDING FIELDS OF TABLE itab.
DATA gr_salv_table TYPE REF TO cl_salv_table.
cl_salv_table=>factory( IMPORTING r_salv_table = gr_salv_table
CHANGING t_table = itab ).
DATA lr_columns TYPE REF TO cl_salv_columns_table.
lr_columns = gr_salv_table->get_columns( ).
* ----- NEW ----- *
DATA lr_column TYPE REF TO cl_salv_column_table.
lr_column ?= lr_columns->get_column( 'X_SEL' ).
lr_column->set_tooltip( 'Some tooltip' ).
lr_column->set_cell_type( cl_salv_column_table=>if_salv_c_cell_type~checkbox_hotspot ).
lr_column->set_output_length( 3 ).
lr_column->set_visible( 'X' ).
* ----- NEW ----- *
lr_columns->set_optimize( 'X' ). "--> Optimise all columns
gr_salv_table->display( ).
X_SEL is the field where I want to set the length (3), all other columns should be optimized by cl_salv_columns_table->set_optimize( 'X' ).
Running the program just like that you get:
[SCREENSHOT 1|http://www.bilder-space.de/show.php?file=09.01rsCvKotmbet657z.PNG]
But I want it to look like that (I did that by hand using resizing with my mouse):
[SCREENSHOT 2|http://www.bilder-space.de/show.php?file=09.01YCiDuPfi4gvmt4i.PNG]
So if you can modify the code to get it look like Screenshot 2, I'd be the happiest ABAP-programmer ever!
Thank you, Rajvansh.
‎2009 Apr 01 4:59 PM
I've just come across exactly the same issue. I would agree that it seems like a bug. Have you checked OSS? I'm just about to, so I'll post back if I find anything.
‎2009 Apr 01 5:07 PM
No, I can't find any OSS notes regarding this bug. I may log it with SAP.
‎2009 Apr 01 5:20 PM
Problem now logged with SAP. Will update if/when I get a response.
‎2009 Apr 01 5:50 PM
It looks like SALV omits the OPTIMIZED for a column.
Method GET_SLIS_FIELDCATALOG of class CL_SALV_CONTROLLER_METADATA fills up the field catalog property. It reads all the column object and fill the field catalog type SLIS_T_FIELDCAT_ALV. If you explore the field cataloge type SLIS_T_FIELDCAT_ALV, you would not find any appropriate field for the OPTIMIZE at column level.
Regards,
Naimesh Patel
‎2009 Apr 02 8:17 AM
It looks like SALV omits the OPTIMIZED for a column.
Yepp, that's the problem (bug)
And thanks Chris, keep us updated ...
‎2009 Dec 04 12:13 PM
Hi Chris,
Did you resolve this yet? Any response from SAP. I have the same problem using CL_SALV_TABLE. I Am not able to optimize individual columns.
Cheers,
Paul
‎2009 Apr 06 8:03 AM
HI Jung,
If your using dynamic table concept then you can use the field catalog and build column names. For your information please see the below given code. I think this will help you to solve the problem.
while building the field catalog you can specifty the length of each fields. It will help you to build the column width dynamically.
try.
cl_salv_table=>factory(
exporting
r_container = go_bottom_contain "lr_dcontainer
importing
r_salv_table = go_detail "gr_table
changing
t_table = <dyntab> ).
catch cx_salv_msg. "#EC NO_HANDLER
endtry.
gr_functions = go_detail->get_functions( ).
gr_layout = go_detail->get_layout( ).
gr_display = go_detail->get_display_settings( ).
gr_functions->set_all( abap_true ).
loop at gt_fcat into gs_fcat.
perform name_columns changing gs_fcat-fieldname gs_fcat-reptext.
endloop.
perform set_layout using p_layout.
gr_display->set_striped_pattern( cl_salv_display_settings=>true ).
gr_display->set_list_header( gv_lvc_title ).
go_detail->display( ).
Find the below subroutine which will name the columns.
form name_columns changing p_field type lvc_fname
p_val type reptext.
data: lv_text1 type scrtext_l.
*Column Headings.
gr_columns = go_detail->get_columns( ). "gr_table->get_columns( ).
try.
gr_column ?= gr_columns->get_column( p_field ).
catch cx_salv_not_found into gv_oref.
gv_text = gv_oref->get_text( ).
cleanup.
endtry.
move p_val to lv_text1.
gr_column->set_long_text( lv_text1 ).
move gv_text to gv_text.
clear gv_text.
endform. " NAME_COLUMNS