When someone asked my former manager David Treadwell what he did on a daily basis his answer was “Go to meetings and delete email”. Unfortunately that often describes my life as well. It is always challenging to manage your time. I want to ensure I’m spending enough on technology, people, customers, etc. To make this easier, I’m using the Categories feature of Exchange to code each meeting I have (these are my custom categories):
At a glance I can then tell what kind of meeting I’m headed to next. But I still need a way to understand how I’m spending my time every month. What would be great is to collect all the category data from all my meetings and then get the ratios. This blog covers a sample that does that.
There are several ways you can get your calendar data. In this case the task is very simple: collect all calendar items in a given month including the category setting. The easiest way to do this is to use Exchange Web Services support to ask the server for the data directly. The sample has a library which can be used to connect to EWS and collect all the calendar items and a console application which provides an easy way to drive the program logic. The following shows the overall structure of the sample code (click for larger image):
The diagram was generated using new Generate Dependency Graph feature of Visual Studio Ultimate. The graph is created by shredding the binaries themselves so we find everything.
There are a few key areas to look through for EWS code. The first is the GetExchangeProxy helper which sets up the connection to Exchange using ExchangeServiceBinding. In this case we are using integrated Windows security so that a userid/password is not required (you could supply them as an alternative):
The next interesting helper method is BuildQueryFilter which is responsible for creating a FindItemType filter class. This class allows you to construct a query for the server to find the data we care about. The code builds up a series of arguments to scope calendar items between the start and end dates. For example, this snippet of code sets a criteria of all dates greater than or equal to the start date:
A similar block of code sets the filter for less than or equal to the end date. Finally these two conditions are combined with an And clause to essentially mean “>= start AND <= end”:
Once the filter is set, we can retrieve all of the calendar items we asked for. In this case I’m returning the array in our own CalendarItemList which will allow us to enumerate the data from the client code. The GetNextItem method will then strip the full Exchange calendar item (with over 100 fields) down to just a handful we care about and return the data in a CalendarItemData instance. There are a huge number of fields available for return. You can use the DebugTraceCalItem helper method to dump the entire type if you are interested in pulling back more data.
The console application then becomes pretty easy: parse and validate all the arguments, connect to the exchange server, then write each calendar item out in a comma separated view (CSV) format. The output can either be written directly to a file or to the console for redirection to other locations. At that point it is very easy to simply open the file directly in Excel where you can edit it, create charts, analyze it, etc.
I’ve included a sequence diagram in the project which demonstrates the core logic of the Run method (click for larger image):
(Note that generating a sequence diagram with VS Ultimate is very easy: just place your cursor in the method and right click to run “Generate Sequence Diagram”)
Running the application is now very simple:
timespent /start:9/1/2009 /end:9/30/2009 /out:c:\temp\sept09.csv /mailpath:https://mydomain/ews/exchange.asmx
“mydomain” in this case is the domain address for your Exchange server. You can get this from your exchange administrator (it will likely match the path you are using on your phone to sync your mail over the air).