SAP

Home / Archive by category "SAP" (Page 36)

Web Dynpro – Adding an Icon in a Dynamic Table Column

Here was another fun task I wanted my new ABAP Web Dynpro to be able to add an icon in a dynamic table column.  Again, I expected this to be easy…  well, not as much as I figured, so I thought it might be something you could use.  (and I’m looking for some fun things to write about).

 *** again, start with getting the reference to the table, and then getting all the columns
l_table ?= view->get_element( ID = ‘TB_XXX’ ).
lt_cols = l_table->get_columns( ).
LOOP AT lt_cols into wa_cols.
*** in this example, I want column DOC_ICON to show an icon, rather than text.
IF lv_col_fld = ‘DOC_ICON’.
*** for the correct column, you need to assign an image, rather than the standard text.  In this ***example, I just needed to tell it what to bind for the value (remember, I had this value already,
***so I just need to assign the correct context node.
lv_image = cl_wd_image=>new_image( bind_source = ‘XXX.DOC_ICON’ ).
*** this is the magic.  Telling it what cell editor to use what sets it as text vs. an Image.
Wa_cols->set_table_cell_editor( LV_IMAGE ).
ENDIF.
ENDLOOP.

And that’s the magic…  Hope this can make your life easier…  Because like the catchphrase goes, I learn things the hard way, so you don’t have to.

Web Dynpro – Changing Dynamic Table Header

Well, this strangely was a lot tougher than I expected.  I just wanted the ability to change the column headers based on my own descriptions (or perhaps by language).  Dynamic table header changes took more research than I originally expected, so here’s what I found…  Hope if can help you…

*** get the reference to your table
l_table ?= view->get_element( ID = ‘TB_XXX’ ).
*** get all of the columns so you can name them as you like
lt_cols = l_table->get_columns( ).
LOOP AT lt_cols into wa_cols.
*** Get the text you want to add to the column headings and assign to lv_col_text
lv_col_fld = “column name”.
l_col_hdr = wa_cols->get_header( ).
l_col_hdr->set_text( lv_col_text ).
wa_cols->set_header( l_col_hdr ).
ENDLOOP.

Happy coding =)

Web Dynpro – Creating a Dynamic Table

I hope you’re not getting tired of Web Dynpro.  I will get back to the function SM and VC stuff soon, but lately I’ve been consumed with converting my Rapier product to ABAP Web Dynpro, so as you can guess, that’s where all of my fun learning experiences have been.  For those you tired of this, I promise to be back in functional side again soon.  I’m not finished with my conversion, so that means its time to add new functionality…  Today it’s creating a dynamic table.  For everyone else, I hope you find this useful 🙂

So, to set the stage, a lot of the Rapier functionality is based on dynamic tables.  The idea is that you can define how you want your input and output fields to work.  That means, I needed to be able to build a dynamic table.  I had to a lot of online hunting to pull all this together, but finally got it working how I wanted.  Thought I’d share this with y’all.

I implemented all of this in the wdomodifyview method.

*** Coding for Dynamic Table
DATA: lt_col TYPE cl_abap_structdescr=>component_table,
col like LINE OF lt_col,
struct_type TYPE REF TO cl_abap_structdescr,
table_type TYPE REF TO cl_abap_tabledescr,
node_info TYPE REF TO if_wd_context_node_info,
node TYPE REF TO if_wd_context_node,
tab_XXX TYPE REF TO data,
row_XXX TYPE REF TO data,
l_root TYPE REF TO cl_wd_uielement_container,
l_node TYPE REF TO if_wd_context_node,
l_table TYPE REF TO cl_wd_table,
lt_cols TYPE CL_WD_TABLE_COLUMN=>TT_TABLE_COLUMN,
wa_cols TYPE REF TO CL_WD_TABLE_COLUMN,
l_col_hdr TYPE REF TO CL_WD_CAPTION,
lv_col_text TYPE string,
lv_col_fld TYPE string.
data: lv_image TYPE REF TO cl_wd_image.
data: nd type ref to if_wd_context_node,
nd_list type WDR_CONTEXT_CHILD_MAP,
wa_list TYPE WDR_CONTEXT_CHILD.
data: n type i,
idx TYPE i.
FIELD-SYMBOLS: <table> TYPE table,
<row> TYPE data,
<fs_col> TYPE any,
<fs_col2> TYPE any.

