SAP

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

Variant Configuration – OEWB – Order Engineering Workbench

Lately, my life has been heavily involved with VC.  For those of you reading me for a while, or my friends that humor me by reading my ramblings J, you know that my loves are VC, SM & development.  I know, a weird combo, but it’s served me well, and I hope that JaveLLin Solutions will soon become my primary source of income…  Anyway, on a recent gig I was trying to “sell” VC to a company.  They have SAP, and do configuration, but all using excel, Access and other outside tools.  They are heavy on the ETO (engineer to order) side of the house, so naturally, I love VC and encouraged them it was the way to go.  They were very heavy into engineering change management, and often had many changes for a single order (even after production may have started).  So this brought up the good old Order Engineering Workbench (OEWB) again.  For those of you unfamiliar with this tool, it’s a much nicer tool for dealing with order BOM’s than the standard CU51 (which is just as ugly as CU50.  Ha ha ha).  It’s designed by SAP, but of course, you have to pay for it if you want to use it…

I am a fan of OEWB since I helped implement it a couple years back.  So I know it works and tends to make life much easier, especially if you have a lot of changes to make.  I’m currently working to try to get a copy of it in my dev system, but SAP in their infinite wisdom is making it difficult for me to try to help them sell (smart business right there, who wants a free sales force anyway).  Ok…  enough my whining…  I like the OEWB because it comes in a nice tree format, gives you clear visibility to what you have changed, allows you to do side by side comparisons of different order BOM’s.  It even gives you versioning ability, so in the case of the client I was at, would be a big bonus to quickly show what version or how many changes had occurred.  I’d love to show you some screenshots, but alas, I can’t add it to my system.  If I can get it eventually (without paying for it of course, I’ll post more about the functionality along with screen shots).

Now, one of the things I’ve been looking for (and If any of you have seen this, let me know) is an easy way to copy an order BOM.  In some of my recent contracts, I’ve seen a reoccurring theme of a customer wanting the exact same product that they ordered 2 week, 2 months, or 2 years ago.  Since it was an ETO product, there wasn’t a permanent part number.  The easiest way would be to copy from that order BOM to the new order BOM.  It’s easy to get the configuration copied… but not the BOM.   I’m toying around with the idea of adding some Order BOM tools to Velocity, and this would be one of them… if it doesn’t already exist.  Anyway…  that’s all for today.  Happy Configuring!

 

Web Dynpro – Dynamic Drop Down Lists

Now as promised, creating the dynamic drop down lists.  I mostly skipped these in my previous post just because there are some extra steps, and rather than cram everything together, it seemed like a good point to break it up.  Keep in mind, the concept is the same as my previous post, only for a dropdown list, you need to build the list as well.   (See my previous post for all of the other data declarations).

Hope you find this useful, and as always, if you have a better way to do it, please let  me know. J

DATA LV_BIND_DROP TYPE STRING.
*** check for dropdown fields
dyn_children = rootnode_info->get_child_nodes( ).
READ TABLE dyn_children with key name = field TRANSPORTING NO FIELDS.
CHECK sy-subrc <> 0.
* create sub node of structure (tablename)
* I created a tabletype/structure for DROPDOWNNODE.  If has fields of Key &

* value
cl_wd_dynamic_tool=>create_nodeinfo_from_struct(
parent_info = rootnode_info
node_name = dyn_attr_info-name
structure_name = ‘DROPDOWNNODE’
is_multiple = abap_true ).
*** the On_enter is only if you want something to happen when a value

*** is selected.  I used it to set another context variable.
CONCATENATE LV_BIND ‘.VALUE’ INTO LV_BIND_DROP.
CALL METHOD cl_wd_dropdown_by_idx=>new_dropdown_by_idx
EXPORTING
bind_texts = lv_bind_drop
id         = lv_bind
state      = lv_state
on_Select  = ‘ON_ENTER’
RECEIVING
control    = lr_drop.

*** first, build up the list any way you want and put it into a table with

*** 2 columns, 1 key, 1 value
lo_nd_app->bind_table(
new_items            =  value_list
set_initial_elements = abap_true ).

*** if you want to specifically set a value for the dropdown in advance, here

*** just use this.  The tabix is for the value_list you populated.

lo_nd_app->set_lead_selection_index( sy-tabix ).

Variant Configuration – Avenue Health Check

In my most recent contract, I’m working with a company called eSpline.  They are one of the more established players in the VC consulting community.  It’s funny, because I’ve met the people that run the company at the Configurator Work Group several times, but this is the first time our paths have crossed professionally.  Anyway, back to my point…  eSpline has a pretty handy little tool for performing a Health Check.  It seems to be relatively new, but it has some powerful features.  It’s called the Avenue Health Check Tool.

The idea behind it is that you dump a model (or group of models), kinda like a knowledge base, and then their tool goes through and figure out all the issues, warning and “less than best” practices.  For example, it will detect “Zombie” characteristics in a class.  This is anything that has no dependencies, tables or functions associated with it.  Now there are multiple explanations for this, sometimes you need an information cstic to pass down to manufacturing, but there are no rules around it.  Simply a selection made by order entry.  Or, it could be a characteristic that a change was started, then rethought, and finally left there to hang out, forgotten in a sea of other characteristics.  At least being able to simply identify these characteristics, gives the modeler an easy hit list to confirm or deny if there is a problem.  Some of the other things that are really handy include flags to tell you if anything won’t transfer to the IPC.  In a recent post, I talked about the long oss note for functionality that doesn’t work in the IPC, but does work in VC.  The Health Check will quickly flag all of those items for you.

The health check is in an HTML type format, so it’s easy to jump to things that are connected, and even has some fancy images to show you how classes are connected, or BOM structures work.  I was impressed by the features, so I wanted y’all to know about it.  If you happen to check out their stuff, be sure to let them know I sent you.  =)

 

Web Dynpro – Dynamically adding Screen Elements

Now, one of the big things I needed for Rapier is to have the screens be completely configurable.  In BSP, this accomplished mostly in the page fragments by doing some looping.  This concept doesn’t exist in ABAP Web Dynpro, so I needed to learn how to do it in Web Dynpro.  Here’s what I learned for dynamically adding screen elements to web dynpro view…

First and foremost, if you want to make dynamic elements in a view, you need to have an attribute to go along with it.  As I use Web Dynpro more and more, this is becoming clear to me why.  The easiest way to get a value onto a screen is using a bound attribute.  So you have 2 choices.  You can create every possible attribute in your view, and use some logic to call the correct one, or you can dynamically create the attributes you need.  While either option “could” work for me, I chose to do this dynamically.  Based on future testing/performance, I may change in the future, but regardless, a fun trick J  Once you have the attribute, you can create the element.  In my case, I needed 2 elements.  A label and something else (input field, longtext, etc…).  The process is same for either one.

Some of the groundwork for this.  I’m using matrixlayout to control the transparent container all of these elements are being put in. I’m skipping dropdowns for this post.  I’ll talk more about those in a separate post.  I’ve done my best to leave the data declarations in here, so you have something that is pretty close to working right here 🙂

It’s funny looking back, it’s not much code for as long as it took me to figure it out.  Ha ha ha.

DATA : rootnode_info TYPE REF TO if_wd_context_node_info,
dyn_node_info TYPE REF TO if_wd_context_node_info,
dyn_node TYPE REF TO if_wd_context_node,
dyn_attributes type WDR_CONTEXT_ATTR_INFO_MAP,
dyn_children TYPE WDR_CONTEXT_CHILD_INFO_MAP.
DATA : dyn_attr_info TYPE wdr_context_attribute_info.
DATA lr_container TYPE REF TO cl_wd_uielement_container.
DATA lr_input TYPE REF TO cl_wd_input_field.
DATA lr_check TYPE REF TO cl_wd_checkbox.
DATA lr_longtext TYPE REF TO cl_wd_text_edit.
DATA lr_drop TYPE REF TO cl_wd_dropdown_by_idx.
DATA lr_label TYPE REF TO cl_wd_label.
DATA lr_invisible TYPE REF TO cl_wd_invisible_element.
DATA lr_table TYPE REF TO cl_wd_table.
DATA lo_nd_sflight TYPE REF TO if_wd_context_node.
DATA lr_button TYPE REF TO cl_wd_button.
DATA lr_grid_data TYPE REF TO cl_wd_grid_data.
DATA lr_flow_data TYPE REF TO cl_wd_flow_data.
DATA lr_matrix_hd TYPE REF TO cl_wd_matrix_head_data.
DATA lr_matrix TYPE REF TO cl_wd_matrix_data.
DATA LV_BIND TYPE STRING.
DATA LV_bind_row TYPE STRING.
DATA lv_state(2) TYPE n.
DATA lv_pwd TYPE wdy_boolean.
DATA lv_label TYPE string.
DATA lo_el_context TYPE REF TO if_wd_context_element.
DATA ls_context TYPE wd_this->Element_context.

lo_el_context = wd_context->get_element( ).

*This will create a attribute at run time…
dyn_attr_info-name = field.
rootnode_info = wd_context->get_node_info( ).
dyn_attributes = rootnode_info->get_attributes( ).

* Check to make sure the attribute doesn’t already exist
READ TABLE dyn_attributes with key name = field TRANSPORTING NO FIELDS.
CHECK sy-subrc <> 0.

CALL METHOD rootnode_info->add_attribute( EXPORTING attribute_info = dyn_attr_info ).

*For Dynamically creating Input Field
*Note : Before that change the Layout of ROOTUIELEMENTCONTAINER to MATRIX LAYOUT
lr_container ?= l_view->get_element( CONTAINER ).
lv_bind = field.

case type.
when ‘TEXT’ OR ‘TIME’ or ‘DATE’.
CALL METHOD cl_wd_input_field=>new_input_field
EXPORTING
bind_value = lv_bind
id         = lv_bind
state      = lv_state
on_enter   = ‘ON_ENTER’
RECEIVING
control    = lr_input.
when ‘CHECK’.
CALL METHOD cl_wd_checkbox=>new_checkbox
EXPORTING
bind_checked = lv_bind
id         = lv_bind
state      = lv_state
RECEIVING
control    = lr_check.
when ‘LONGTEXT’.
CALL METHOD cl_wd_text_edit=>new_text_edit
EXPORTING
bind_value = lv_bind
bind_rows  = lv_bind_row
id         = lv_bind
state      = lv_state
RECEIVING
control    = lr_longtext.
ENDCASE.
CALL METHOD cl_wd_label=>new_label
EXPORTING
label_for = lv_bind
text      = lv_label
RECEIVING
control   = lr_label.

*** once the elements are created, they must assigned to the screen as either
*** a matrix head data or matrix data (head starts a new line)
lr_matrix_hd = cl_wd_matrix_head_data=>new_matrix_head_data( lr_label ).
lr_matrix_hd->set_v_align( ’01’ ).
lr_label->set_layout_data( lr_matrix_hd ).
CALL METHOD lr_container->add_child( lr_label ).
case wa_configrma-type.
when ‘TEXT’ OR ‘TIME’ or ‘DATE’.
lr_matrix = cl_wd_matrix_data=>new_matrix_data( lr_input ).
lr_input->set_layout_data( lr_matrix ).
CALL METHOD lr_container->add_child( lr_input ).
when ‘CHECK’.
lr_matrix = cl_wd_matrix_data=>new_matrix_data( lr_check ).
lr_check->set_layout_data( lr_matrix ).
CALL METHOD lr_container->add_child( lr_check ).
when ‘LONGTEXT’.
lr_matrix = cl_wd_matrix_data=>new_matrix_data( lr_longtext ).
lr_longtext->set_layout_data( lr_matrix ).
CALL METHOD lr_container->add_child( lr_longtext ).
ENDCASE.

Variant Configuration – Integration with the IPC

On my recent evaluational for variant configuration, I got to get back into the CRM world a little bit again.  It’s been a while, but this client is using CRM and is looking into using VC & IPC.  If the IPC isn’t familiar, it’s SAP’s Internet Pricing and Configuration.  It’s the CRM version of variant configuration.  It uses all of the standard VC componets (well, almost…).  In this post I want to talk about the Variant Configuration integration with the IPC.

If you have a VC model, and you want to use the IPC (which, by the way can also be used in ERP in your sales orders/CU50), there are some key limitation you need to be aware of for the integration with the IPC.  Because the IPC is written in java, and not ABAP, there will inevitably be some things that differ.  So, I wanted to capture what all those things were.

OSS: 1819856

http://help.sap.com/saphelp_crm700_ehp02/helpdata/en/e8/a3fc3739a25941e10000009b38f8cf/frameset.htm

Among the obvious things like functions, pricing requirements, and anything else ABAP must be rewritten in Java, there are pages of other little things that won’t work, or at least won’t work exactly the same way.  So if you’re looking at using the IPC, make sure to check this out.  If you are new to variant configuration, try to do all these things in your model from the get go, it’ll make your life much easier later on.  Happy configuring.

 

Variant Configuration – Copying Sales Order Line Items

Special thanks to my Padawan, Dennis Mayo, he showed this me cool trick.  However, I had to do a little more research on it first.  It turns out, you could need some OSS notes applied for this to work.  So, before I go into some possible fixes, first let me tell you the good stuff about copying sales order line items with a configuration.

If you ever need a copy of a configuration within the same order, you can simple go into VA02, and use the menu Sales Document -> Create w/Reference.  Now, in my ignorance, I didn’t realize you could do within the sales document.  I thought it was only to create a new document.  So simple change the tab to order, if your system is like mine, it will even default your order in.  Now, magically, you have a second line that is identical to the first, with it’s own changeable configuration.  This is great for quoting when a customer might just be asking for minor variations of a configuration to see the see the difference in price =)

Now for the gotcha’s…  first and foremost, if you don’t have OSS Notes 738671 & 903495 applied in your system, you will need them.  This change appears to impact quite a few different system versions, so make sure those are applied (or the support packs that contain them).  Also, refer to OSS Note 814547 for the explanation of the configuration that applies to this change.  The short story is that in the copy control for the sales order line item, the item category must be set as blank or “A”, if you want the configuration to be changeable.  In the other choices, the configuration is directly linked to the original, and can only be changed from the original.

So there you go…  Thanks Dennis.

Web Dynpro – Creating a Radio Button

Well, I’m stilling hanging out in Web Dynpro land.  I found a new enhancement that Rapier 1.0 really needed.  So here I am again.  This time I had to focus on creating a radio button, because I wanted a customer to be able to select either an existing customer, or create a new one.  IN my brain, a radio button was a nice easy solution…  right???  As always, things are more complicated than I expected.  ha ha ha.  Well, here’s how it works.

You’ll need a context element that will hold the texts for the radio buttons.  This will dynamically determine the number of radio buttons displayed.  To make it work, you’ll need a node and an attribute.  The attribute should just be a string.  Be sure to add a supply function to the node.  This is how the texts will get populated.  See below for the code.

In the layout, create yourself a new element.  I used the RadioButtonGroupByIndex element.  I had a very defined set of values (for this example, 2) so that made life nice an easy.  Inside the element, you need to set a few things…  First, ColCount, this is the number of columns that will be used to display the radiobutton.  Second, texts…  this is a table that contains the texts.  Use the context node you created above.  Third, you’ll want an action for on select.  This will determine what happens when you select a radio button.

Now for some code.  First, you’ll need to populate the radio button text.  In the supply function you assigned in the context node, add something like the following code.

data : it type table of if_v_rp_user_create=>element_cust_method,
wa like line of it.
DATA lo_nd_app TYPE REF TO if_wd_context_node.

wa-text = ‘radio 1’.
append wa to it.
wa-text = ‘radio 2’.
append wa to it.
node->bind_table( it ).

So, those are the basic…

ABAP: Eliminating Errors by using exception ERROR_MESSAGE

I have to thank Jeremy Meier for this post.  I have to confess, I’m pretty excited to have my first guest post, so I just wanted to preface his post with a hearty thank you 🙂  The exception ERROR_MESSAGE is a technique I was unfamiliar with until Jer sent this to me.

I discovered this for one of our developers today – he was getting errors in using a standard SAP function module to get material requirements data from an MD04 function module for a report he was writing.  The code was calling a standard message when it hit a rare error check in the code”

if xyz <> abc.
MESSAGE ID ‘123’ TYPE ‘E’ NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
endif.

As this is used in MD04, it’s meant to throw the message to the screen – but when he tried to embed this function module in his Z-Report and ran it on a specific material number it caused an error to occur on the expected automated file download to excel to fail.

After looking for the right TRY-CATCH statement – which wouldn’t actully work because there was no “exception” or dump – the solution after digging a bit was to include the exception ERROR_MESSAGE to his function module call, even though it wasn’t a “defined exception” on the function header:

CALL FUNCTION ‘XYZ’
EXPORTING
VALUE1 = VARIABLE1
IMPORTING
VALUE2 = VARIABLE2
EXCEPTIONS
EXCEPTION_A = 1
EXCEPTION_B = 2
ERROR_MESSAGE = 3.

This action trapped the message and saved it to the SYST table where a standard FM can then be used to extract it if necessary, if the function module returns with sy-subrc=3:

if sy-subrc = 3.
CALL FUNCTION ‘BALW_BAPIRETURN_GET2’
EXPORTING
type  = sy-msgty
cl    = sy-msgid
number = sy-msgno
par1  = sy-msgv1
par2  = sy-msgv2
par3  = sy-msgv3
par4  = sy-msgv4
IMPORTING
return = return.
endif.

