.NET MessageBox with Checkbox

I have been working on a Windows application, TM1Compare. If you are a TM1 developer or administrator, I highly suggest you check it out. It can save you a lot of time and hassle. Click here to check it out and download the Lite version for free.

One of the features we have recently added is the ability to copy view data from one server to another. This can be done through TM1Compare without needing to export the view, copy-and-paste, or import the data through creating a complicated ETL process. TM1Compare handles all of this work in the background with a couple simple steps.

A challenge I came across while working on the view data feature was how to alert the user of important information without being annoying. TM1Compare allows the user to copy data on a single-view basis or in bulk. When copying a single view, if there is a warning we need to display to the user about that view, we display a message box and ask the user to make a choice whether to accept and continue or cancel. When the user is copying data in bulk, we didn’t want to repeatedly annoy the user with multiple message boxes, unless we could offer them the chance to make the same decision for all of the views at once. Several applications have similar functionality, such as a checkbox labeled “Don’t show this again” or “Apply to all…”. I was surprised to see that in the .NET Framework 4.5, not only is this not a standard option, but the MessageBox is a sealed class and cannot be extended to add it.

After reading several posts on StackOverflow.com, I found two options for creating the functionality I needed. Several people suggested creating a custom dialog window and displaying it as you would a normal window. I wanted my solution to have a look and feel just like the native Windows message box, which varies depending on the version of Windows the user is on, as well as the configurations they have set up in Windows, so I opted not to make my own window. The other option was a nifty trick posted by Code Project, building on Dino Esposito’s October 2002 and November 2002 MSDN articles to “hook into” to the native Windows message box and add the functionality directly into it. I decided this would work perfectly for my purposes, so I downloaded the sample code and modified it slightly to fit TM1Compare.

In Scanlon’s sample, the MessageBox wrote to the Windows registry. For my purposes, I didn’t want the user’s choice to be permanent, but to last just for the session they are in. I modified the MessageBox.Show() method to take an out parameter, which was then checked by the application and stored in a session variable.


Book Review: IBM Cognos TM1 Cookbook

In my current job I work closely with IBM Cognos TM1, creating and extending multi-dimensional OLAP databases and applications that work with these databases. When I first started down this path, I knew very little about OLAP and business intelligence technologies. To further my training last year I read through “IBM Cognos TM1 Cookbook” by Ankit Garg, ISBN: 978-1-84968-210-7. When I picked this book up I expected it to be an advanced manual which would provide some tips and tricks beyond the beginner level. Instead, the author takes the reader through TM1 from start to finish with tutorials of how to construct a single TM1 database as if he was writing a beginner’s manual. He does attempt to teach the reader some tips in-between the basic tutorials, but the author is not a very good English writer so some points he tries to make were so confusing that I ended up skipping past them.

Garg’s book is littered with spelling and grammar errors, and also contains some logical inconsistencies. Another problem with the book is that the screenshots are sometimes irrelevant, incorrect, or incomplete. One of the tutorials instructs the reader to create a “Full Name” attribute and populate it with values from a screenshot. The screenshot, however doesn’t display these values because the author didn’t maximize the window to show its entire contents. A scrollbar is visible in the screenshot, begging to be scrolled so the user can see the values they’re supposed to enter. Unfortunately, since it is a static image the reader will never know what those values are. I had been working with TM1 for a few months already when I picked up this book, so I could look past some of these problems and still move on through the tutorials. I don’t think I would have been very pleased with the book, however, if it was my first exposure to TM1.

In the first chapter Garg not only explains what TM1 is used for, but contrasts it to other types of databases, both relational and multidimensional. He then takes the reader through an introduction of using TM1. I found this chapter to be a little too detailed in areas, and had preferred that the author leave some of the advanced topics for a later chapter or an appendix. Some information seemed like it would be helpful to intermediate TM1 users, while other information was basic enough for beginners to understand.

In chapter 2 Garg starts leading the reader through creating their first database by building dimensions. I like that he takes the reader through creating dimensions manually as well as using a TI process in the same chapter. Since most of what I do in my job involves creating TI processes, I find it helpful to cover TI throughout the entire book. In this chapter attributes are also introduced, which can be a good thing or a bad thing, depending on how you look at it. I have found attributes to be essential in every TM1 system I have come across, but since they are optional I feel it was unnecessary to use them at the very beginning of a system’s design. A more appropriate place to introduce attributes would be when a problem arises that the creation of an attribute can solve.