*** build table columns
loop at XXX into wa_XXX where visible = ‘X’.
col-name = “anything”.
*** note, if you use describe_by_name, LV_COL_FIELD must be a table-fieldname combination,
*** then the method will find the data type.  I wasn’t able to find any way to just enter in the date
*** type.
col-type ?= cl_abap_datadescr=>describe_by_name( LV_COL_FLD ).
append col to lt_col.
endloop.

*** build dynamic structure
struct_type = cl_abap_structdescr=>create( lt_col ).
*** returns meta information about the node
CALL METHOD wd_context->get_node_info
RECEIVING
node_info = node_info.

*** this simply checks to see if the node already exists to stop potential short dumps.  This is
***important depending on where you implement this code, and if it runs multiple times.
nd_list = wd_context->get_child_nodes(  ).
READ TABLE nd_list with KEY name = ‘XXX’ TRANSPORTING NO FIELDS.
if sy-subrc <> 0.
*** creates info object and adds it as a lower level node      CALL METHOD node_info->add_new_child_node(
exporting
name = ‘XXX’
static_element_rtti = struct_type
is_static = abap_false
RECEIVING
child_node_info = node_info ).
endif.
*** child node of lead selection or specific index
CALL METHOD wd_context->get_child_node
EXPORTING
name       = ‘XXX’
RECEIVING
child_node = node.
clear n.
n = node->get_element_count( ).
if n = 0.
*** Return RTTI object for sturcture type of static attributes
CALL METHOD node_info->get_static_attributes_type
RECEIVING
rtti = struct_type.
endif.

*** now you have all of the context nodes created…  next up, creating the table.
*** create table
table_type = cl_abap_tabledescr=>create( p_line_type = struct_type ).
FREE tab_xxx.
CREATE DATA tab_xxx TYPE HANDLE table_type.
ASSIGN tab_xxx->* to <table>.
refresh <table>.

*** create lines
FREE row_configequiphis.
CREATE DATA row_xxx TYPE HANDLE struct_type.
ASSIGN row_xxx->* to <row>.

*** populate the values for the table.  Don’t worry too much about this implementation.  This is
***uses dynamic tables to populate the structure.  What you need to do is populate all of your
***rows and columns to make a table that will be bound to your new table.
LOOP AT wd_this->it_xxx INTO wa_xxx.
loop at wd_this->it_xxx into wa_xxx.
ASSIGN COMPONENT wa_xxx-yyy OF STRUCTURE <row> to <fs_col>.
if sy-subrc = 0.
ASSIGN COMPONENT wa_xxx-yyy OF STRUCTURE wa_xxx to <fs_col2>.
if sy-subrc = 0.
<fs_col> = <fs_col2>.
endif.
endif.
endloop.
APPEND <row> to <table>.
ENDLOOP.

*** bind the table
node->bind_table( new_items = <table>
set_initial_elements = abap_true ).

*** build table
l_root ?= view->get_element( ‘TC_TABLE’ ).
l_node ?= wd_context->get_child_node( ‘XXX’ ).

cl_wd_dynamic_tool=>create_table_from_node(
ui_parent = l_root
table_id = ‘TB_TABLE’
node = l_node ).

There’s all the magic.  It’s as simple as creating the nodes, populating those nodes, and then binding them to the table.  Sounds easy right???  as you can see from the code above, it was a lot more complex than I imagined.  Hope this makes life easier for you.

 

Web Dynpro – Logoff Button

This one turned out to be pretty easy, but it sure did take some effort to get to that point…  I guess that’s the irony of it all.  ha ha ha.  So, here was my goal.  I have a web dynpro application that uses a generic user to login as the default.  Then you login with an internet user.  Now the trick that had me stumped for a while was how do I log off the internet user, and reset the application back to the initial login screen the default user.  So this is my solution for creating a logoff button that would reset the transaction back to my original internet user.

I’m sure this sounds easy to any of you Web Dynpro experts out there, but it had me hunting through textbooks, google and my few Web Dynpro contacts.  Finally came up with the trick…  so here you go.

