2011-06-09

WD Screen Variants – WD Component

overview

The concept of a selection screen variant is something that most SAP users have come to expect, yet this feature is unavailable in standard Web Dynpro. Below is the next in a series of posts detailing how to bring this necessary feature back to Web Dynpro. Start here to see the full requirements.
ZES_SELOPT_VARIANT
Start your development by creating a new Web Dynpro component named ZES_SELOPT_VARIANT. This WD component will have a public interface with a few methods used to initialize the report name and selection screens. It will have one main window that contains three buttons (by default): Get Variant, Save Variant, and Delete Variant. 
ZES_SELOPT_VARIANTIn the Web Dynpro component, we’ll need to use two instances of the Web Dynpro ALV component:

Comp. Use Component Description
ALV1 SALV_WD_TABLE List of existing selection screen variants for this Web Dynpro application)
ALV2 SALV_WD_TABLE List of fields assigned to this set of selection screens.
This is also where you identify the assistance class created earlier.
In the Component Controller, add the following context nodes:
Node: TEXT stores the values of various labels used through the component.
Context node TEXT
Node: IN stores values that are bound to various screen elements throughout.  This elements in this node could have used a little more structure – maybe split out by view - given the time.
Context node IN
Node: VARIANT_LIST is a table of variants associated with the REPORT_NAME assigned when the component is initialized.
Context node VARIANT_LIST
Node: VARIANT_FIELDS holds a table of fields associated with the currently selected (or newly created) variant.
Context node VARIANT_FIELDS
Node: FIELD_PARAMS is a single-line structure that holds the values selected by the user from view V_ASK_PARAMETERS that are used to help determine dynamic dates (more later).
Context node FIELD_PARAMS
One additional attribute is required on the Component Controller: M_CLEAR_MSGS.  This value will be set at each *first* display of the W_GET_VARIANT and W_SAVE_VARIANT windows in order to prevent ‘required field’ warnings from being shown to the user.  The MO_GET_WINDOW is not used.  It was added as part of an attempt to get the W_GET_VARIANT window to auto-close when a row is selected.
Component controller Attributes
I added the following events to the Component Controller:
Component controller Events
The following methods were added as part of the Web Dynpro Component interface in order of importance:
SET_REPORT_NAME:  Here we’re simply setting the the context node element to remember the value.
   1: METHOD set_report_name .                                    " PLM8034
   2:  
   3:   DATA: lo_nd_in                      TYPE REF TO if_wd_context_node.
   4:   DATA: lo_ni_in                      TYPE REF TO if_wd_context_node_info.
   5:   lo_nd_in = wd_context->get_child_node( name = wd_this->wdctx_in ).
   6:   lo_ni_in = lo_nd_in->get_node_info( ).
   7:  
   8:   lo_nd_in->set_attribute( EXPORTING: name = 'REPID'
   9:                                       value = i_report_name ).
  10:   me->refresh_variant_list( ).
  11:  
  12: ENDMETHOD.

It’s also important to know what the REFRESH_VARIANT_LIST routine is doing. It’s called when the report name is set in addition to a couple of other important times. This retrieves a list of variants from the transparent table created for storing the variants for the report name indicated above.  It binds this list to the VARIANT_LIST context node.

 

   1: METHOD refresh_variant_list .                               " PLM8034
   2:  
   3:   DATA: lo_nd_in                      TYPE REF TO if_wd_context_node.
   4:   DATA: lo_ni_in                      TYPE REF TO if_wd_context_node_info.
   5:   lo_nd_in = wd_context->get_child_node( name = wd_this->wdctx_in ).
   6:   lo_ni_in = lo_nd_in->get_node_info( ).
   7:  
   8:   DATA: l_repid                       TYPE repid.
   9:   lo_nd_in->get_attribute( EXPORTING: name = 'REPID'
  10:                            IMPORTING: value = l_repid ).
  11:  
  12:   DATA: lt_variants                   TYPE TABLE OF zes_wdvari,
  13:         ls_variant                    LIKE LINE OF lt_variants.
  14:   SELECT prog_name vari_name vtext protected
  15:          ename edat etime aename aedat aetime
  16:     INTO CORRESPONDING FIELDS OF TABLE lt_variants
  17:     FROM zes_wdvari
  18:    WHERE relid = 'WD'
  19:      AND prog_name = l_repid.
  20:  
  21:   DATA: lo_nd_list                    TYPE REF TO if_wd_context_node.
  22:   DATA: lo_ni_list                    TYPE REF TO if_wd_context_node_info.
  23:   lo_nd_list = wd_context->get_child_node( name = wd_this->wdctx_variant_list ).
  24:   lo_ni_list = lo_nd_list->get_node_info( ).
  25:  
  26:   lo_nd_list->bind_table( lt_variants ).
  27:  
  28: ENDMETHOD.


