10 05 2014
Using OneNote API to count degustated beers
I am heavy OneNote user as OneNote is easybut still powerful application to keep important information and organize it the way I like. Not to mention powerful cloud back-end that makes my OneNote notebooks available for me on desktop, tablet and mobile phone. In this posting I will show you some code I use to update the number of degustated beers in beer diary.
Lazy as I am I needed dumb and simple solution to update the number of degustated beers in my degustation diary. I had no time enough to come out with something polished and nice. But my solution still works fine and I can run it on Windows task scheduler so the fresh number of degustated beers is also available when I’m using Surface RT or Windows Phone to add new beers to degustation section. The wonderful power of clout it is!
Structure of degustation section
In my beers OneNote I have special section for degustation. Image on right shows example of the structure. Here are hierarchy levels I use:
So, first level is always country, under countries I have breweries and under breweries the beers they brew and what I have already tried and documented.
In the beginning you don’t need automated way to count beers because it’s easy to do manually. It takes just minute. But after 80 beers you suddenly understand that there must be some automated way how to do counting.
There is one more top-level page: section entry page. First block of this page shows me the number of documented beers and this is the number I want to update automatically.
As beers are always on third level in page hierarchy and always in same notebook and same section it’s easy to do some hardcoding that for nice solutions I try to avoid.
Here’s what my code does:
- Find beer degustation section, section index and beer pages
- Take first block of index page
- Write number of beers to this block
And here is the code itself (ugly but works for me):
static void Main(string args)
string strNamespace = "http://schemas.microsoft.com/office/onenote/2013/onenote";
var app = new Application();
var outputXML = "";
var pageXml = "";
// load whole notebook sections hierarchy
app.GetHierarchy(null, HierarchyScope.hsSections, out outputXML);
XmlDocument xmlDoc = new XmlDocument();
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
// find degustation section
XmlNode xmlNode = xmlDoc.SelectSingleNode("//one:Section[@name='Õllekataloog']", nsmgr);
var id = xmlNode.Attributes["ID"].Value;
app.GetHierarchy(id, HierarchyScope.hsPages, out outputXML); //pageLevel="3"
// find beer pages
var nodes = xmlDoc.SelectNodes("//one:Page[@pageLevel=3]", nsmgr);
// find degustation section index page
xmlNode = xmlDoc.SelectSingleNode("//one:Page[@name='Õlleindeks']", nsmgr);
app.GetPageContent(xmlNode.Attributes["ID"].Value, out outputXML, PageInfo.piBasic);
var pageId = xmlNode.Attributes["ID"].Value;
// load first block from index page
xmlNode = xmlDoc.SelectSingleNode("//one:Page/one:Outline/one:OEChildren/one:OE/one:T", nsmgr);
pageXml = "";
// add total number of beers to index page
xmlNode.InnerText = "TOTAL: " + nodes.Count + "\r\n";
pageXml = xmlDoc.OuterXml;
// save index page
NB! Don’t forget to add reference to OneNot Type Library if you want to run or build this code in your machine. It is expected that OneNote 2013 is installed on your machine!
Image on left shows simple example of beer index page. Instead of going manually through all subpages in degustation section and making mistakes on counting them I have now nice automated way how to update the number of degustated beers.
It’s not hard to use OneNote API to modify contents of notebooks. At first the API is cumbersome and seems kinky but after some messing with it and OneNote XML it is easy to do whatever you like to do with your notebooks. One thing to notice – it is possible to build OneNote add-ons too but it takes more effort and some hacking on Visual Studio to make add-ons work.