ABAP Coding

Home / SAP / Archive by category "ABAP Coding" (Page 5)

ABAP – Optimizing your Code using SE30

One of my favorite tools when I’m developing is transaction SE30, ABAP Runtime Analysis.  I’ve been using this a lot more lately in an attempt to optimize my code in my Service Management Dashboard.  Whenever you deal with a dashboard, you are always hitting a lot of different tables, as well as implementing a lot of different code.  Using SE30 is a great way to quickly see the biggest pain points in your code.  Let me walk you through the basics of using it.

I’ve highlighted the 4 biggest fields you need to enter to execute it.

1.  Description
2. Transaction/Program/Function Module – I’m a fan of transaction whenever it’s available, but pick what you have.
3.  Execute Button – press when you populated everything else.
4.  Variant if you have one.

Press execute button, and you’ll see your program/transaction.  Execute all the steps you want to analyze.  Be careful with this step.  You maybe want to pinpoint certain parts of the transaction, and if you click too many options your results could be scewed.

When you’re done, you’ll this on the bottom.  Press Evaluate, and now you can start the real work.

This next screen will show you where all the work is, is it in ABAP, the Database, or the system.
PRess F5 to start the hit list.

Now, here’s all the information.  The column I tend to pay the most attention to Net %.  I will typically sort on this column to see where the worst performing code is.  Now you do need to be aware, that a lot of times your problems can be “obscured” if you code is too modular.  You may simply see that most of the time is in one function call or one method call.  So you may need to “throw” those numbers out and pay attention to next items on the list.  But i’m sure you’ll figure that out quick enough
Thanks for reading.

ABAP – Select Statement Optimization

Today, special thanks go out to my buddy Jeremy.  He set me straight on some things, and helped me streamline my code in my service management dashboard.

I’m quickly learning that my system works great, except when it comes to volume testing.  (I’m working on this in a separate initiative).  But back to my original thought.  The select statement.  I found out recently that using the SELECT with an ENDSELECT Statement to close it off, and then add some logic in the middle is terrible when it comes to database performance.  Take this example:

 

Select vbeln posnr from VBAP into (lv_vbeln, lv_posnr)
for all entries in table LT_TABLE
where pstyv = ‘TAC’.
<add some logic here>
endselect.

While this code works, and will produce the correct results, as the table VBAP grows, so will the runtime.  Now, the better approach (thanks Jer), is to build and internal table first, then loop through it…  like this.

define a type and a table for lt_result with the fields you want (vbeln & posnr)

Select vbeln posnr from VBAP lt_result
for all entries in table LT_TABLE
where pstyv = ‘TAC’.
loop at lt_result into wa_result.
<add some logic here>
endloop.

Now, this will improve performance, but the real trick to employ if you need to improve performance is to provide an index on the table you are seeing poor performance.  In essence, the index on a table is a lot like changing the key fields set for the table, and allows for faster searching.  This obvious involves a basis person and some additional storage space.  So, if you need to improve performance use the following guidelines.
1. try to set the key fields in the where statement.
2. avoid the select/endselect combination.
3. if using inner join, make sure you need to do it, and try to limit the number of inner joins to 2 or 3 tables max.
if you follow these guidelines, you code should work in nearly any enviroment.
Again, thanks Jer.  And for everyone else, Thanks for reading.

Variant Configuration – VC_I_GET_CONFIGURATION Issues

Well, it’s funny, just yesterday we were talking about interface design and the printouts, and here we are already finding an issue 🙂  Well, I came up with a great idea of having multiple Sales Printouts, and using the function: VC_I_GET_CONFIGURATION to just call it by Sales Printout and by the name of the UI Char group.  Well, unfortunately, I found that char group is not one of the parameters you can send into VC_I_GET_CONFIGURATION.  This was highly disappointing to me.  I did a little debug work, and found that it’s even more confusing than that.  If you create multiple Interface Designs with the same printout checked (for example, Sales Printout is selected on 2 different char groups) then it will only display the characteristics common in both groups.  Confusing???  well it was to me too.  So, let me explain a little better…

Char group 1 (sales printout has been checked)
Cstic 1
Cstic 2Cstic 3

Char group 2 (sales printout has been checked)
Cstic 2
Cstic 4
Cstic 6

If you execute: VC_I_GET_CONFIGURATION for sales, then it will only return Cstic 2.