APPEND_SELOPT_SCREEN: Add the value supplied to the list of selection screens to process later when getting/saving the variant.


 

   1: METHOD append_selopt_screen .                               " PLM8034
   2:   APPEND i_selopt_screen TO wd_assist->selopt_screens[].
   3: ENDMETHOD.

SHOW_BUTTONS: Show/hide Get/Save/Delete buttons (untested)

 

   1: METHOD show_buttons .                                       " PLM8034
   2:  
   3:   DATA: lo_nd_in                      TYPE REF TO if_wd_context_node.
   4:   lo_nd_in = wd_context->get_child_node( name = wd_this->wdctx_in ).
   5:  
   6:   lo_nd_in->set_attribute( EXPORTING: name = 'VISIBLE_BTN_GET'
   7:                                       value = i_btn_get ).
   8:   lo_nd_in->set_attribute( EXPORTING: name = 'VISIBLE_BTN_SAVE'
   9:                                       value = i_btn_save ).
  10:   lo_nd_in->set_attribute( EXPORTING: name = 'VISIBLE_BTN_DELETE'
  11:                                       value = i_btn_delete ).
  12:  
  13: ENDMETHOD.

GET_VARIANT_NAME: Get variant name chosen by user (untested)


 

   1: METHOD get_variant_name .                                   " PLM8034
   2:  
   3:   DATA: lo_nd_in                      TYPE REF TO if_wd_context_node.
   4:   lo_nd_in = wd_context->get_child_node( name = wd_this->wdctx_in ).
   5:  
   6:   lo_nd_in->get_attribute( EXPORTING: name = 'VARIANT_NAME'
   7:                            IMPORTING: value = r_result ).
   8:  
   9:  
  10: ENDMETHOD.

The WDDOINIT method is called immediately at initialization.  First, I’m initializing the list of ‘dynamic date’ routines used later for DATS fields.  Then I’m setting the labels for various controls used through the views based on logon language.  Finally, I indicate that the MAIN view should show all three buttons by default.


 

   1: METHOD wddoinit .                                           " PLM8034
   2:  
   3:   wd_assist->init_varivar_table( ).
   4:  
   5:   DATA: lo_nd_text                    TYPE REF TO if_wd_context_node.
   6:   lo_nd_text = wd_context->get_child_node( name = wd_this->wdctx_text ).
   7:  
   8:   DATA: l_text                        TYPE string.
   9:  
  10:   l_text = wd_assist->get_text( '001' ).
  11:   lo_nd_text->set_attribute( EXPORTING: name = 'GET'
  12:                                         value = l_text ).
  13:  
  14:   l_text = wd_assist->get_text( '002' ).
  15:   lo_nd_text->set_attribute( EXPORTING: name = 'SAVE'
  16:                                         value = l_text ).
  17:  
  18:   l_text = wd_assist->get_text( '003' ).
  19:   lo_nd_text->set_attribute( EXPORTING: name = 'OK'
  20:                                         value = l_text ).
  21:  
  22:   l_text = wd_assist->get_text( '004' ).
  23:   lo_nd_text->set_attribute( EXPORTING: name = 'CANCEL'
  24:                                         value = l_text ).
  25:  
  26:   l_text = wd_assist->get_text( '005' ).
  27:   lo_nd_text->set_attribute( EXPORTING: name = 'PROTECTED'
  28:                                         value = l_text ).
  29:  
  30:   l_text = wd_assist->get_text( '006' ).
  31:   lo_nd_text->set_attribute( EXPORTING: name = 'PARAM1'
  32:                                         value = l_text ).
  33:  
  34:   l_text = wd_assist->get_text( '007' ).
  35:   lo_nd_text->set_attribute( EXPORTING: name = 'PARAM2'
  36:                                         value = l_text ).
  37:  
  38:   me->show_buttons( ).
  39:  
  40: ENDMETHOD.

Okay that gets a real good start on the Component Controller.  In truth there are quite a few more methods on this object that we’ll get into a little later.  These methods are called by user-events, but were placed at the Component Controller level, because it already had access to the shared Context nodes we created above.






overview

2011-06-02

WD Screen Variants – Assistance Class

overview

<< previous | next >>

