Mathias Brandewinder on .NET, F#, VSTO and Excel development, and quantitative analysis / machine learning.
by Mathias 2. August 2011 16:06

When working with Excel, it is common to use small optimization tricks, like setting Excel.ScreenUpdating to false to avoid un-necessary screen refreshes, during lengthy operations – something along these lines:

public void DoJob(Worksheet  worksheet)
{
   var excel = worksheet.Application;

   var initialScreenUpdating = excel.ScreenUpdating;
   var initialCursor = excel.Cursor;

   excel.ScreenUpdating = false;
   excel.Cursor = XlMousePointer.xlWait;

   // do stuff

   excel.ScreenUpdating = initialScreenUpdating;
   excel.Cursor = initialCursor;
}

This is a good outline of what we would like to happen, but as is, this code has limitations. We would like to be certain that whenever we capture the state, the final two lines, which reset the state to what it was originally, are executed.

More...

by Mathias 23. January 2011 15:51

Excel Data Validation provides a nice mechanism to help users select from a set of acceptable choices, by adding a drop-down directly in a cell and displaying the list of options when the cell is selected. To do that within Excel, just go to the Data ribbon, and the Data Validation button displays a dialog like the one below. Selecting allow “List”, and typing in a few comma-separated values in the Source section will do the job. How would we go about to do the same thing from .NET?

DataValidationDialog

Turns out it’s not very complicated, as I just found out. Just create a Validation object, Add it to a Range, and you are good to go. Here is a code snippet to do just that, from a VSTO project:

var excel = Globals.ThisAddIn.Application;
var worksheet = (Worksheet)excel.ActiveSheet;
         
var list = new List<string>();
list.Add("Alpha");
list.Add("Bravo");
list.Add("Charlie");
list.Add("Delta");
list.Add("Echo");

var flatList = string.Join(",", list.ToArray());

var cell = (Range)worksheet.Cells[2, 2];
cell.Validation.Delete();
cell.Validation.Add(
   XlDVType.xlValidateList,
   XlDVAlertStyle.xlValidAlertInformation,
   XlFormatConditionOperator.xlBetween,
   flatList,
   Type.Missing);

cell.Validation.IgnoreBlank = true;
cell.Validation.InCellDropdown = true;

Nothing fancy, but as usual it took a bit of searching to figure out the right enumerations to use in the method call – hopefully it will be useful to someone else!

In the process, I found out two things. First, I wondered what would happen if I tried to set through code the contents of a cell to a value that isn’t valid. The answer is, Data Validation doesn’t validate anything in that case – it appears to be strictly a UI mechanism. Then, I realized that I had no clear idea what the 2nd and 3rd tab in the dialog do; turns out, these are potentially pretty cool. Input Message behaves like a ToolTip that shows up on cell selection, with a title and message, in a way similar to Comments, but not editable. Error Alert defines the message that should show up when an invalid value is entered – and allows to disable the Error Alert if need be. So if all you wanted was a DropDown with “suggested” choices, you could just disable the error alert, and you would have a cell with a DropDown, where users could still type any freeform text they please.

by Mathias 28. June 2010 13:14

A client asked me recently a fun probability question, which revolved around figuring out the probability of success of a research program. In a simplified form, here is the problem: imagine that you have multiple labs, each developing products which have independent probabilities of succeeding – what is the probability of more than a certain number of products being eventually successful?

Let’s illustrate on a simple example. Product A has a 30% probability of success, and product B a 60% probability of success. Combining these into a probability tree, we work out that there is an 18% chance of having 2 products successful, 18% + 12 % + 42% = 72% chance of having 1 or more products succeed, and 28% chances of a total failure.

SimpleBinaryTree

It’s not a very complicated theoretical problem. Practically, however, when the number of products increases, the number of outcomes becomes large, fairly fast – and working out every single combination by hand is extremely tedious.

Fortunately, using a simple trick, we can generate these combinations with minimal effort. The representation of integers in base 2 is a decomposition in powers of 2, resulting in a unique sequence of 0 and 1. In our simplified example, if we consider the numbers 0, 1, 2 and 3, their decomposition is

0 = 0 x 2^2 + 0 x 2^1 –> 00

1 = 0 x 2^2 + 1 ^ 2^1 –> 01

2 = 1 x 2^2 + 0 x 2^1 –> 10

3 = 1 x 2^2 + 1 x 2^2 –> 11

As a result, if if consider a 1 to encode the success of a product, and a 0 its failure, the binary representation of integers from 0 to 3 gives us all possible outcomes for our two-products scenario.

More...

by Mathias 2. June 2010 05:43

It seems like all the cool kids are using either Git or Mercurial these days, so I feel like a dinosaur sticking to Subversion and Tortoise for version control. In the meanwhile, I just figured out a small Tortoise trick yesterday.

In my experience, the number one dumb mistake that happens with Subversion is adding a new file in a project, and forgetting to add that new file when committing. To avoid this, before a commit, I right-click on my project, and select add, which shows all the local files that haven’t been added to the repository. The problem is that you get a bazillion files this way, some of them you know you are never going to add, like the Bin and Obj folders for instance.

AddFiles

Easy fix: right-click TortoiseSVN, settings, and you’ll see the following:

TortoiseSettings

The text box “Global ignore pattern” defines what patterns you want to exclude; in my case I wanted to remove bin and obj folders, and ReSharper related files, which typically contain _ReSharper, so I added

bin obj *_ReSharper*

to the list of patterns. Et voila! Once again, I just wish I had taken the time to read the user manual. This type of dumb process detail just takes a few seconds here and there, but adds up over time; I wouldn’t want to know how many hours I spent un-selecting files in this list over the last 5 years…

by Mathias 30. May 2010 11:01

Silence is gold. Or… is it? You may have noticed that VSTO swallows exceptions; that is, if something goes wrong in your add-in code, Office will discreetly carry on as if nothing had happened. Consider the following code:

public partial class ThisAddIn
{
    private int counter;

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        this.Application.SheetActivate += SheetActivated;
    }

    private void SheetActivated(object sheet)
    {
        MessageBox.Show("Counter = " + this.counter.ToString());
        throw new ArgumentException("Something went south here.");
        counter++;
    }

The add-in is supposed to maintain a counter of how many times the user has changed the activate sheet. However, a bug throws an exception right before the counter is updated. If you run this code, you’ll see that the MessageBox keeps being displayed every time you change the selected worksheet, but the counter stays firmly at zero, and never gets updated.

More...

Comments

Comment RSS