Reputation: 2328
I love using OneNote, however I want more control over the locations of my notes and how notes are generated. I'm very versed in VBA and ok with Python (and those are the only languages I can code with on my machine) however I haven't found a decent way to interact with OneNote through code. I'm using OneNote 2003 which doesn't look like it has an xml export like 2007 does. Has anyone figured out an easy way to be able to read and write OneNote files with Python or VBA?
Upvotes: 9
Views: 6490
Reputation: 984
Here is the working code from this Microsoft example. The code needed a few corrections to bring it up to date with Microsoft 365 these are shown in the comments, the original line commented out and the new line below it. The code is hosted in Excel.
The OneNote version - Microsoft® OneNote® for Microsoft 365 MSO (Version 2406 Build 16.0.17726.20078) 64-bit
Option Explicit
' https://learn.microsoft.com/en-us/previous-versions/office/developer/office-2010/hh377183(v=office.14)
Sub sbCreateNewPage()
' Connect to OneNote 2010.
' To see the results of the code,
' you'll want to ensure the OneNote 2010 user
' interface is visible.
' Dim oneNote As oneNote14.Application
Dim oneNote As oneNote.Application
' Set oneNote = New oneNote14.Application
Set oneNote = New oneNote.Application
' Get all of the Notebook nodes.
Dim nodes As MSXML2.IXMLDOMNodeList
Set nodes = GetFirstOneNoteNotebookNodes(oneNote)
If Not nodes Is Nothing Then
' Get the first OneNote Notebook in the XML document.
Dim node As MSXML2.IXMLDOMNode
Set node = nodes(0)
Dim noteBookName As String
noteBookName = node.Attributes.getNamedItem("name").Text
' Get the ID for the Notebook so the code can retrieve
' the list of sections.
Dim notebookID As String
notebookID = node.Attributes.getNamedItem("ID").Text
' Load the XML for the Sections for the Notebook requested.
Dim sectionsXml As String
' oneNote.GetHierarchy notebookID, hsSections, sectionsXml, xs2010
oneNote.GetHierarchy notebookID, hsSections, sectionsXml, xs2013
' Dim secDoc As MSXML2.DOMDocument
' Set secDoc = New MSXML2.DOMDocument
Dim secDoc As MSXML2.DOMDocument60
Set secDoc = New MSXML2.DOMDocument60
If secDoc.LoadXML(sectionsXml) Then
' select the Section nodes
Dim secNodes As MSXML2.IXMLDOMNodeList
secDoc.SetProperty "SelectionNamespaces", "xmlns:one='http://schemas.microsoft.com/office/onenote/2013/onenote'"
' change from the original to define the one: abbreviation
Set secNodes = secDoc.DocumentElement.SelectNodes("//one:Section")
If Not secNodes Is Nothing Then
' Get the first section.
Dim secNode As MSXML2.IXMLDOMNode
Set secNode = secNodes(0)
Dim sectionName As String
sectionName = secNode.Attributes.getNamedItem("name").Text
Dim sectionID As String
sectionID = secNode.Attributes.getNamedItem("ID").Text
' Create a new blank Page in the first Section
' using the default format.
Dim newPageID As String
oneNote.CreateNewPage sectionID, newPageID, npsDefault
' Get the contents of the page.
Dim outXML As String
' oneNote.GetPageContent newPageID, outXML, piAll, xs2010
oneNote.GetPageContent newPageID, outXML, piAll, xs2013
Dim doc As MSXML2.DOMDocument60
Set doc = New MSXML2.DOMDocument60
' Load Page's XML into a MSXML2.DOMDocument object.
If doc.LoadXML(outXML) Then
' Get Page Node.
Dim pageNode As MSXML2.IXMLDOMNode
doc.SetProperty "SelectionNamespaces", "xmlns:one='http://schemas.microsoft.com/office/onenote/2013/onenote'"
' change from the original to define the one: abbreviation
Set pageNode = doc.SelectSingleNode("//one:Page")
' Find the Title element.
Dim titleNode As MSXML2.IXMLDOMNode
Set titleNode = doc.SelectSingleNode("//one:Page/one:Title/one:OE/one:T")
' Get the CDataSection where OneNote store's the Title's text.
Dim cdataChild As MSXML2.IXMLDOMNode
Set cdataChild = titleNode.SelectSingleNode("text()")
' Change the title in the local XML copy.
cdataChild.Text = "A Page Created from VBA" & Format(Now(), " - YYYYMMDD HH:MM")
' Write the update to OneNote.
oneNote.UpdatePageContent doc.XML
Dim newElement As MSXML2.IXMLDOMElement
Dim newNode As MSXML2.IXMLDOMNode
' Create Outline node.
Set newElement = doc.createElement("one:Outline")
Set newNode = pageNode.appendChild(newElement)
' Create OEChildren.
Set newElement = doc.createElement("one:OEChildren")
Set newNode = newNode.appendChild(newElement)
' Create OE.
Set newElement = doc.createElement("one:OE")
Set newNode = newNode.appendChild(newElement)
' Create TE.
Set newElement = doc.createElement("one:T")
Set newNode = newNode.appendChild(newElement)
' Add the text for the Page's content.
Dim cd As MSXML2.IXMLDOMCDATASection
Set cd = doc.createCDATASection("Text added to a new OneNote page via VBA." & Format(Now(), " - YYYYMMDD HH:MM"))
newNode.appendChild cd
' Update OneNote with the new content.
oneNote.UpdatePageContent doc.XML
' Print out information about the update.
Debug.Print "A new page was created in "
Debug.Print "Section " & sectionName & " in"
Debug.Print "Notebook " & noteBookName & "."
Debug.Print "Contents of new Page:"
Debug.Print doc.XML
End If
Else
MsgBox "OneNote 2010 Section nodes not found. error 01"
End If
Else
MsgBox "OneNote 2010 Section XML Data failed to load. error 02"
End If
Else
MsgBox "OneNote 2010 XML Data failed to load. error 03"
End If
End Sub
Private Function GetAttributeValueFromNode(node As MSXML2.IXMLDOMNode, attributeName As String) As String
If node.Attributes.getNamedItem(attributeName) Is Nothing Then
GetAttributeValueFromNode = "Not found. error 04"
Else
GetAttributeValueFromNode = node.Attributes.getNamedItem(attributeName).Text
End If
End Function
'Private Function GetFirstOneNoteNotebookNodes(oneNote As oneNote14.Application) As MSXML2.IXMLDOMNodeList
Private Function GetFirstOneNoteNotebookNodes(oneNote As oneNote.Application) As MSXML2.IXMLDOMNodeList
' Get the XML that represents the OneNote notebooks available.
Dim notebookXml As String
' OneNote fills notebookXml with an XML document providing information
' about what OneNote notebooks are available.
' You want all the data and thus are providing an empty string
' for the bstrStartNodeID parameter.
' oneNote.GetHierarchy "", hsNotebooks, notebookXml, xs2010
oneNote.GetHierarchy "", hsNotebooks, notebookXml, xs2013
' Use the MSXML Library to parse the XML.
' Dim doc As MSXML2.DOMDocument
' Set doc = New MSXML2.DOMDocument
Dim doc As MSXML2.DOMDocument60
Set doc = New MSXML2.DOMDocument60
If doc.LoadXML(notebookXml) Then
doc.SetProperty "SelectionNamespaces", "xmlns:one='http://schemas.microsoft.com/office/onenote/2013/onenote'"
' change from the original to define the one: abbreviation
Set GetFirstOneNoteNotebookNodes = doc.DocumentElement.SelectNodes("//one:Notebook")
Else
Set GetFirstOneNoteNotebookNodes = Nothing
End If
End Function
Upvotes: 0
Reputation: 432
For basic CRUD (Create, Read, Update, Delete) operations on OneNote notebooks, sections or pages, you can also use the REST API from Python.
Upvotes: 0
Reputation: 9333
OneNote 2007 has more options, but OneNote 2003 only supports the CSimpleImporterClass API for importing data programmatically into OneNote. CSimpleImporterClass will let you bring in images, ink, and HTML into OneNote using VB.
Reading OneNote 2003 files might be a little harder. I don't know of any resources to make it easy to ready OneNote 2003 files with Python or VBA.
Upvotes: 4