I really don’t understand this behavior, but it’s what the function does.

Now… there is one potential, so bear with me…

Option 2 is a bit more involved, and depending on the requirements may not even be an option.  Here is the basic concept.  We would create a “super” UI for “engineering” that would be used for production orders and the like.  Then each characteristic (within the model specific class) could have an organizational area set.  We could create an organization for each plant (or each breakdown needed).  We could then assign all the applicable org areas to each characteristic, and the function module above is able to take into account the org areas in what it prints.  Since this is confusing, here’s an example…

Org areas available:

1-Plant 1
2-Plant 2
3-Plant 3
4-Plant 4
5-Plant 5
Etc…

Plant 1 only wants to see: Char 1, char 2, char 3.
Plant 3 wants to see char 1, char 3, char 5, char 7
Plant 5 wants to see char 1, char 4, char 7, char 10.

The Class would have the following:

Char                       Org Area
CHAR 1                 1, 4 , 5
CHAR 2                 1
CHAR 3                 1, 4
CHAR 4                 5
CHAR 5                 4
CHAR 6
CHAR 7                 4, 5
CHAR 8
CHAR 9
CHAR 10               5

So our UI (interface design) for engineering would contain:

CHAR 1
CHAR 2
CHAR 3
CHAR 4
CHAR 5
CHAR 7
CHAR 10

Now, when plant 1 prints the production order, we would call the function above with Org Area = 1, Engineering = X

The function will then pull the “super” UI, and then strip out anything that doesn’t have Org Area = 1.

Now keep in mind, VC_I_GET_CONFIGURATION can read the org areas, but I haven’t fully proved out this idea.  If anyone has a better idea to do something like this, I’d love to hear it.

So, there’s your forray into the mind of a crazy VC modeler.  Thanks for reading.

 

Development – Be Careful when Switching Gears

Today I wanted to talk about a general thing I’ve experienced, and I’m slowly learning from.  Switching gears.  By that I mean jumping from one project to another.  If you’ve checked out the products we’ve designed, you’ll notice that there are some very different items in the list.  Some are SM, some are PP, some VC and some even MM and WM.  So what?  So…  it means they are are all radically different from each other (and perhaps I’ve wandered too far away for some of them, in search of more sales).  Inevitably, it’ll happen though.  Even if you only have 2 different projects you’re working on, you might be asked to jump over to the other project…  so, how can you make that as painless and efficient as possible?  try this approaches..

My favorite, if you can, finish up what you’re working on.  Right now, I’ve been working on a big Web Dynpro addition, but there is interest in one of our MM utilities.  These 2 things have nothing in common.  So I chose to finish up the piece of the Web Dynpro that I’d been working on for the past 2 weeks.  Why?  because when you shift gears, you forget what you were doing, you have to spend an hour or so remember where you left off, and what you still wanted to do.  If you have the option, get yourself to a good stopping point before you move on.  It’ll save you a lot of time (and headaches).

Multi-task when you can.  I know this is a little counter-intuitive, but if you can spend even an hour a day on the first project, you’ll keep all your ideas fresh (even things as simple as where to put the breakpoint).  This will keep you from forgetting where you left off.  Option 1 is still better, but this will help without diverting too much attention away from your new priority.

Take good notes.  (often you’ll do this one no matter what).  Be sure to not everything you haven’t done yet, maybe little techniques you used that you might forget (I use this blog for that), or even just bullet points of what you were working on, and where to start when you can return to this.  It sounds obvious, but I’ve forgotten to do this more than one.

I know, none of this is rocket science, but keep this ideas in mind.  We all get pulled away from what we  “want” to work on, in order to do what we “have” to work on.  So make it as easy as you can to jump right back where you left off.  Thanks for reading.

 

Variant Configuration – using CS_BOM_EXPL_KND_V1 for VC BOM Explosion

Here’s a fun little tidbit.  A recent client was looking for ways to get the BOM from a sales order line item before if hits the planned order/production order phase.  Particularly when you deal with large or expensive manufacturing, you planning/procurement groups might need a heads up on what components will be needed long before it hits MRP.  In that case, you can use the ABAP Function:  CS_BOM_EXPL_KND_V1  This function with a few inputs will provide you the complete BOM for the sales order configuration.  Here’s what you need to enter to make CS_BOM_EXPL_KND_V1 work:

VBELN & VBPOS…  easy one here.  the sales order & line item you want to explode.
WERKS – the plant it should be exploded in
MTNRV – this is your configurable material (KMAT)
EMENG – the quantity of the line item
DAVTUV – the explosion date you want to use (important if you use ECM on the BOM)
CUOBJ – this is the configuration to use ( you can find this in VBAP)
CAPID – this is your BOM type.  PP01 or SD01 are the most popular
MMory – set this to 0 (not sure if this is required)
MEHRS – set this to X (again, not sure what this is for)

If you set these values, BAM, you get your VC BOM before MRP does.  Hope you find this useful.

 

Project Management – Redesigning your baby

Well, lately I’ve been spending a lot of time on the rework of Rapier.  I’m sure you’ve noticed some of my posts in the past.  My original baby, Rapier, started as a crazy idea I came up with on a plane ride  home from my project in Boston.  Rapier started as a BSP application, then when I realized that BSP was a dying technology, I moved to ABAP Web Dynpro.  Now, I’m moving to add a ton of new functionality to the application that started it all.

Now, with all of these new ideas, it forces you to revisit what you originally designed, and come at it from a new perspective.  While that sounds obvious to any developer, it comes with a price that I’m not sure everyone realizes (I didn’t at the time).  When I first converted to Web Dynpro, I left most of the original structure intact, and focused on the web dynpro conversion and understanding that new coding.  Now that I’m full blown into version 2 functionality, I’m realizing there are a lot of pieces that could be designed better.

This post is to remind you that a simply adding new functionality comes with a lot of additional work.  For example, I’m looking at adding a new product designed around the field service engineer.  There is a lot of shared functionality between the 2 products.  So that required me to reevaluate all of my tables and classes, so they could easily shared.  Suddenly, this meant that all of my tables, classes, etc. needed to be created under a new shared namespace.  All of those items then needed to be swapped out of the existing code, etc.  Get the picture?  simply letting my code be reused, caused a huge chain reaction that took almost a week to reconcile.  And all of this wasn’t changing any functionality.  Just renaming things.

So, the word of advise for today is to remember that when you redesign, add plenty of time to your schedule.  If you choose to do it right, it’s gonna take longer than expected.  It’s worth it in the long run, but everything comes with a price.

 

Web Dynpro – Testing a Dynamic Table

Now, since I always learn things the hard way, and if you’ve been reading my posts for any length of time, you’ll know that I can be a bonehead when it comes to things…  but I’m too stubborn to give up (hence why I’m writing this post.  ha ha ha).  Anyway, my latest discovery was in the testing of my new dynamic table.  I really needed a table with some editable fields, but in the creation of my table, the context node was empty.  So the table was being created, but there were no lines in the table.  Well, maybe it was the lack of sleep, but my brain was moving a little slow, so I didn’t grasp that the dynamic table was empty…  thus, impossible to see if there were any fields editable.

So, short story, you need to populate at least one row in the table, even if it’s empty.  Here’s an example:

* navigate from <CONTEXT> to <NOT_ITEM> via lead selection
lo_nd = wd_context->get_child_node( name = wd_this->wdctx_item ).
lo_nd->get_static_attributes_table( importing table = lt ).
IF lt IS INITIAL.
APPEND wa to lt.
lo_nd->bind_table( new_items = lt set_initial_elements = abap_true ).
ENDIF.

this simple addition, and suddenly I could see my editable fields in my dynamic table.  Probably obvious to a lot of folks, but yet another lesson learned in my never ending journey.

Thanks for reading.

 

ABAP – Web Dynpro Dynamic Table, again

Well, as it turns out, I didn’t figure out everything I needed for a dynamic table.  =)  The dynamic table code that I previously talked about works great, until you want to control the read only vs. editable aspects of the table.  I found a great way of creating a Dynamic Table in ABAP Web Dynpro that gives me the control that I needed to do allow for editing.

First things first, you need to create a context node and the attributes for to define the table.  You could do this dynamically, but I’m finding it’s cleaner to build it normally.  Either way, once it exists, here how to build the dynamic table.

*** create dynamic table for Notification – Items
cl_wd_table=>new_table(
exporting
id = ‘TB_TABLE’
bind_data_source = ‘CONTEXT_NODE’
visible_row_count = 5
read_only  = abap_false
receiving
control = l_table ).

*** build table columns
loop at <cols> into wa_config.
wa_cols = cl_wd_table_column=>new_table_column( ).