First, in your main window, you need to create an outbound exit plug.  Be sure to give it a parameter of URL.

I recommend setting a context element to hold the intial URL.  You’ll need it later.

Next, in the main view, give your button or however you want to execute the log off procedure.

Once you call the log off procedure, you simply need to take the initial URL and add ‘?logout_submit=true’ to the end.

Here’s an example:

CONCATENATE lv_e_url ‘?logout_submit=true’ INTO lv_e_url.
data: L_REF_MAIN_WINDOW type ref to IG_XXX.
L_REF_MAIN_WINDOW =   WD_THIS->GET_XXX_CTR( ).
L_REF_MAIN_WINDOW->fire_LOGOFF_EXIT_plg( URL = lv_e_url ).

Note:  XXX is the main window name.  LOGOFF_EXIT is the exit plug name.

See what I mean…  it really is that easy =)  good luck.

 

 

ABAP – Suppressing BAPI Messages

I just learned a fun trick when using a BAPI.  I’ve been designing a dynpro transaction and I used a BAPI to pull some information.  What I discovered is that certain BAPI’s have some messages that automatically get displayed, and also caused a weird behavior of leaving the screen (without requesting it.  ha ha ha).  So today I talk about suppressing BAPI messages within a method or form.

Well, I learned a quick fix for this, when calling a function, add the DESTINATION = ‘NONE’.

this will suppress the messages of the BAPI, and just execute the data retrieval I was looking for.

This is a quick one…  I hope you find it useful.

ABAP – Refresh ALV Grid

I recently had to go through and add a button to refresh ALV grid in a custom transaction.  I initially expected this to be easy.  And looking back, it actually is pretty easy, if you kept your program modular.  However, I had to handle things differently than I expected.

I thought I would need to do something with the refresh button that comes with the standard ALV grid.  However, after a some extensive google digging, I couldn’t find anything that told me how I could do that.  Everyone else took care of the issue by creating their own button.  Here’s the basic steps to do it yourself.

You will need to setup the following 2 handlers.  I created a local class to house these methods.  You can take care of it anyway you prefer.

DATA: l_event_receiver_grid TYPE REF TO lcl_event_receiver.
(where lcl_event_receiver is the local class)

SET HANDLER l_event_receiver_grid->on_toolbar_add_button
FOR grid.
SET HANDLER l_event_receiver_grid->on_user_command
FOR grid.

For the add_button:

DATA: ls_toolbar TYPE stb_button.
MOVE ‘ZRFO’ TO ls_toolbar-function.
MOVE ICON_REFRESH TO ls_toolbar-icon.
MOVE ‘Refresh’ to ls_toolbar-quickinfo.
MOVE ‘ ‘ TO ls_toolbar-disabled.
APPEND ls_toolbar TO e_object->mt_toolbar.
this adds a button that looks exactly like the standard refresh button.  You can feel free to play around with the look and feel, but this will get your started.

In the on_user_command, you will need to look at sy-ucomm, and find when it matches ZRFO (in this example).

refresh grid table.
rebuild the grid table

then call the display method.  For me, I uised the set_table_for_first_display method.  So updating the grid table and calling this is enough to perform the refresh.

This will give you a great start if you want to add a refresh button your custom transaction.

I hope you find this helpful.

Network – Changing Internet Providers

Well, I discovered a whole new challenge recently.  We changed cable providers, and upgraded our internet.  It all seemed so easy.  A couple of minor tweaks, and everything would just keep working, right???  not so much.  Here’s what I discovered you need to remember when changing internet providers and still keep your SAP system exposed to the outside world…

Even if you don’t change providers, they might change the box for your signal.  In my head, that meant nothing.  When I went to connect to my SAP systems, it meant everything.  Here’s what I found.

1.  Changing providers or even changing modems can change your IP address.  So, if you’re changing things,  make sure you check this right away.  My previous post on this stuff talks about some of the steps.  www.whatismyip.com is your quick check.

2.  Now, a changed IP address unfortunately means that if you are using subdomains (like I am), you need to go to your host provider and change the IP address they are pointing to.  I hate this part because it can take up to 24 for the changes to circulate through the internet.

