Now, in my recent experiments, I came to find just how much better the performance is when you can define the table in advance, and then manipulate it, rather than create the entire thing dynamically (check out some of my previous posts if you want to see how to do that). So I decided create the full table in the layout tab, and then remove the columns I didn’t need. Everything worked great, until I wanted to control the sorting columns of Table dynamically.
The first thing I found is that when you define a table using the wizard (not dynamic), it make the columns grouped columns. I still don’t really grasp the difference, but it does force you to use a different set of methods and also has different behavior. But thanks to Google, I found this nice little tidbit. It showed me that you can delete the Grouped Column, and replace it with a standard column. And with a standard column, you can define the sort order. Here’s some sample code to get you rolling.
DATA: lo_table TYPE REF TO cl_wd_table,
grcol TYPE REF TO cl_wd_abstr_table_column,
tcol TYPE REF TO cl_wd_table_column,
lc_element TYPE string VALUE ‘CTR_ITEMS’.
IF first_time EQ abap_true.
* get table reference
lo_table ?= view->get_element( id = lc_element ).
CALL METHOD lo_table->remove_grouped_column
id = ‘COL_NAME’
index = 1
the_grouped_column = grcol.
tcol ?= grcol.
CALL METHOD lo_table->add_column
index = lv_sequence
the_column = tcol.
Wow… I have to tell you, I pretty much feel like the dumbest guy on earth right now. I’ve been fumbling for a few hours trying to do something as simple as automatically generate an inbound delivery for a repair order. To set the stage, I’m trying to generate data in my test system is an automated fashion. In short, I realize I need a lot more data to help me test the performance on my dashboards. Well, if you want to at least make it look good, you should be generating some data every day, pretend like it’s a real company. So I’ve got notification being generated every day, repair sales orders, and I thought the inbound delivery would be a nice easy piece… Well, shame on me…
After spending way too much time on this, I wanted to give you benefit of my bonehead day.
1. Be careful if you try to do BDC with an Enjoy transaction. Sometimes it works, sometimes weird things happen, especially in the background. I found this with VL01N.
2. Most popup message DO NOT need to be addressed in the BDC. This was the point that killed me. I set it up to work perfectly on-line. My example was to create an inbound delivery with serial number. Well, if you have a status of ECUS on the serial number/equipment, you get that annoying popup to tell you that. I confess, I haven’t played with BDC in a while, so I totally forgot that even though it happens on-line and in error mode, it doesn’t happen when you move to N mode. “Doom on Me”, as one of my favorite authors always said. I eventually came to the revelation to find everything worked great. DOH!
3. Use transaction SHDB to get your recording information. But remember #2 above.
Anyway, just wanted to float that tidbit out there in case you might be thinking of trying anything similar.
Thanks for reading,
Hello again. In my ever changing world, today I happen to be back to Web Dynpro and my Service Management Web application. My life is truly fun and varied. ha ha ha. Anyway, my latest quest is to use a table tree. Short story, a table tree looks like an ALV grid, but it has the branch/leaf concept like a tree. I needed this particular structure because I want to sure additional columns when a node is a expanded, rather than just the node. So I started doing some digging. I was able to find a demo program in SAP to get me started. I had 2 different web applications inside of the same program. My immediate question was what is the different of between TREE_BY_KEY and TREE_BY_NST.
Strangely, this isn’t an obvious answer. I started by looking at the code and there isn’t a lot of obvious differences. So I went back to my trusty friend, Google. While I may fear the amount of information they collect on me and pass to the government, they are still the best source of information when I’m looking for SAP stuff (I’ve tried Bing and Yahoo, but the results aren’t as good). Anyway, I found a great blog that gave the answer I was looking for. But like so many of my quests, it only got me half way there. I learned that TREE_BY_KEY is for a known structure. If you know the levels and everything before runtime, you should use TREE_BY_KEY. Of course, in my world, I needed to use TREE_BY_NST because it is for dynamically building the folders and nodes when you don’t know the structure until during runtime. So this blog is great because if walks you through the TREE_BY_KEY. My next hunt is to learn about TREE_BY_NST. I’m hoping that it will be similar, and I’ll be looking at the DEMO_TABLE_WITH_TREE application in SAP to give me a start. Expect more information as I learn yet another new piece of ABAP Web Dynpro.
Thanks for reading,
Once again, thanks to my good friend Jeremy. He has once again given me a cool tool to use. The report:
It works as a Where Used within code to find any particular statement. It’s provided by SAP, but like so many thing, it isn’t advertised. Jer deals with a highly customized environment, so this tool is invaluable.
Here’s the basics of it, you get to define define what program(s) you want to search through (along with lots of other selection options). Then enter in the String you are looking for.
In my recent optimization, I needed to hunt through my code and find all the places I was using ENDSELECT. It would’ve been much easier had I used this program to find everywhere, instead of my hunt and paste methodology going through lots of different programs and ABAP methods. So, my gift to those of you that didn’t know about this, here you go. Courtesy of SAP =)
Thanks for reading,
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.
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.
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>
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>
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.
Well, I have to confess, it’s been a long week, exciting, but very stressful. I’ll expound on that more in the next couple days, but right now I need your help. I’m realizing that I’ve been doing this for a while, and every so often I just run out of good things to talk about. So when I’ve run into this before, I turn to you, my faithful reader.
What would you like to hear about? do you have specific questions on Service Management? Variant Configuration? or even small business questions? What would you like to hear me write about?
I hope to hear from you and thanks for reading, because I do this for you.
I’m sure, with all great start up companies, the players hit walls from time to time. I often ask myself, what did they to keep themselves going? You look at guys like Gates, Jobs, Dell, and they all started with nothing. And built empires. Now don’t worry, I have no delusions of grandeur that our company will grow to that size… but I have to believe they all started with the same obstacles we are encountering right now. How to get the opening round of sales, how to get that illusive customer feedback to build credibility, how to earn enough money to make this our full time endeavor without going down the venture capital path.
For now, I’ve personally pushed myself on belief. Belief in my ideas, belief that others need what I can offer. I’ve noticed though, this is getting harder to keep up. With 2 kids, a day job and my wife, pushing myself night after night is starting to take it’s toll. I keep hitting the proverbial wall more often. I noticed that today I again lost my motivation. I looked at my list of activities that I need to do, blogging, marketing, development… it’s just never ending. I know there’s a light at the end of the tunnel. Eventually we can do this full time, and then grow it to the point of getting real people to do all these jobs. But we aren’t there yet. We can’t afford to outsource all of these tasks, and we can’t afford to hire people to offload much of the work… yet.
So the million dollar question for me is: “How do I keep going?” How do I continue to push, night after night. I have my goal of doing this full time, working from home on my projects, no longer consulting. It’s still about perseverance. So, here’s my question to all of you. How do you keep yourself motivated? And you do have any secrets I could tap into? ha ha ha.
Thanks for reading,
I recently had a friend of mine ask me about how to deal with a situation that made me instantly think about service contracts. Like so many thing in SAP, standard service contracts have a lot of possibilities, but can require some work. That made me think that I should do a post on SAP Service Contracts. So here goes.
SAP Contracts are a very versatile sales document in ERP. Some of the things you can do with contracts include:
- Start and end dates by line item.
- Ability to connect multiple technical objects to a contract line item.
- Ability to connect a billing plan to bill at any interval the customer needs.
- The ability to recognize revenue on a particular line item, either at a time based or milestone basis.
- The ability to connect to any document in the document flow. Notifications, repair sales orders and call off orders are the scenarios just to name the most popular.
- The ability to directly kick off a service order from the contract (given the correct item category). This allows for easier profitability analysis for a contract due to settlement rules that can settle directly to the contract. This would work in the same way that the current field service sales order behaves.
Contracts also provide a mechanism to see if the contract is making or losing money. This is typically accomplished using custom reports. The custom report is usually required since service orders typically settle to the repair sales order and normally companies will want to do analysis on all contracts for a particular materials/profit center/product hierarchy/etc to determine the contract tends. Using document flow, you can quickly gather all repair sales orders or direct service orders connected to the contract and sum all the values.
Contracts also have several out of the box reports that can be run at any time:
- VA45 – Contract List (this will behave like VA05)
- VA46 – Collective Subsequent Processing of Contracts
- IW74 – Change of Servicable Item Contract
- IW75 – Display of Servicable Item Contract
- V.06 – Display incomplete contracts.
- SDV1 – Expiring Contracts
- SDV2 – Expired Contracts
- SDV3 – Completed Contracts
Maintenance Contracts Items
The maintenance contract is used for general service over a time period. An example of some things you would use a maintenance contract for:
- Extended maintenance where all parts and labor are covered for 1 year.
- Unlimited tech support calls or emails.
The maintenance contract is very useful when you don’t have a limit to the number of times a customer can request service. You can still follow the standard repair process, field service process, or even just create a notification in order to track the services provided. Typically, a maintenance contract is invoiced only from the contract, unless the terms and conditions state that all parts must be paid for by the customer or any other variation like that. In those instances, it may be required to use time and expenses billing on the repair sales order (using the DIP profile) rather than flat rate pricing.
Quantity Contracts Items
The quantity contract is used for any service that you are selling in a limited quantity. An example of some quantity contracts may include:
- 3 calibrations to be used any time over the next 3 years
- Yearly onsite inspection
- 5 repairs for any of 5 pieces of equipment over the next 3 years.
The quantity contract is useful to keep track of how many service calls a customer has paid for in advance. It can also be easily tied into revenue recognition (milestone). Each time a call off order is created with reference to the quantity contract item, it can signal revenue recognition that the item has been used and can now be moved from deferred revenue. You can also quickly look at the quantity contract and see how many items the customer has outstanding. Please note, this is a dynamically generated quantity field, so you will not be able to pull this field directly from a table if you are doing any custom reporting.
There’s a lot more about contracts, and if you have specific questions, I’d love to hear from. Thanks for reading.