*For Dynamically creating Input Field
CASE type.
when ‘TEXT’ OR ‘TIME’ or ‘DATE’ or ‘DROPDOWN’.
CALL METHOD cl_wd_input_field=>new_input_field
EXPORTING
bind_value = lv_bind
id         = lv_id
state      = lv_state
read_only  = abap_false
on_enter   = ‘ON_ENTER’
RECEIVING
control    = lr_input.
wa_cols->set_table_cell_editor( lr_input ).
when ‘CHECK’.
CALL METHOD cl_wd_checkbox=>new_checkbox
EXPORTING
bind_checked = lv_bind
id           = lv_id
state        = lv_state
RECEIVING
control      = lr_check.
wa_cols->set_table_cell_editor( lr_check ).
ENDCASE.
ELSE.
CALL METHOD cl_wd_text_view=>new_text_view
EXPORTING
bind_text  = lv_bind
id         = lv_id
RECEIVING
control    = lr_textview.
wa_cols->set_table_cell_editor( lr_textview ).
ENDIF.

l_col_hdr = cl_wd_caption=>new_caption( ).
l_col_hdr->set_text( lv_col_text ).
wa_cols->set_header( l_col_hdr ).

l_table->add_column( wa_cols ).
endloop.

l_root ?= view->get_element( ‘TC_XXX’ ).
grid_data = cl_wd_grid_data=>new_grid_data( l_table ).
l_table->set_layout_data( grid_data ).
l_root->add_child( l_table ).
Now this code obviously won’t work out of the box, but you should be able to get the idea of how to use it.  If you have questions on this let me know and I can expand on the code provided.  Thanks for reading.

 

ABAP – How to Spool SD Output Documents

Well, this is a continuation of my post from yesterday, so if you missed it, I talked about using the ABAP Web Dynpro Download element to display documents on your web application.  What I talked about yesterday was completely based on having a spool job to convert.  So…  today I’ll talk about how you can Spool SD Output Documents again and again, and easily retrieve them.

SUBMIT RSNAST00
WITH S_KAPPL = i_kappl
WITH S_OBJKY = i_objky
WITH S_KSCHL = i_kschl
WITH P_AGAIN = ‘X’
WITH P_SUFF2 = lv_suff2
AND RETURN.

You might already be familiar with the program RSNAST00, but who knew you could use it for this (I didn’t…  =>  ).  You’ll notice, it’s a pretty simple program.  You give the Output type, the document key, and you can even using define a special key field (SUFF2) that makes it easier to retrieve.

After you run the program, simply go to table TSP01 and enter in the enough criteria to pull out the spool. Then you simply assign this to a context element, and link it to your download element.  And by doing this it will give you another popup window in your favorite web browser showing your output.

Now for my shameless plug.  I’ve done this all in Rapier now (it’ll be released in version 2 this fall), but thanks to this technique, I’ve been able to output Order Confirmations, invoices, etc…  directly onto the customer website, so they pull their own documents anytime they want.  If you’re interested in seeing this in action, let me know and I’ll be happy to setup a demo to show you.  Rapier 2.0 is gonna be really cool.  I’ve been putting a lot of hours into this recently, so you’ll want to check it out.  And, remember, if you’re in the market and you buy now, you get the charter customer price, and the ability to influence functionality that will be officially released this fall.    Ok… commercial over… =)

Thanks for reading,

ABAP – Using Web Dynpro Download Element

One of my recent adventures was find a way to pull documents out of SAP, and display them within my web application.  This turned out to be rather challenging, but I learned some neat tricks about ABAP Web Dynpro along the way.  The Web Dynpro Download Element is one of my new favorites, once I figured out how I could use it.

Let’s set the stage.  You have a document withing SAP that you want to display to your web user.  The Web Dynpro Download Element works perfectly for this…  provided you can feed it the proper data.  What I figured out is that in order to make this work, you need to get your document into an XSTRING format.  I think this is a RAW string or something like that, but it’s not important.  What is important is how do you get it into the XSTRING format.  One of the cool tricks I found online was using the following function module:

CONVERT_OTFSPOOLJOB_2_PDF

This function will convert a spool job into the XSTRING format you need to output it.  Now, getting things into the spool can be another headache, so tomorrow I’ll talk about how to get your standard SD documents into the spool again so you can read them out of the Web Dynpro Download Element.

Thanks for reading,