3.  Next up, I lost all of my expections.  So I needed to go into my router configuration and create/add the firewall expections (80XX & 32XX) for the web and for the gui connections.

4.  While you are in there, double check that the static IP addresses are still connected to your machines.  If you lost those too, re-add them.

Now, if you’re lucky, everything will be back to normal in a day.  For me, it took 2, because I didn’t catch that the IP address changed until a day later.  Short story, be sure to test right away from outside of your network to make sure everything is still working.  Good luck, and try not to change your internet provider if you can avoid.  ha ha ha

Variant Configuration – Replacing a Characteristic that is in Use

Something I’ve been dealing with quite a bit lately is remove or replacing a characteristic that is in use in a model.  Now I hope that this only occurs in your development environment, but regardless, the same rules apply.  So I just wanted to outline the basics of accomplishing this removal/replacement of characteristics.

1.  Txn CT12 – this is your best friend in this instance.  Using CT12, and selecting all of the options, will show you where it has been used.  One bad thing about CT12 is that enter in the value doesn’t necessarily work, at least in my opinion.  I tend to get a lot more results than just the cstic using that value.

2.  CU22 – this one is optional, but if your where used shows a constraint or constraint net, this is the next thing you’ll need to do.  Go into the CNET, and lock any constraints that use the characteristics.  This process is a bit tedious, but it’s the only way to accomplish it.

3.   CU50 – Interface design – again, you might not be using this feature, but if you are, you’ll see it in your where used.  Be sure to remove the characteristic from every interface design it exists in.  You won’t be able to delete this from the class if it’s still used in the ID.

4.  CL02 – now once these steps occur, you finally go into the class and remove the characteristic.  Just a note, if you already have configurations out there using the cstic or if the class is part of a class hierarchy, you will need to use CL6K in order to remove the characteristic.

5.  CU02 – now you can change all the standard dependencies to either remove the cstic or replace it.  Now remember, you need to pay attention to the logic here because it might not be a simple replacement.  Only you can determine this.

6.  CU22 – change and release the constraints that used the old cstic.  (steps 5 & 6 are interchangeable).

These are the big pieces.  Keep in mind, you may also have tables or functions.  In that event, you will need to update CU60 & CU62 for the tables, and CU66 for the functions.  But only after you’ve done steps 5 & 6.  Then you might need to revisit steps 5 & 6 based on your table/function changes.

I hope this is useful for you.

Web Dynpro – Visible Binding

Ok, I confess, I’m writing this in advance, because I’m sure the trade show will keep me busy… and afterall, I am in Vegas as you read this =)  Now that’s out of the way, I still wanted to give you something to learn.  So, today I picked up a new trick.  I wanted to make an element dynamically appear or disappear depending on what happens in the application.  The concept is called Visible Binding.  Every element has an attribute called visible, and you can dynamically change the value by binding a variable to that attribute.

It turns out, it’s pretty easy, with just a little bit of effort.  So, here’s what you need to do…

1.  Create a context attribute.  it should be of data type wdui_visibility (I think wdy_boolean would also work).2.  Next, for every element you want to dynamically control, be sure to bind this context attribute.
3.  in your method, you simply need to set the value of the context attribute to 1 for invisible, 2 for visible.

This last part was the part that threw me off, I kept trying 0 & 1.

Have fun… and wish me luck.  If all goes well, I’m making sales right now =)

 

Web Dynpro – Invisible Element

Well, since I’ve been spending a lot of time lately doing my Web Dynpro conversion, it’s time for another lesson I learned 🙂  Today I want to talk about the Invisible Element (InvisibleElement).  It’s a pretty handy little unit that I was always looking for in my  BSP design.

Often times, if you are using a grid layout or matrix layout, you need a placeholder.  In my case, I had a whole list of input fields to show on a screen, but I wanted to skip some rows between certain elements.  In the BSP world, you were stuck using a text field with a period or something, so it took up the space in the row, but was “nearly” invisible.  Now Web dynpro provides you an element to do exactly this.

The big trick to remember is if you are using the Matrix Data, make sure that the Invisible Element is Matrix Head Data, so it will skip the entire row.  Otherwise, there really isn’t anything fancy, except knowing that it exists. =)

Alright, there’s today’s tip.