Chapter 3 takes the user through creating cubes and views. At the beginning of the chapter the author’s grammar had improved, and I had hopes that the editor had started doing his job at this point. Alas, I was disappointed after a few paragraphs. The format of the chapter was pretty straightforward and basic, with a couple good tutorials, and again Garg chose to implement a couple TI processes. There were a few tricky errors in this chapter, which I was able to notice and work around, but they might trip up a lesser experienced user. At the end of the chapter, I was surprised that Garg didn’t go into a ton of detail, given the amount of detail he had written in the first couple chapters. However, it was actually a nice break from the information overload that he had written the previous chapter.

Chapter 4, Loading and Maintaining Data, wasn’t written as poorly as previous chapters, but I was a little annoyed that Garg instructs his readers to manually create several Excel files throughout the book for use in TI processes. Ideally, these files should have been provided by the author via a Web site or data disc. I had an electronic version of the book, so I can’t say for sure that it doesn’t come with a data disc, but I found no reference to a data download. I chose to take the time necessary to manually create the files since later examples build on the work done in previous chapters. Choosing not to create my own data files would likely have made future chapters a little more difficult to get through. Unfortunately, even though I followed the instructions to the letter, when it came to setting up an ODBC data source, I ran into issues. After half a day of troubleshooting the problems, it appeared that they stemmed from a bug in the TM1 software that doesn’t know how to look for 32-bit drivers on a 64-bit system. All kinds of people have had similar issues using ODBC in TM1, as I found on tm1forum.com. I cannot blame Garg for this issue, but since I couldn’t complete the ODBC import, I had to choose between importing the data another way or skipping it. As mentioned earlier, the tutorials all build on each other, so I could not simply skip this one.

If you can get past the book’s many errors, there are some valuable tips that TM1 developers can learn from this book. For example, I have been through several beginning TM1 tutorials, a couple from IBM themselves, and none of them mentioned the simple fact that you can copy-and-paste Dimension elements straight into the Dimension Editor windows. Garg not only tells you that you can do it, he leads you step-by-step through creating a Months dimension using copy-and-paste from Excel. One might think that this valuable fact might be well-known, but in my experience I hadn’t come across this tip prior to reading Garg’s book.

I should also state that this book should not be the first book you read if you need to learn TM1 from scratch. While there are valuable tips that a beginner’s guide should contain, the book’s many errors and the author’s broken English make it a bad choice for someone who is not already familiar with TM1. Garg also makes some assumptions about the reader’s knowledge in some cases and overlooks important details that should be further explained. I would only recommend this book to someone who has already been through several TM1 tutorials, needs a TM1 refresher, wants additional practice creating TM1 systems, and/or wants to learn a few TM1 tips and tricks to make their work slightly easier. For me it was a good fit, since I fall into all of these categories, but I would suspect there are not many others who will get the same benefits from it as I did.

On a scale of 1 (worthless) to 10 (invaluable), I rate “IBM Cognos TM1 Cookbook” as follows:
Accuracy – 4
Bias / Motive – 8
Instruction – 7
Facts – 7
Organization – 6
Target – 4
Knowledge – 7
Reference – 8
Relevancy – 7
Research – 6
Illustrations – 6
Visual Appeal – 7
Overall – 6.4


Time to Start Blogging

I’ve finally decided what to use my blog for. In the past few months I’ve come across some pretty challenging tasks in my work. I find that when I¬†discover a solution to a problem I’m working on, it’s generally the same problem that others have already dealt with. Nine times out of ten, the overall solution I end up with is a collaboration of others’ efforts. The tenth time, the solution is my own custom creation, having not found good enough examples. In all cases, however, I find that I come up with the best solution by talking it out.

So that’s what the majority of these blog posts will be. They’ll be my experience of a problem, the possible solutions I’ve come across, the solution I ended up with, and how I arrived at that decision. If I can’t explain it well enough, then chances are it wasn’t the right solution, and I may have to go back to the drawing board. I also hope to gain feedback through my posts of others’ experiences, whether I’ve helped them with my solution, or whether I’ve shown them what not to do and they can correct my flaws. So each post will be a learning experience, in one shape or another.

I’d like to make some connections through blogging, and to¬†build some long-lasting friendships and/or business relationships. Please check out my about page to see if we have similar interests, and drop me a line if you’d like. Thanks!