Altius Community

Altius Consulting Community
Welcome to Altius Community Sign in | Join | Help
in Search

Adam Adshead

  • Lessons Learned in a Software Development Project

    It is a few days until Christmas now, most people are winding down and I am given a short window to reflect on my work this year. I have recently completed a project that built a medium sized planning, forecasting and reporting solution. I am looking at what has worked well in my project, as well as what has not. The project lasted a year and involved a tremendous effort by the whole team. It is important after so much work to look at what lessons can be learnt.

    The things I have seen work well this year have been:

    • The business taking ownership of the system being delivered. Interaction between the business and project team was good, especially during the execute phase that ensured the project’s successful delivery
    • Good communication within the team, issues and risks were handled and managed well and the team was kept informed on responsibilities, timeframes etc.
    • Having the support organisation involved in the design and build allowed them to get on board and made handover more seamless
    • Using different presenters for different topics worked very well during training. Collaboration between the business and project team in producing and reviewing the training materials meant they were of a high standard
    • Providing demos of functionality early in the define phase so the business could gain an early understanding and appreciation of the system functionality
    • A realistic and well defined plan was created that was regularly monitored to keep the team focused and aware of deadlines
    • Tight control of scope creep helped to keep the project on schedule. During user acceptance testing it was very important that every change was carefully thought through to minimize delivery delays and not affect other system components

    A lot of positive points have been made here that are important to remember in future projects. There are also the areas of work that did not go so well, these have been:

    • One requirement was unclear and the business was not aligned in realising the use of its functionality. Subsequently, the configuration built may not be used, resources and time could have been spent on other streams
    • Roles and responsibilities for each piece of work needed to be more detailed in the Design/Requirements document. This led to resources spending time on issues while more critical issues were still outstanding
    • Tight deadlines meant a couple of issues in integration testing ran into user acceptance testing. This led to a loss of interest by business users during testing who had other responsibilities and caused further delays. Integration testing should have been bottomed out before user acceptance testing started
    • Meetings tended to be quite consultative leading to long hours. Participation should have been more restrictive and only involved key decision makers
    • User configuration issues were only found during user acceptance testing. This caused them to lose testing time while they waited for the configuration to be corrected

    Most of these lessons are fairly obvious in hindsight but in the large scheme of a project they can be easily missed. It may be worth reviewing these lessons against your current project to see if they can be of benefit.

     

    Technorati Tags: ,
  • SAP Web Dynpro Best Practices

    During my time designing and developing Web Dynpro applications I have compiled a list of best practices I follow. I would like to open this list up and welcome further additions to it. I have split the list into the core components of a Web Dynpro application. If you have any best practices relating to other areas like plugs, attributes or events please feel free to comment on them as well.

    User Interface (UI):

    clip_image001 A standard naming convention should be used

    clip_image001[1] Context elements should be implemented before UI creation. The Web Dynpro wizard can then be utilized to generate elements, minimizing UI development

    clip_image001[2] Container element properties should control the layout of child elements for improved maintenance

    clip_image001[3] Images should be incorporated on all buttons and main interaction elements to improve intuitiveness

    clip_image001[4] Views used for popup messages should be generic. All UI elements in these views should be bound to context nodes to promote reuse

    Context:

    clip_image001[5] A standard naming convention should be used for context nodes and elements

    clip_image001[6] Multiple trips to the database or other external objects to access data should be avoided by holding a larger dataset in the Context’s memory

    clip_image001[7] Store data transparently by using the Context rather than buffering through ABAP methods

    clip_image001[8] Populate context data via Supply Functions rather than embedding code in initialization methods

    clip_image001[9] Create standard context nodes in the Component Controller and map to Views. I normally create a context node for holding data related to properties of the views and another for holding user selection information.

    clip_image001[10] Simple data types can be stored in Web Dynpro Attributes rather than the Context. This reduces the amount of code required for accessing the data

    Methods / Actions:

    clip_image001[11] A standard naming convention should be used

    clip_image001[12] Interactions with data and other external objects to the Web Dynpro application should be encapsulated in class objects, e.g. database access, execution of programs etc.

    clip_image001[13] Use Events to trigger private methods in other Web Dynpro views rather than creating methods publicly in the Component Controller

    clip_image001[14] Common calls to update or select context elements can be encapsulated in a method, reducing the amount of code needed

    clip_image001[15] Validation should be performed in the view’s WDDOBEFOREACTION method. If validation fails, the cancel navigation should be called

    clip_image001[16] Validation of UI elements should be linked to the UI element to highlight the erroneous user input

    clip_image001[17] Use Text Symbols rather than message classes to hold literals as they offer language translation

     

    Technorati Tags: ,,

  • An Excel tool to optimise BEx Queries

    I’ve recently created an Excel tool to optimise Business Explorer (BEx) Queries by identifying values to be applied to the query’s characteristic restrictions. It has been designed to optimise BEx Queries used in a predefined workbook that reads and writes data through BExGetData and BExSetData. This tool is very useful for fine tuning your existing queries and will reduce the time it takes to refresh and save values.

    The tool works by comparing an Analysis Grid’s attributes against the current workbook’s BEx formula attributes. All attributes used by the query, but not in the workbook are highlighted, identifying those that can be removed from the characteristic restrictions.

    To use the tool, a temporary sheet should be created in the workbook containing the query you wish to optimise. In this sheet add the BEx Analysis Grid and set it to the query’s DataProvider. Highlight all the grid’s attributes and press the customised shortcut key, I have chosen ctrl + k. The attributes that should be removed from the characteristic restrictions are then highlighted.

    Highlighted_Example

    The tool was built using Microsoft Visual Basic for Applications (VBA). I have created one module to hold the needed procedures and one class to represent the BEx formula data structure. The initial execution of the tool stores all BEx formulas in a global collections object. These formulas are held within the collection object as the new BEx formula data type, making it quick to identify the parameter’s DataProvider. When the user executes the tool, their selected cell values are compared against the collection’s parameters. If the cell values (query’s attributes) are not found in memory, the cells will be highlighted.

    On my initial attempt writing this application I used Excel’s Find method to search for identical attributes. This proved to be very slow, but once I stored the entire workbook’s data in memory and then performed the search, the results were near instantaneous.

    Once this tool has been built, it can easily be imported into workbooks containing queries you wish to optimise. Running the tool is quick and allows easy identification of all attribute values that should be in the query’s characteristic restrictions. Optimising your queries now could save your users a lot of time waiting for server results.

     

     

  • BEx Analyzer's file upload bug when integrated with SAP Portal

    This blog identifies a bug found executing a file upload planning sequence in SAP’s Business Explorer (BEx) Analyzer. I will explain how the bug occurs and describe a solution that can be used to avoid it.

    My current project integrates a SAP Portal with planning functions from Netweaver’s Business Intelligence (BI) platform. One process we have is to use a centrally held BEx workbook to upload an offline file into a planning cube. Technically this is achieved using the transaction RRMXP via a Portal iView that opens a given BEx workbook. The workbook contains a button linked to a planning sequence that uploads an offline file. During this process, the bug occurs executing the planning sequence and the following “GUI_NO_MODE_AVAILABLE” error message is displayed.

    Error_message

    This error occurs because we have executed the RRMXP transaction directly from the Portal without interacting with the SAP server, so the session’s process is running in background mode. The solution to avoid this error is to run the session’s process in an active mode.

    The RRMXP transaction’s program can be easily modified to force the user to logon to the SAP GUI before opening BEx Analyzer. To find which program RRMXP uses, go to transaction SE93 and enter the transaction code. You will see the header information as below.

    rrmxp_heade

    Create a copy of the program and edit the following line’s code by changing the ‘X’ to ‘ ‘ as the passed in parameter value.

       1:  
       2: MODULE user_command_0100 INPUT. 
       3:     PERFORM start_excel USING wbid query 'X'. 
       4: ENDMODULE.
       5:  
     
    Now assign this program to a transaction and change the transaction iView to execute it. If you open the workbook again from the Portal using this iView, you should receive a SAP GUI logon before BEx Analyzer is displayed. The file upload should now successfully run.

    Details of how to assign a program to a transaction can be found in Glen Chamber’s blog below.

    http://community.altiusconsulting.com/blogs/glenchambers/archive/2008/06/08/using-custom-transaction-codes-as-shortcuts-to-abap-programs.aspx

     

  • Periodic Jobs and Tasks in SAP BW

    I thought it is worth highlighting the 'Periodic Jobs and Tasks in SAP BW' white paper by SAP, which gives an overview of the most important maintenance tasks in SAP BW.

    This white paper is an important read for all those designing and supporting a SAP BW system. The following areas are covered:

    • Support package best practices
    • Transport best practices
    • Backup strategies
    • Application and Basis monitoring
    • Performance tuning
    • Data management tips

    The latest copy of the white paper can be found on SAP's Developer Network (SDN) at:

    https://www.sdn.sap.com/irj/sdn/go/portal/prtroot/docs/library/uuid/08f1b622-0c01-0010-618c-cb41e12c72be

     

    Technorati Tags: ,
  • Designing Table Buffering

    An important factor to consider when designing your database tables is the use of buffering. Data access can be up to one hundred times faster reading from the buffer than directly from the database, but choosing to buffer a table may not be the best option depending on its use. This blog will describe the types of buffering available and offer a few tips on whether to use this facility.

     

    Buffering is configured on the Technical Settings of a table.

    clip_image003

    As the above screenshot illustrates, SAP database tables offer three buffering options:

    • Full Buffering: On initially accessing the table, the full content of the table will be read into the buffer.
    • Generic Buffering: A generic area must first be defined that corresponds to the first n key fields of the database table. The data subsequently buffered will be the intersection of this generic area and the accessing query. Note, when generic buffering is used with the number of key fields equal to zero, this will have the same effect as full buffering.
    • Single Record Buffering: Only single records are buffered and the accessing query must use a SELECT SINGLE statement.

     

    Buffering should be used on tables that are frequently read and rarely updated. SAP database tables use a synchronisation mechanism to ensure data integrity, but if the buffered table is often updated then it negates the performance improvement of using buffering. For an example of how buffer synchronisation works please see the below link from SAP:

    http://help.sap.com/saphelp_nw70/helpdata/en/cf/21f25e446011d189700000e8322d00/content.htm

     

    Tables to be buffered should also be quite small to prevent the buffer overflowing. All master data tables are very large, so these should never be buffered. System memory should always be checked before buffering tables, transaction ST02 can be used for this.

    The application programmer should also be aware of statements that bypass the buffer. For a list of these please refer to the below SAP library documentation.

    http://help.sap.com/saphelp_nw70/helpdata/en/aa/4734a00f1c11d295380000e8353423/frameset.htm

    Posted Jan 31 2009, 09:01 PM by AdamAdshead with no comments
    Filed under: , ,

  • Developing Accessible Web Applications with SAP Web Dynpro

    The emergence of the Internet has provided the ability to access web applications across the world and to a vast number of people. Keeping this in mind web applications should have a Universal Design that does not exclude any potential users. In this blog I will give a brief overview of the current accessibility directives for web technologies and then describe how some of Web Dynpro’s features can assist in building more accessible web applications.

    In many countries accessibility to information technology has been led by initiatives, laws and regulations. The most notable is the Web Accessibility Initiative (WAI) which is part of the World Wide Web Consortium (W3C). The initiative provides an international set of guidelines, technical reports, educational materials and other documents that help to improve different aspects of web accessibility. There is also section 508 of the US Rehabilitation Act that has laid out a set of rules designed to help web developers make their sites accessible. SAP has set out some specific Accessibility Guidelines for Web Dynpro to improve accessibility when building web applications.

    Web Dynpro has built-in accessibility checks that are carried out automatically on performing a syntax check. These checks are there to make sure that all user interface (UI) elements have some property set to make them easy to read. For example the Label and Button elements have a check that if the Text property was not filled, then the Tooltip property should be. These accessibility checks will not prevent the application from being compiled, but they will display a warning so the developer can correct them. A full list of these checks can be found on SAP’s help page under UI Element Checks. It is worth noting that these are not carried out when the application is in a temporary development package ($TMP). If you wish to ignore these warnings they can be switched off on the Web Dynpro component properties by un-checking the highlighted check box.

    clip_image003

    Web Dynpro has an accessibility mode that provides additional keyboard accessibility functions and will allow use of a screen reader if one is connected to the user’s computer. To set accessibility mode on, you need to post fix ‘?sap-accessibility=X’ to the URL of the page, or add the WDAccessibility parameter to the application and specify ‘X’ as a value.

    clip_image005

    clip_image007

    Web Dynpro applications are fully keyboard compliant, meaning the user can interact with them using only a keyboard. The developer is not offered the option to configure tab order, this will be defined automatically by the Web Dynpro framework. The order is top to bottom, left to right, within each grouping of elements. Common shortcuts are used like the tab key for navigation, control Z and control Y for undo and redo respectively. A full list of these keyboard commands can be found on SAP’s help page.

    Screen readers are accommodated in Web Dynpro by a few attributes on UI elements. The Accessibility Description is usually found on elements that group other elements, like the Tab Strip or Transparent Container. This property is used to include a title for elements that may not have a visible header. The Label has a similar property called Label For to describe its associated element. Also the Tooltip text is another useful property which is read by screen readers. This should be used to display the UI element’s semantic information. Be careful when setting this though, it is best to add short concise descriptions rather than more lengthy texts that could be confusing. Tooltips should not be used for some elements like the Label because they will not be read by screen readers. Here, it is best to add the tooltip to the object the label is pointing to, i.e. Input fields, list boxes etcetera.

    clip_image009

    To test accessibility texts SAP provides a quick method using an additional ‘sap-accessibility-debug=X’ URL parameter. This needs to be added along with the ‘sap-accessibility=X’ parameter. When this is set, the accessibility text will be displayed in a window at the bottom of the browser. The text will be associated to each element you select on the page. The order of accessibility text will be:

    • Text of the Label
    • Type of the Element
    • Value of the field
    • State of the current field (read-only, modifiable, inactive, not available)
    • Tooltip Text
    • Tutor is additional information about how to use the element.

    It is advised to test each element’s accessibility text is easy to understand while this is active. The Accessibility Guidelines for Web Dynpro provides a full list of other accessibility features that should also be tested, see the section titled ‘Manual Tests at Runtime’.

    In conclusion, Web Dynpro offers the tools to make your web applications accessible to as many users as possible. All of these features are very straight forward to use and in the situation the developer might miss some helpful text, the framework will warn them. I have included a list of useful resources below.

     

    References

    Universal Design - http://en.wikipedia.org/wiki/Universal_design

    Web Accessibility Initiative - http://en.wikipedia.org/wiki/Web_Accessibility_Initiative

    Section 508 of the Rehabilitation Act - http://www.access-board.gov/sec508/guide/act.htm

    Accessibility Guidelines for Web Dynpro - http://www.sapdesignguild.org/resources/Accessibility_Guideline_WebDynpro_external_Version.pdf

    UI Element Checks - http://help.sap.com/saphelp_nw04s/helpdata/en/19/e64941bfb4de2be10000000a1550b0/content.htm

    Keyboard Commands - http://help.sap.com/saphelp_nw04s/helpdata/en/47/60a081df4b3d31e10000000a42189c/frameset.htm

  • Creating a WebDynpro Tree Component based on an InfoObject Hierarchy

    Background

    This blog describes how to create a custom Web Dynpro Tree component based on an InfoObject hierarchy. The tree will use a recursive context node to configure its size at runtime. This will have the benefit that the Web Dynpro tree reflects any future changes made to the underlying InfoObject, reducing future maintenance.

     

    The Data we are Modelling

    An SAP InfoObject is a characteristic that can be stored in a dimension of a cube, such as company code, product, fiscal year etc. InfoObject's can contain master data as attributes, texts or hierarchies. These are all setup in transaction RSA1, under Modelling. The screenshot below shows the hierarchy tab of an InfoObject. The hierarchy has three master data tables:

    1. Hierarchy table
    2. Hierarchy SID tab
    3. SID HierarchyStruc

    clip_image003

    We will be using the Hierarchy table to read the structure of the hierarchy into a Web Dynpro context node. The screenshot below shows the structure of this table.

    clip_image005

    The fields we will use from the hierarchy table to build the tree’s structure are:

    • NodeId
    • NodeName, and
    • ParentId.

    We will also create a join onto the Texts table to retrieve a description of the data. You can find the name of the Texts table by looking at the ‘Master data/texts’ tab of the same InfoObject in transaction RSA1. Note this will need to be an outer join onto the texts table if you require text nodes in your hierarchy. Text nodes have an entry in the hierarchy table but not in the Texts table, so an inner join would not find these records.

     

    Build Overview

    The tree will be built at runtime, level by level, when the user requests it. This means that on initialising the view, only the root node is created. The rest of the tree will be built when the user clicks to display the next level. This event triggered is called OnLoadChildren, we will assign an action to this in the step by step guide.

    I have tried building the entire tree on initialising the Web Dynpro view and then binding it to the context node. I would not recommend this approach though as it is more complex because it requires a routine to iterate through the master data hierarchy, building up the structure.

     

    Step by Step Guide

    Step One

    First we create our model of the data using the Web Dynpro context nodes and attributes. The first node will be the root, with a subsequent parent node and its attributes. The parent node will have a recursive node that points to itself, this allows a dynamic number of levels.

    Two context nodes will be created, one to model the tree and the other to hold data for the currently selected node. The Selection node will be identical to the Parent node with the exception of the recursive node.

    clip_image007

    The Parent context node’s cardinality property will need to be set to 1..n. This allows the node to support multiple children. All other context nodes will have the default properties.

    The attribute's data types are shown below.

      image

    Step Two

    We can now create our tree component and bind it to our data model.

    On the Web Dynpro view, insert a Tree component called TREE and then insert a Tree Node Type component called TREE_NODE within the tree. The TREE component will be mapped to the root of our data model and the TREE_NODE will display the hierarchy we read from the InfoObject.

    I have made the following changes to the default properties of the TREE and TREE_NODE components:

    image

     image

    The data source property is bound to the path of the context node. The Has Children property specifies whether the node can be expanded to display its children and the Text property is mapped to the description, this will show the user friendly name of the node.

    Step Three

    In this step we will create the required methods and actions.

    All required code is found at the end of this blog split into Methods and Actions. The tables below give a brief description of what these methods/actions are used for:

    image

    image

    The following tables display the method’s and action’s parameters.

    image

    image

    Step Four

    Now the actions have been created, we can assign them to our tree component. These are done on the Tree Node Type components of the tree.

    image

     

    The tree should now be complete. This component can be applied to any hierarchy that has been created with the simple adjustment to the name of the hierarchy table and the root node.

     

    Methods

       1: method WDDOINIT .
       2:   DATA:
       3:     lr_current_node    type ref to if_wd_context_node,
       4:     lr_current_element type ref to if_wd_context_element.
       5:  
       6:   lr_current_node    = wd_context->get_child_node( 'ROOT' ).
       7:   lr_current_element = lr_current_node->get_lead_selection( ).
       8:   create_node(
       9:     exporting
      10:       cur_element = lr_current_element
      11:  
      12:       node_name   = 'PARENT'). 
      13: endmethod.
      14:  
      15: method CREATE_NODE .
      16:   DATA:
      17:     lr_cur_node type ref to if_wd_context_node.
      18:  
      19: * create the new node by requesting it as a child node
      20:   lr_cur_node = cur_element->get_child_node( node_name ).
      21:  
      22: * create its elements
      23:   create_element(
      24:     exporting
      25:       cur_element  = cur_element
      26:       cur_node     = lr_cur_node
      27:       node_name    = node_name ).
      28: endmethod.
      29:  
      30: method CREATE_ELEMENT .
      31:   DATA:
      32:     ls_parent             TYPE                  wd_this->element_parent,
      33:     wa_parent             TYPE                  wd_this->element_parent,
      34:     itab_parent           TYPE TABLE OF         wd_this->element_parent,
      35:     lr_cur_element        TYPE REF TO           if_wd_context_element,
      36:     loop_counter          TYPE                  i.
      37:  
      38: **************************************************************************** 
      39: *  Add code to select data from hierarchy and text data into itab_parent 
      40: ****************************************************************************
      41:  
      42:    SORT itab_parent BY PARENT_ID.
      43:  
      44:   IF NODE_NAME = 'PARENT'.
      45:     " Set Root Node
      46:     READ TABLE itab_parent
      47:       INTO ls_parent
      48:       WITH KEY NAME = [root node name].
      49:  
      50:     lr_cur_element = cur_node->create_element( ).
      51:     lr_cur_element->set_attribute( name = 'NAME' value = ls_parent-NAME ).
      52:     lr_cur_element->set_attribute( name = 'DESCRIPTION' value = ls_parent-description ).
      53:     lr_cur_element->set_attribute( name = 'ID' value = ls_parent-ID ).
      54:     lr_cur_element->set_attribute( name = 'HAS_CHILDREN' value = abap_true ).
      55:     cur_node->bind_element( new_item = lr_cur_element set_initial_elements = abap_false ).
      56:    ELSE.
      57:     " Set CHILD Node
      58:     CUR_ELEMENT->get_static_attributes(
      59:       IMPORTING
      60:         static_attributes = ls_parent ).
      61:  
      62:     loop_counter = 0.
      63:  
      64:     LOOP AT itab_parent INTO wa_parent
      65:       WHERE PARENT_ID = ls_parent-ID.
      66:  
      67:       " Determine if node has children
      68:        READ TABLE itab_parent
      69:          TRANSPORTING NO FIELDS
      70:          WITH KEY PARENT_ID = wa_parent-ID BINARY SEARCH.
      71:  
      72:        IF SY-SUBRC = 0.
      73:          wa_parent-has_children = abap_true.
      74:        ELSE.
      75:          wa_parent-has_children = abap_false.
      76:        ENDIF.
      77:  
      78:        lr_cur_element = cur_node->create_element( ).
      79:        lr_cur_element->set_attribute( name = 'NAME' value = wa_parent-name ).
      80:        lr_cur_element->set_attribute( name = 'DESCRIPTION' value = wa_parent-description ).
      81:        lr_cur_element->set_attribute( name = 'ID' value = wa_parent-id ).
      82:        lr_cur_element->set_attribute( name = 'HAS_CHILDREN' value = wa_parent-has_children ).
      83:  
      84:        " Only set the initial element on first child
      85:        IF loop_counter = 0.
      86:          cur_node->bind_element( new_item = lr_cur_element set_initial_elements = abap_true ).
      87:        ELSE.
      88:          cur_node->bind_element( new_item = lr_cur_element set_initial_elements = abap_false ).
      89:        ENDIF.
      90:  
      91:        loop_counter = loop_counter + 1.
      92:     ENDLOOP.
      93:   ENDIF.
      94: endmethod.
     

    Actions

       1: method ONACTIONLOAD_CHILDREN .
       2:  
       3:   DATA:
       4:     lr_context_element type ref to if_wd_context_element.
       5:  
       6: * get the context element at which we are supposed to do load the children
       7:   lr_context_element = wdevent->get_context_element( 'CONTEXT_ELEMENT' ).
       8:  
       9: * create the child nodes, if necessary
      10:   create_node(
      11:     exporting
      12:       cur_element = lr_context_element
      13:       node_name   = 'CHILD' ).
      14:  
      15: endmethod.
      16:  
      17:  
      18: method ONACTIONSELECT_NODE .
      19:   DATA:
      20:     ls_parent             TYPE        wd_this->element_parent,
      21:     lo_nd_selection       TYPE REF TO if_wd_context_node,
      22:     lo_el_selection       TYPE REF TO if_wd_context_element.
      23:  
      24:   CONTEXT_ELEMENT->get_static_attributes(
      25:     IMPORTING
      26:       static_attributes = ls_parent ).
      27:  
      28:   lo_nd_selection = wd_context->get_child_node( name = wd_this->wdctx_selection ).
      29:   lo_el_selection = lo_nd_selection->get_element(  ).
      30:   lo_el_selection->set_static_attributes(
      31:     EXPORTING
      32:       static_attributes = ls_parent ).
      33: endmethod.

     

    Technorati Tags: ,,,,
  • Integrating SAP’s Business Information Warehouse with Web Dynpro

     

    Recently I have been working with SAP’s Web Dynpro for ABAP to create a customised workflow application that is integrated with the Business Information (BI) Warehouse. When considering how to implement the workflow application we first looked at SAP’s off the shelf Status and Tracking System (STS) that is included with BW Business Planning and Simulation. STS met most of our needs but was too rigid when trying to enhance it. To meet our needs we created the web application using Web Dynpro which offers a blank canvas that is completely customisable and can offer a very attractive and user friendly interface.

    The development environment is part of the ABAP Development Workbench allowing it access to the ABAP dictionary like any other ABAP object. This gives us full access to our SAP BI system as well as the rest of the Netweaver 2004s suite.

     

    clip_image002

     

    Web Dynpro is based on the Model View Controller (MVC) architecture to separate the content, logic and layout providing good reusability if you need a similar application used across different business areas. The Web Dynpro component sits on SAP’s Portal offering further functionality to the information repositories and portal services. Below is a screenshot of one of several Web Dynpro components created. This component allows opening a workbook from Business Explorer’s (BEx) Analyzer, sending emails to a dynamic list of users and saving settings to database tables.

     

    image 

     

    We’ve found the final application to be very robust and the performance has been good. The development environment offers a flexible way of storing information in memory using a concept of context nodes as data structures. These structures are adhoc and can be quick to implement if you are copying from similar nodes or a table's structure. Context nodes can also be recursive allowing them to be created at runtime from ABAP code.

  • Using BEx Analyzer's API via VBA

    Introduction

    Netweaver 7.0 exposes the interface for Business Explorer’s (BEx) Analyzer in Visual Basic for Access (VBA) code. This blog describes how we can use this interface via VBA code held in our workbooks.

     

    Why might we want to do this?

    The VBA language  is now in its 15th year of use, it is rich in functionality and offers a wide range of integration with multiple applications and data sources  including the web. Combining this with BEx Analyzer we can automate our tasks between data from a variety of sources and SAP’s Business Intelligence Warehouse. The use of VBA to work with the Application Programming Interface (API) can also be used to work around some of the limitations that we may have with BEx Analyzer's front end.

    Let’s start by looking at the API which comprises of four modules and one class:

    · Common: Usable methods and functions that execute BEx Analyzer’s features.

    · ConnectionHandling: A set of functions used for handling connections.

    · xBExapi: Error handling and drill down state information.

    · xBExPrec: Status information.

    · BExEventHandler: Event handlers to work with Excel’s events.

    clip_image001

     

    To use this interface you first need to create an instance of the class. This is done by executing BEx Analyzer’s add-in, which returns an object of type BExApplication.

    Set BEx = Application.Run("BExAnalyzer.xla!GetBEx")

    Two of the most useful methods provided are BExGet and BExSet, used to read and write data to InfoProviders. To use these methods you are required to pass the address of the data you wish to return/alter as parameters. Below is the header information of these methods to show how these are formed:

    BexGetData(iDataProv As String, ParamArray iParam() As Variant)

    BexSetData(iValue As Double, iDataProv As String, ParamArray iParam() As Variant)

     

    Another useful feature of the API to note is how BEx Messages can be accessed and used. These contain the information that we can see in the status bar of the worksheet and the more detailed information shown if you double click the status message. The API exposes these messages through the Messages function. An example of how these messages can be used is to test whether data was saved back to the InfoProviders. This can be accomplished with the following code:

    Dim obBExMessage As BExMessage

    Dim sTextToFind as String

    sTextToFind = “data was saved”

    For Each obBExMessage In BEx.Messages

    If InStr(1, LCase(obBExMessage.Text), LCase(sTextToFind)) > 0 Then

    bDataSaved = True

    Exit For

    End If

    Next obBExMessage

    This is just a snippet of the automation you can provide using BEx Analyzer’s API via VBA. The best way to learn what else can be achieved would be to read through the API’s Common Module functions and methods.

     

  • Converting a Standard InfoCube to a Real-Time InfoCube while Maintaining Data

    There could be a couple of reasons why you might wish to convert your Standard InfoCube to a Real-Time InfoCube:

    - your user's needs may change and you require the data to be kept closer to real-time, or

    - the amount of data you are loading increases and you're finding the InfoCube's write performance is simply too slow.

    The Real-Time InfoCube supports parallel write access making it much faster compared to the Standard InfoCube. This can be combined with a daemon service that is scheduled to check the InfoSource for any changes, if found the delta is quickly updated.

    How to convert:

    1. Go to the ABAP Editor (SE80) and select Edit Object

    clip_image002

    2. Execute the program 'sap_convert_normal_trans'

    clip_image002[4]

    3. Enter the InfoCube's name and decide the direction of the conversion.

    clip_image002[6]

    Once the InfoCube has been converted it will be ready and any data you previously had in the InfoCube will remain intact.

    Technorati Tags:
    Technorati Tags:
    Technorati Tags: