Solve the Right Problem, Solve the Problem Right

Over twenty years ago I learned a valuable lesson about solving the right problem for the people who used the software that I was building.

I was working on a training management system, specifically on the reports that were needed by the people who handled training for a relatively large organization. There were a number of 'canned' reports, meaning that the format was fixed and the query options were limited to a small set of options. One of the reporting requirements was for an ad hoc report generator that would allow the people in the training department to create and save their own reports. This report engine was intended to have the flexibility that the canned reports didn't.

At the time, I looked at several options including off the shelf report packages (I think an early version of Crystal Reports). However, my software developer "build a better mousetrap" instincts took over and I decided to write the report generator myself.

I used an existing report file format as the starting point after finding some documentation about its binary format. I then extended it to contain some extra information that I needed for my report engine. The big chunk of the work was in building a quasi-WYSIWYG report designer that would give the people the ability to see how fields were being positioned, headers, footers, groups, etc. It was anything but a trivial task and took me about 3 to 4 weeks to have it working in a reasonable manner.

But no one used it.

I gave some demos. I sat with people and helped them create a report. They still didn't use it. From a functional perspective, my report generator was as good as anything you could get off the shelf and as easy to use... at least from my perspective as a developer. From the perspective of the consumers of the system, they just didn't have the time to learn how to use the tool well enough. So, they simply didn't use it.

The a funny thing happened. I received an urgent request for a report that had to join data from several tables and aggregate results. My report engine wasn't built to handle such a report, so I had to quickly throw together a program that could do the work. Once I had the basic report in place, I had the person who requested it come and sit with me to review what I had done. There were a couple of tweaks to make, but it was mostly OK. I asked him if this was a one-off situation, or if that report was going to be needed again in the future. The answer, of course, was the latter - this was a new requirement from upper management.

The minor problem, though, was that I was working on another system for another group in the same organization and couldn't take the time to add the new report into the training management system as one of the canned reports. Also, by that point policies around releasing desktop systems had changed and each system had to go through a test process to ensure that it would play well with other systems used by that organization.

So, I quickly created a UI for the person to be able to enter some query parameters, rolled it all together into an app and handed it to the person on a disk. He was very happy, to say the least, and I may have spent half a day on the work.

A month or two later, he came by and sheepishly said that he was given another report request from upper management. Again, it was just different enough that the ad hoc report generator couldn't handle it. Being a lazy developer, I simply copied the code from the previous report, replaced the report generation code with what was needed for the new report and change the UI to handled the different parameters. Pack it up, ship it off, and you have another happy customer!

Then, the third request arrived. This time, I copied the code but created a 'skeleton' of the app that would generate the report. The UI was blank except for buttons, as was the method that created the report. I now had a template app that just needed the code for the report and UI to allow the user to change the report parameters.

Again, I churned out a report and my customer was a happy camper. Another half day at the most.

The fourth request arrived. After half a day, there was the report's app on a disk and I believe at that point I also provided an installer to simplify that process.

I worked in that organization for another 4 years, and I don't know how many more of those reports I generated. My customer was very happy the entire time. There were other people for whom I built these quick reports as well. In those 4 years, not a single person other than me used the ad hoc report generator that I spent 3-4 weeks of my life building.

The moral of this story is that I wasn't solving the right problem with the ad hoc report generator. Yes, the customer had requested the ability to create ad hoc reports. I translated that requirement into a need to build something into the system rather than the simpler approach of writing a small app for each need. The 3-4 weeks I spent building the report generator was quite likely more than the time spent building the individual report apps.

I also didn't take the time to let anyone else try to build a report using the generator I had written. I likely would have seen much sooner that someone who wasn't me and knew the tool inside and out would struggle creating a report from scratch, and that another approach was needed.

Essentially, if I had thought more critically about solving the problem of ad hoc reporting the system could have shipped 3 to 4 weeks earlier than it did.

And that, I suppose, was the cost to learn what problem I actually needed to solve and how to solve it "right". It's a lesson that has stuck with me, and has been the rope that allowed me to climb out of a number of rat holes since by pausing and asking,

Am I solving the right problem here? Is this the right solution to the problem?