The concept of a selection screen variant is something that most SAP users have come to expect, yet this feature is unavailable in standard Web Dynpro. Below is the next in a series of posts detailing how to bring this necessary feature back to Web Dynpro. Start here to see the full requirements.

Start a new ABAP class ZCL_WDR_SELOPT_VARIANT.  It should inherit from CL_WD_COMPONENT_ASSISTANCE in order to be a true Web Dynpro assistance class (however, this isn’t a requirement).  An Assistance Class is assigned to a Web Dynpro component for two reasons: text elements and class-based coding.

SNAGHTML1e5aeada

Text Elements

I use this class to hold a list of language-dependent label captions that can be translated as needed.

SNAGHTML1e60972f

Classic ABAP Class-based Code

I’ve made the assistance class very important to this project by placing the list of assigned select options in this class.  It also stores a list of dynamic-date functions from RS_VARI_V_INIT.
SNAGHTML1e64b29b

You’ll see later where these methods are called.  The GET_TEXT method is simply a call to Web Dynpro assistance class GET_TEXT.  This makes for a more simple method call inside my Web Dynpro component.  The INIT_VARIVAR_TABLE is called at initialization to populate the MT_VARIVAR variant variables function list.

SNAGHTML1e66f4c9

This method gets a list of the various dynamic date possibilities:

   1: METHOD init_varivar_table.
   2:  
   3:   CALL FUNCTION 'RS_VARI_V_INIT'
   4:     TABLES
   5:       p_varivar = me->mt_varivar[].
   6:  
   7: **********************************************************************
   8: * Hide these dynamic date possibilities.
   9: * We don't have factory calendars configured in D15.
  10: **********************************************************************
  11:  
  12:   DATA: ls_varivar                    TYPE rsvarivar.
  13:   LOOP AT me->mt_varivar[] INTO ls_varivar.
  14:     CASE ls_varivar-runt_fb.
  15:       WHEN 'RS_VARI_V_TODAY_XWD' OR
  16:            'RS_VARI_V_WDAYS_UP_TO_NOW' OR
  17:            'RS_VARI_V_XWD_ACTUAL_MONTH'.
  18:  
  19:         DELETE TABLE me->mt_varivar[] FROM ls_varivar.
  20:  
  21:       WHEN OTHERS.
  22:     ENDCASE.
  23:   ENDLOOP.
  24:  
  25: ENDMETHOD.

Next, let’s dive into the Web Dynpro component itself.







overview

<< previous | next >>

2011-05-31

WD Screen Variants – DDIC Changes

overview

<< previous | next >>

The concept of a selection screen variant is something that most SAP users have come to expect, yet this feature is unavailable in standard Web Dynpro.  Below is the next in a series of posts detailing how to bring this necessary feature back to Web Dynpro.  Start here to see the full requirements.

Data Dictionary Changes
First we need a data store. In SE11, create a new table ZES_WDVARI. This table conforms to the specifications of the IMPORT/EXPORT database ABAP command.
ZES_WDVARI

We’ll also need a few additional data dictionary objects:
This structure will be used to hold the content of the data stored into ZES_WDVARI-CLUSTD (raw data) field). 
ZES_VUVVALUES 
This structure includes some additional fields used to display data to the user in the Web Dynpro ALV. 
ZES_VUVVALUES_ALV 
Table type used for class method parameters.
ZES_T_VUVVALUES 
Table of Web Dynpro Select Options will contain a list to all select option screens being considered as part of this variant.
ZES_T_WD_SELECT_OPTIONS

Now that we have the dictionary objects in place, let’s take a look at the development.

overview

<< previous | next >>

2011-05-27

Web Dynpro Selection Screen Variants

Okay – so I know I’m late to the game, but I finally got around to working on my first Web Dynpro Application. I was overall very happy with the tool and end-user presentation. 

This application was a report and as such, made heavy use of select options (WDR_SELECT_OPTIONS) in order to help filter the results.  I was excited to find most all of my standard SAP selection screen features replicated in Web Dynpro.  Still, I found one thing lacking: there is no concept of the selection screen variant.  It’ll take me a while to get this all out, but I intend to provide specific details to recreate my response to this issue. 

Disclaimer: This implementation was built in SAP NetWeaver 7.0 EHP 1 SP3.  I expect change and at some point (maybe already) this will become obsolete.  So far as I can tell, there is no SAP-provided solution to what I perceive as a big miss.

To complete this task, I referenced two other posts
here and here.  Both helped a lot.  However neither had everything we expected from our selection screen variant.