Realistically, anytime your using SAP function modules that are part of transactions, developers should try to us this to suppress the error messages and return them on their terms.

Web Dynpro – Dynamically Setting the Theme

I had to do some digging to figure this one out.  I have to give all of the credit to the link I found below.  This is geared toward a Non-Portal application,  Like my Rapier application.  It gives some great pointers on dynamically setting the theme within a web dynpro application.

http://www.sdn.sap.com/irj/scn/go/portal/prtroot/docs/library/uuid/7015b1f9-535c-2910-c8b7-e681fe75aaf8?QuickLink=index&overridelayout=true&8053063684070

Here’s the quick details.

1.  In your application, add a parameter RUN.  You can use Type String, C or whatever you want.  This is just a flag.  I also added the WDFORCEEXTERNALSTYLESHEET = X.  I’ll be honest, I’m not sure if I need this or not.  From what I’ve read, this is required if you’re using the portal.  I’m not using the portal, but it works if I set this parameter, so I left it.

2.  Now, go to your main window.

3.  Add an outbound plug of type EXIT.  Be sure to give it a parameter of URL.  If you read my or used my post on the logoff button, you already have this =)

4.  Add an inbound plug (or use the default plug).  You need a startup plug is the only key here.  Now double click on it to go into the code.

5.  Once in the code, add the parameter of Run here.  and add the following code (or a variation of it).

  CALL METHOD CL_WD_UTILITIES=>CONSTRUCT_WD_URL
EXPORTING
APPLICATION_NAME = ‘XXX’ “Your web dynpro applicaiton name
IMPORTING
OUT_ABSOLUTE_URL = lv_e_url.

if run is INITIAL.
CONCATENATE lv_e_url
‘?sap-ep-themeroot=/SAP/PUBLIC/BC/UR/NW5/THEMES/SAP_HIGHCONT’
‘&run=N’ INTO lv_e_url.
wd_this->fire_logoff_exit_plg( url = lv_e_url ).
endif.

Here’s what happens.  The first time you log into the application, it works like normal, but run is initial.  so it leaves the current application, and re-runs it with the additional parameters of you set above.

Now I did run into some strange behavior.  I kept getting a dump because of parameter run.  I implemented OSS Note: 946490, still no luck.  I finally just entered a value into the RUN parameter in the application, and then blanked it out.  Then it finally worked.  Not sure what the deal was, but hope it helps you out.

Thanks for reading and I hope this helps…

Basis – Getting Support Packs

Well, I had to move back into the world of Basis again.  SAP sent out a message a couple months ago basically saying you have to implement a bunch of OSS notes, or move your system up to a certain support pack level.  Well, needless to say, I’m way behind on support pack for my systems anyways.  This is partly intentional and partly just a lack of time.  The intentional part helps keep me accessible no matter what version of SAP support packs my potential customers have.  Well, since I have to contractually do this, it was a good opportunity to update my systems.  This posts talks about my challenges of getting support packs for my SAP system.

Well, support packs, in theory, are very easy to implement.  Transaction SPAM does everything for you.  Well, the challenge for me came in to get the actual support packs to implement.  As it turns out, anything after a certain date can only be acquired using Solution Manager (there’s a way around this that I found).  Now my problem is that I have a solution manager system, but it’s not really connected to anything.  I’ve used SOLMAN purely to get the access codes for system installation.  Now I know that SAP keeps hyping up SOLMAN, but to be honest for my purposes it has no value add.  So I went through and started to manually download all of the support packs I needed.

Even the download was tougher than I expected.  I dug around service.sap.com until I finally found the support “stack” table of contents to find out what packages are required.  Initially, I did it the hard way of downloading the packs I thought I needed, tried to implement, and found out it had more pre-requisites.  Well, I finally found everything I needed, but in my SAP Download manager, it showed everything under needing approval.

Well, I can only guess that if I had a fully functioning SOLMAN, I could do this, but instead, I went out and posted an OSS message to approve the packs.  Be sure to set the area as:  SV-SMG-MAI-APR  As it turns out, SAP will quickly approve these and let you just download them (Thank goodness for that…).  I did make a very brief effort to get the SOLMAN component working to allow me to do it from there, but I had no success, and no time to investigate it.

Anyway, I wanted to pass along these little tidbits.  My EHP4 system is still running after 36 hours, so who knows how long it will take to finish, but it’s rolling =)  Thanks for reading.