Photo Credit: 'gadl' @ FlickrMcGillicutty Power and Light was a small utilities company with a big problem: Their customer base was growing by leaps and bounds but the supposed-to-be simple task of printing a batch of invoices was taking a glacial age to complete. Things got to be so bad in fact that each of the accounting clerks needed two PC's – one dedicated to everyday tasks like email and spreadsheets and the other for printing invoices.

It wasn't as if the printing workstation was maxed-out on resources, it's just that generating customer invoices was a delicate process. If one were to, say, compose an email while printing invoices, then the printer would be full of email print-outs instead of invoices, meaning that the batch print would need to be run from scratch. Hired on as one of the "big guns" to help address the grim situation, John Reese was not surprised when he saw how the company's business "logic" was being executed.

Written in Microsoft Access, invoices were created by running a macro that sent a complex series of "sendKey" commands to the UI that simulated scrolling through the records and clicking the "Print Report" button. This was not only time-consuming, but it was what made the workstation off-limits to the user while the process was running. The only thing missing was the duct tape.

Another developer on John's team solved the printing part of Rube Goldberg Invoicing process and sent the process behind the scenes instead of using the dreaded sendKey commands.

John's job was to tackle the performance problem. First, he converted the macros to VBA so that the errors could be logged somewhere other than the invoice's output and could be diagnosed by someone other than the customer. John's next task was to painstakenly identify and address the application's unnecessary and inefficient operations, mostly by utilizing pass-through queries to SQL Server (where the data was slowly being migrated) rather than using the agonizingly slow JET database engine to process the data on the local machine.

While the end result was admittedly a "hack" at best, it was workable and resulted in an invoice run taking only 30 - 45 minutes. The accountants were overjoyed, but their happiness was short lived - the invoices were now printing out of sequence and not grouping by end cusotmer. Not a huge deal until one considers that a single run resulted in several hundred individual printouts being generated and a sorting nightmare for the poor accounting intern who had to group output by customer...one...by...one.

Sorting FAIL!

There's no freaking way - I KNOW that I tested for this! John thought out loud. He ran his test run of 30 invoices and everything was grouped fine in the output. Armed with his test cases, John told management that there was no way this could be the application's fault - it had to be somewhere in the network. The powers-that-be countered with everything was fine until YOU came along and broke it. You're the developer, now go and WRITE SOME CODE TO FIX IT!

Out of ideas, John had no choice but to follow an actual invoice print run all the way through which meant monitoring both the application and its printer queue. At first, everything was coming out fine. Just as tested. However, once the application had placed about 100 print jobs in the printer queue, things got a little strange. Subsequent print jobs were skipping ahead and going directly to the printer. Suddenly it was as if a light bulb went off in John's head. Before the performance improvements, the printer was able to spit out paper faster than the dusty old report generation process could send requests. Now, the creation process was much faster than the printer, so jobs started to pile up in the queue.

Just Following Orders...

If a coded solution was what the big wigs wanted, then that was exactly what they were going to get...and it was going to be an ugly one at that. John's fix was that, after sending out 100 print requests, a message box would pop up saying "Click OK to continue." Waiting for the user to press "OK" paused things long enough to allow the printer to catch up to the backlog of jobs in the queue.

Upon seeing this fix, management was elated. In fact, they were so impressed by this genius solution that when the invoicing application was rewritten in VB.NET years later, John learned that the message box still was there, just to make sure that the invoices didn't skip ahead in the printer queue.