Functional Requirements
There are a number of expectations from this Web Dynpro Component.  Over the next few posts, I’ll be describing my implementation of the following functional requirements:
  • Allow multiple uses of a selection screen variant within the same application.
  • Allow for multiple “screens” (or instances of IF_WD_SELECT_OPTIONS) to be assigned to a single variant.
  • Save selection screen fields into a variant with a specific name, created/modified information.
  • Protect a variant for modification only be one user.
  • Retrieve existing selection screen variant to repopulate field values.
  • Ability to use dynamic date feature found in standard SAP selection screen variants.
  • Delete a selected selection screen variant.
Technical Requirements
  1. DDIC Changes
  2. Assistance Class
  3. WD Component
  4. Main View
  5. Get Variant view
  6. Save Variant view
  7. Dynamic Dates
  8. Component Usage in your WD Application

The End Result

The result of this effort is an unobtrusive triplet of buttons that can be located in your Web Dynpro application.  This small little feature lends tremendous power to your web reports.  And in some cases, it is what your users have come to expect from quality ABAP development.
image

Enjoy.

2011-03-23

Compliments to the Development Team on IE9

I have to hand it to the IE9 development staff.  They really put out a nice product this time around. 

Load Performance

On my machine, the time to load IE9 has improved noticeably.  I am also impressed by the visibility of add-on “Load time”.  This helps a great deal in determining which add-on is causing performance issues on a machine.
ie9-01

Application Responsiveness

It’s just snappy.  I can’t tell you enough: I’m surprised by how quick the tool is compared to it’s predecessor.  I’ve seen performance improvements in events such as: opening new tabs and switching between tabs, initiating a URL request, and page load time.

Features From Other Browsers

It’s rather obvious that the team implemented a few ideas from existing browsers.  It’s good to see Internet Explorer finally get with the program.  I was happy to see the following enhancements to IE9: tear-off tabs, the address/search bar combined, the “new” New Tab page that shows recent sites.

I like the simplified title bar area that contains the address bar and tabs on one line.  And the status / notification bar that only appears when it’s needed. These types of changes offer more screen real-estate to what the product is intended for: browsing the web.
ie9-02

Developer Tools

Wow – all the information I need packed right here.  Know that most of this was already available in IE8.  The most useful enhancement (to me) is the availability of the Network Traffic logs.  Here you can see the details of each file requested in a URL request.  Nice feature…
ie9-04

What’s missing?

Something I’d really like to see come back: the ability to “hide” an add-on without having to “disable” it.  My biggest qualm is having to approve disabling an add-on.

Overall, Internet Explorer 9 is a very nice upgrade with lots of useful enhancements.  Thanks to all those who worked on its release.

2011-02-24

A Plea for Custom Document Property Manipulation in Excel

In my experience, the capabilities of Microsoft Excel have far outweighed that of Microsoft Word.  It may possibly be my line of work, but I’ve thus far always found that I can accomplish more with Excel’s formulas, references, and especially macros than I could ever hope to get out of a Word document.  Word was great for typing fancy-looking text, but when I required any amount of functionality Excel was always there to save.  Until today…


The Request
Microsoft: please enhance Excel such that I can
  1. Retrieve and manipulate Custom Document Properties using only Formulas (no macros required) in the same way that can be found using Word’s Insert > QuickParts > Field functionality.
  2. Insert these same custom document properties into the header/footer section of a worksheet.

Microsoft Word
For example, in Word, I can choose Insert > Quick Parts > Field > DocProperty.  Then choose any document property maintained and insert a reference to it.
prop01


Limitation of Microsoft Excel
Unfortunately, in Excel a macro must be written in order to retrieve values from the CustomDocumentProperties collection.  A formula can then reference this macro.  In a corporate network with any sort of security policy, this means that users must “enable the macros” for this to function properly.

Function GetProperty(PropertyName As String, PropertySet As PropertyLocation, _
    Optional WhatWorkbook As Workbook) As Variant
(Reference Chip Pearson’s website for GetProperty code.)

Further, I’m unable to insert any auto-updated values into the footer of an Excel worksheet other than the handful of values pre-defined by Microsoft: page number, date/time, sheet name, etc.  In order for this to occur, I need yet another macro to execute Before_Print.
Private Sub Workbook_BeforePrint(Cancel As Boolean)
    With Worksheets("Sheet1").PageSetup
        .CenterFooter = GetProperty(“Issue.Header.Id”, 2)
    End With
End Sub
Code found by doing a Google search for excel formula in footer.

I’d like to see efforts made to improve the functionality of these items in the next release of Microsoft Excel.

Enjoy!