ABAP Code: How to Implement ALV Tree?

This report program is based on the standard SAP program BCALV_TREE_01. It shows the essential steps to build up a hierarchy using an ALV Tree Control (class CL_GUI_ALV_TREE). 

In this program, the hierarchy tree consists of nodes for each month on top level (this level can not be build by a simple ALV Tree because there is no field for months in our output table SFLIGHT. Thus, you can not define this hierarchy by sorting nor initial calculations neither a special layout has been applied. Note also that this example does not build up and change the fieldcatalog of the output table. For this reason, all fields of the output table are shown in the columns although the fields CARRID and FLDATE are already placed in the tree on the left.

Steps:
1.Usual steps when using control technology.

  • Define reference variables.
  • Create ALV Tree Control and corresponding container.
2.Create Hierarchy-header
3.Create empty Tree Control
4.Create hierarchy (nodes and leaves)

  • Select data
  • Sort output table according to your conceived hierarchy
  • Add data to tree
5.Send data to frontend.
6.Call dispatch to process toolbar functions 

Complete Source Code:
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
* ァ1a. Define reference variables
data: g_alv_tree         type ref to cl_gui_alv_tree,
      g_custom_container type ref to cl_gui_custom_container.

data: gt_sflight      type sflight occurs 0,      "Output-Table
      ok_code like sy-ucomm,
      save_ok like sy-ucomm,           "OK-Code
      g_max type i value 255.

end-of-selection.

  call screen 100.

*&---------------------------------------------------------------------*
*&      Module  PBO  OUTPUT
*&---------------------------------------------------------------------*
*       process before output
*----------------------------------------------------------------------*
module pbo output.

  set pf-status 'MAIN100'.
  set titlebar 'MAINTITLE'.

  if g_alv_tree is initial.
    perform init_tree.

    call method cl_gui_cfw=>flush
      exceptions
        cntl_system_error = 1
        cntl_error        = 2.
    if sy-subrc ne 0.
      call function 'POPUP_TO_INFORM'
        exporting
          titel = 'Automation Queue failure'(801)
          txt1  = 'Internal error:'(802)
          txt2  = 'A method in the automation queue'(803)
          txt3  = 'caused a failure.'(804).
    endif.
  endif.

endmodule.                             " PBO  OUTPUT
*&---------------------------------------------------------------------*
*&      Module  PAI  INPUT
*&---------------------------------------------------------------------*
*       process after input
*----------------------------------------------------------------------*
module pai input.
  save_ok = ok_code.
  clear ok_code.

  case save_ok.
    when 'EXIT' or 'BACK' or 'CANC'.
      perform exit_program.

    when others.
* ァ6. Call dispatch to process toolbar functions
      call method cl_gui_cfw=>dispatch.

  endcase.

  call method cl_gui_cfw=>flush.
endmodule.                             " PAI  INPUT

*&---------------------------------------------------------------------*
*&      Form  init_tree
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
form init_tree.
* ァ1b. Create ALV Tree Control and corresponding Container.

* create container for alv-tree
  data: l_tree_container_name(30) type c.

  l_tree_container_name = 'CCONTAINER1'.

     create object g_custom_container
        exporting
              container_name = l_tree_container_name
        exceptions
              cntl_error                  = 1
              cntl_system_error           = 2
              create_error                = 3
              lifetime_error              = 4
              lifetime_dynpro_dynpro_link = 5.
    if sy-subrc <> 0.
      message x208(00) with 'ERROR'(100).
    endif.

* create tree control
  create object g_alv_tree
    exporting
        parent              = g_custom_container
        node_selection_mode = cl_gui_column_tree=>node_sel_mode_single
        item_selection      = 'X'
        no_html_header      = 'X'
        no_toolbar          = ''
    exceptions
        cntl_error                   = 1
        cntl_system_error            = 2
        create_error                 = 3
        lifetime_error               = 4
        illegal_node_selection_mode  = 5
        failed                       = 6
        illegal_column_name          = 7.
  if sy-subrc <> 0.
    message x208(00) with 'ERROR'.                          "#EC NOTEXT
  endif.

* ァ2. Create Hierarchy-header
* The simple ALV Tree uses the text of the fields which were used
* for sorting to define this header. When you use
* the 'normal' ALV Tree the hierarchy is build up freely
* by the programmer this is not possible, so he has to define it
* himself.
  data l_hierarchy_header type treev_hhdr.
  perform build_hierarchy_header changing l_hierarchy_header.

* ァ3. Create empty Tree Control
* IMPORTANT: Table 'gt_sflight' must be empty. Do not change this table
* (even after this method call). You can change data of your table
* by calling methods of CL_GUI_ALV_TREE.
* Furthermore, the output table 'gt_outtab' must be global and can
* only be used for one ALV Tree Control.
  call method g_alv_tree->set_table_for_first_display
    exporting
      i_structure_name    = 'SFLIGHT'
      is_hierarchy_header = l_hierarchy_header
    changing
      it_outtab           = gt_sflight. "table must be empty !

* ァ4. Create hierarchy (nodes and leaves)
  perform create_hierarchy.

* ァ5. Send data to frontend.
  call method g_alv_tree->frontend_update.

* wait for automatic flush at end of pbo
endform.                               " init_tree
*&---------------------------------------------------------------------*
*&      Form  build_hierarchy_header
*&---------------------------------------------------------------------*
*       build hierarchy-header-information
*----------------------------------------------------------------------*
*      -->P_L_HIERARCHY_HEADER  strucxture for hierarchy-header
*----------------------------------------------------------------------*
form build_hierarchy_header changing
                               p_hierarchy_header type treev_hhdr.

  p_hierarchy_header-heading = 'Month/Carrier/Date'(300).
  p_hierarchy_header-tooltip = 'Flights in a month'(400).
  p_hierarchy_header-width = 30.
  p_hierarchy_header-width_pix = ' '.

endform.                               " build_hierarchy_header
*&---------------------------------------------------------------------*
*&      Form  exit_program
*&---------------------------------------------------------------------*
*       free object and leave program
*----------------------------------------------------------------------*
form exit_program.

  call method g_custom_container->free.
  leave program.

endform.                               " exit_program
*&---------------------------------------------------------------------*
*&      Form  create_hierarchy
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
form create_hierarchy.

  data: ls_sflight type sflight,
        lt_sflight type sflight occurs 0,
        l_yyyymm(6) type c,            "year and month of sflight-fldate
        l_yyyymm_last(6) type c,
        l_carrid like sflight-carrid,
        l_carrid_last like sflight-carrid.

  data: l_month_key type lvc_nkey,
        l_carrid_key type lvc_nkey,
        l_last_key type lvc_nkey.

* ァ4a. Select data
  select * from sflight into table lt_sflight up to g_max rows.

* ァ4b. Sort output table according to your conceived hierarchy
* We sort in this order:
*    year and month (top level nodes, yyyymm of DATS)
*      carrier id (next level)
*         day of month (leaves, dd of DATS)
  sort lt_sflight by fldate+0(6) carrid fldate+6(2).
* Note: The top level nodes do not correspond to a field of the
* output table. Instead we use data of the table to invent another
* hierarchy level above the levels that can be build by sorting.

* ァ4c. Add data to tree

  loop at lt_sflight into ls_sflight.
* Prerequesite: The table is sorted.
* You add a node everytime the values of a sorted field changes.
* Finally, the complete line is added as a leaf below the last
* node.
    l_yyyymm = ls_sflight-fldate+0(6).
    l_carrid = ls_sflight-carrid.

* Top level nodes:
    if l_yyyymm <> l_yyyymm_last.      "on change of l_yyyymm
      l_yyyymm_last = l_yyyymm.

*Providing no key means that the node is added on top level:
      perform add_month using    l_yyyymm
                                      ''
                             changing l_month_key.
* The month changed, thus, there is no predecessor carrier
      clear l_carrid_last.
    endif.

* Carrier nodes:
* (always inserted as child of the last month
*  which is identified by 'l_month_key')
    if l_carrid <> l_carrid_last.      "on change of l_carrid
      l_carrid_last = l_carrid.
      perform add_carrid_line using    ls_sflight
                                       l_month_key
                              changing l_carrid_key.
    endif.

* Leaf:
* (always inserted as child of the last carrier
*  which is identified by 'l_carrid_key')
    perform add_complete_line using  ls_sflight
                                     l_carrid_key
                            changing l_last_key.
  endloop.

endform.                               " create_hierarchy

*&---------------------------------------------------------------------*
*&      Form  add_month
*&---------------------------------------------------------------------*
form add_month  using     p_yyyymm type c
                          p_relat_key type lvc_nkey
                changing  p_node_key type lvc_nkey.

  data: l_node_text type lvc_value,
        ls_sflight type sflight,
        l_month(15) type c.            "output string for month

* get month name for node text
  perform get_month using p_yyyymm
                    changing l_month.
  l_node_text = l_month.

* add node:
* ALV Tree firstly inserts this node as a leaf if you do not provide
* IS_NODE_LAYOUT with field ISFOLDER set. In form 'add_carrid_line'
* the leaf gets a child and thus ALV converts it to a folder
* automatically.
*
  call method g_alv_tree->add_node
    exporting
      i_relat_node_key = p_relat_key
      i_relationship   = cl_gui_column_tree=>relat_last_child
      i_node_text      = l_node_text
      is_outtab_line   = ls_sflight
    importing
      e_new_node_key   = p_node_key.

endform.                               " add_month
*--------------------------------------------------------------------
form add_carrid_line using     ps_sflight type sflight
                               p_relat_key type lvc_nkey
                     changing  p_node_key type lvc_nkey.

  data: l_node_text type lvc_value,
        ls_sflight type sflight.

* add node
* ALV Tree firstly inserts this node as a leaf if you do not provide
* IS_NODE_LAYOUT with field ISFOLDER set. In form 'add_carrid_line'
* the leaf gets a child and thus ALV converts it to a folder
* automatically.
*
  l_node_text =  ps_sflight-carrid.
  call method g_alv_tree->add_node
    exporting
      i_relat_node_key = p_relat_key
      i_relationship   = cl_gui_column_tree=>relat_last_child
      i_node_text      = l_node_text
      is_outtab_line   = ls_sflight
    importing
      e_new_node_key   = p_node_key.

endform.                               " add_carrid_line
*&---------------------------------------------------------------------*
*&      Form  add_complete_line
*&---------------------------------------------------------------------*
form add_complete_line using   ps_sflight type sflight
                               p_relat_key type lvc_nkey
                     changing  p_node_key type lvc_nkey.

  data: l_node_text type lvc_value.

  write ps_sflight-fldate to l_node_text mm/dd/yyyy.

* add leaf:
* ALV Tree firstly inserts this node as a leaf if you do not provide
* IS_NODE_LAYOUT with field ISFOLDER set.
* Since these nodes will never get children they stay leaves
* (as intended).
*
  call method g_alv_tree->add_node
    exporting
      i_relat_node_key = p_relat_key
      i_relationship   = cl_gui_column_tree=>relat_last_child
      is_outtab_line   = ps_sflight
      i_node_text      = l_node_text
    importing
      e_new_node_key   = p_node_key.

endform.                               " add_complete_line
*&---------------------------------------------------------------------*
*&      Form  GET_MONTH
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_P_YYYYMM  text
*      <--P_L_MONTH  text
*----------------------------------------------------------------------*
form get_month using    p_yyyymm
               changing p_month.
* Returns the name of month according to the digits in p_yyyymm

  data: l_monthdigits(2) type c.

  l_monthdigits = p_yyyymm+4(2).
  case l_monthdigits.
    when '01'.
      p_month = 'January'(701).
    when '02'.
      p_month = 'February'(702).
    when '03'.
      p_month = 'March'(703).
    when '04'.
      p_month = 'April'(704).
    when '05'.
      p_month = 'May'(705).
    when '06'.
      p_month = 'June'(706).
    when '07'.
      p_month = 'July'(707).
    when '08'.
      p_month = 'August'(708).
    when '09'.
      p_month = 'September'(709).
    when '10'.
      p_month = 'October'(710).
    when '11'.
      p_month = 'November'(711).
    when '12'.
      p_month = 'December'(712).
  endcase.
  concatenate p_yyyymm+0(4) '->' p_month into p_month.

endform.                               " GET_MONTH
*-----------------------------------------------------------------------


Sample Output:

No comments:

Post a Comment