5

I would like to use VBA in Excel 2007 to step through about 500 receipts, which have been converted to one large OneNote 2010 notebook. Each notebook tab contains a different receipt. I need to get the pertainant details (Receipt #, Receipt Date, Amount, all of the line item data, tax, etc) out of each and I want to create a sheet in Excel with that data.

The data is semi-structured, meaning that once I find "Order Number" I know there is a space character and then the order number follows. But it might be on different lines or even pushed over, etc. But thats OK. I can write the VBA code, that isnt the problem..

I figured it would be easier than data entry or cheaper than hiring someone to key all this in by hand... I dont want to go the OCR route because I need the accuracy that I think I can get from some sort of Office Automation between Excel and OneNote. I just cant find any example of automation using OneNote 2010 (either from the OneNote side nor the Excel side). Can another point me in the right direction? MSDN has a developer site for Office and OneNote but I must be blind to not see any examples or even an object model!

Community
  • 1
  • 1
Taptronic
  • 5,129
  • 9
  • 44
  • 59
  • Please navigate to "https://code.msdn.microsoft.com/office/onenote-2010-retrieve-data-023e69c0" and download the sample files. It has all possibilities of onenote automation. Hope it helps. – MNS CHANDRASEKARAN Jun 19 '19 at 14:08

5 Answers5

5

This VBA example code on MSDN might help you. I retrieves a list of all OneNote notebooks. It is written for OneNote 2010 and works for my Office 2010 package, but I hope it works on 2007 also.

I have modified the example source to retrieve all pages and the page content. The page content is XML so you would have to parse that.

Modified MSDN Example:

'Add the following references (adjust to our office version):
'
' - Microsoft OneNote 14.0 Object Library
' - Microsoft XML, v6.0

Sub ListOneNotePages()
    ' Original example is from http://code.msdn.microsoft.com/office/onenote-2010-retrieve-data-023e69c0
    ' License: Apache 2.0
    ' Modified to get all pages & content instead of the notebook list

    ' Connect to OneNote 2010.
    ' OneNote will be started if it's not running.
    Dim oneNote As OneNote14.Application
    Set oneNote = New OneNote14.Application

    ' Get the XML that represents the OneNote pages
    Dim oneNotePagesXml As String

    ' oneNotePagesXml gets filled in with an XML document providing information
    ' about all OneNote pages.
    ' You want all the data. Thus you provide an empty string
    ' for the bstrStartNodeID parameter.
    oneNote.GetHierarchy "", OneNote14.HierarchyScope.hsPages, oneNotePagesXml, xs2010

    ' Use the MSXML Library to parse the XML.
    Dim doc As MSXML2.DOMDocument
    Set doc = New MSXML2.DOMDocument

    If doc.LoadXML(oneNotePagesXml) Then
        ' Find all the Page nodes in the one namespace.
        Dim nodes As MSXML2.IXMLDOMNodeList
        Set nodes = doc.DocumentElement.SelectNodes("//one:Page")

        Dim node As MSXML2.IXMLDOMNode
        Dim pageName As String
        Dim sectionName As String
        Dim pageContent As String
        Dim temp As String
        ' Walk the collection of Pages.
        ' Read attribute values and write them
        ' out to the Immediate window of your VBA host.
        For Each node In nodes
            pageName = node.Attributes.getNamedItem("name").Text
            Debug.Print "Page name: "; vbCrLf & " " & pageName

            Call oneNote.GetPageContent(GetAttributeValueFromNode(node, "ID"), pageContent, piBasic)
            Debug.Print " content: " & pageContent

        Next
    Else
        MsgBox "OneNote 2010 XML Data failed to load."
    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."
    Else
        GetAttributeValueFromNode = node.Attributes.getNamedItem(attributeName).Text
    End If
End Function
3

I don't know of any great resource for doing what you want but the following two articles have some info that might help you get started:

Creating OneNote 2010 Extensions with the OneNote Object Model

What's New for Developers in OneNote 2007 (Part 1 of 2)

To find more information I'd suggest googling for Microsoft.Office.Interop.OneNote which should hopefully get you quite a lot of questions of doing it from .Net, which, even it might not be ideal, might at least give you some hints.

Hans Olsson
  • 54,199
  • 15
  • 94
  • 116
2

I found a better VBA example, titled "Programmatically Searching in OneNote 2010":

Sub SearchTermsInTheFirstNoteBook()
    ' Connect to OneNote 2010
    ' OneNote will be started if it's not running.
    Dim oneNote As OneNote14.Application
    Set oneNote = New OneNote14.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 notebook found.
        Dim node As MSXML2.IXMLDOMNode
        Set node = nodes(0)
        ' Get the ID.
        Dim notebookID As String
        notebookID = node.Attributes.getNamedItem("ID").Text

        ' Ask the user for a string for which to search
        ' with a default search string of "Microsoft".
        Dim searchString As String
        searchString = InputBox$("Enter a search string.", "Search", "Microsoft")

        Dim searchResultsAsXml As String
        ' The FindPages method search a OneNote object (in this example, the first
        ' open Notebook). You provide the search string and the results are
        ' provided as an XML document listing the objects where the search
        ' string is found. You can control whether OneNote searches non-indexed data (this
        ' example passes False). You can also choose whether OneNote enables
        ' the User Interface to show the found items (this example passes False).
        ' This example instructs OneNote to return the XML data in the 2010 schema format.
        oneNote.FindPages notebookID, searchString, searchResultsAsXml, False, False, xs2010

        ' Output the returned XML to the Immediate Window.
        ' If no search items are found, the XML contains the
        ' XML hierarchy data for the searched item.
        Debug.Print searchResultsAsXml
    Else
        MsgBox "OneNote 2010 XML data failed to load."
    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."
    Else
        GetAttributeValueFromNode = node.Attributes.getNamedItem(attributeName).Text
    End If
End Function

Private Function GetFirstOneNoteNotebookNodes(oneNote As OneNote14.Application) As MSXML2.IXMLDOMNodeList
    ' Get the XML that represents the OneNote notebooks available.
    Dim notebookXml As String
    ' Fill notebookXml with an XML document providing information
    ' about available OneNote notebooks.
    ' To get all the data, provide an empty string
    ' for the bstrStartNodeID parameter.
    oneNote.GetHierarchy "", hsNotebooks, notebookXml, xs2010

    ' Use the MSXML Library to parse the XML.
    Dim doc As MSXML2.DOMDocument
    Set doc = New MSXML2.DOMDocument

    If doc.LoadXML(notebookXml) Then
        Set GetFirstOneNoteNotebookNodes = doc.DocumentElement.SelectNodes("//one:Notebook")
    Else
        Set GetFirstOneNoteNotebookNodes = Nothing
    End If
End Function

It results in "searchResultsAsXml" containing XML data listing all pages where "searchString " is present; buy specifying TRUE as 5th parameter in

oneNote.FindPages notebookID, searchString, searchResultsAsXml, False, False, xs2010

you get OneNote to highlight results.

jumpjack
  • 841
  • 1
  • 11
  • 17
2

After a long study of VBA & OneNote I arrived at this solution:

'Add the following references (adjust to our office version):
'
' - Microsoft OneNote 14.0 Object Library
' - Microsoft XML, v6.0

Sub SearchStringInOneNote()
    ' Original example is from http://code.msdn.microsoft.com/office/onenote-2010-retrieve-data-023e69c0
    ' License: Apache 2.0
    ' Modified to get all pages & content instead of the notebook list

    StringToSearch = InputBox("Text to search:", "Search in OneNote")
    StringToSearch = UCase(StringToSearch) ' Case insensitiveness

    ' Connect to OneNote 2010.
    ' OneNote will be started if it's not running.
    Dim oneNote As OneNote14.Application
    Set oneNote = New OneNote14.Application

    ' Get the XML that represents the OneNote pages
    Dim oneNotePagesXml As String

    ' oneNotePagesXml gets filled in with an XML document providing information
    ' about all OneNote pages.
    ' You want all the data. Thus you provide an empty string
    ' for the bstrStartNodeID parameter.
    oneNote.GetHierarchy "", OneNote14.HierarchyScope.hsPages, oneNotePagesXml, xs2010

    ' Use the MSXML Library to parse the XML.

    Dim doc As MSXML2.DOMDocument
    Dim notebooks As MSXML2.IXMLDOMNodeList
    Dim sections As MSXML2.IXMLDOMElement
    Dim page As MSXML2.IXMLDOMElement

    Set doc = New MSXML2.DOMDocument
    result = doc.LoadXML(oneNotePagesXml)

    Set notebooks = doc.ChildNodes
    Set sections = notebooks(1)
    For Each section In sections.ChildNodes
        Debug.Print "Notebook: "; section.Attributes(1).Text
        Set Pages = section.ChildNodes
        For Each page In Pages
            Debug.Print "    Section: " & page.Attributes(0).Text
            For Each node In page.ChildNodes
                Debug.Print "        Page: " & node.Attributes(1).Text
                Call ProcessNode(node, oneNote, StringToSearch)
            Next
        Next
    Next
End Sub


Sub ProcessNode(ByVal node As MSXML2.IXMLDOMNode, ByVal oneNote As OneNote14.Application, ByVal StringToSearch As String)
        Dim SectionName As String
        Dim PageContent As String
        Dim pageXML As MSXML2.DOMDocument
        Dim TextToSearch As String
        Dim TableNode As MSXML2.IXMLDOMNode
        Dim RowNode As MSXML2.IXMLDOMNode
        Dim Outlines As MSXML2.IXMLDOMNodeList
        Dim Tables As MSXML2.IXMLDOMNodeList

        ' Walk the collection of Pages.
        ' Read attribute values and write them
        ' out to the Immediate window of your VBA host.

           Call oneNote.GetPageContent(GetAttributeValueFromNode(node, "ID"), PageContent, 4) ' Put page content in XML format into string variable

           '---- Put XML page content into XML object:
           Set pageXML = New MSXML2.DOMDocument
           pageXML.LoadXML (PageContent) ' Load page content in XML format into XML object
           pageXML.LoadXML (pageXML.ChildNodes(1).XML) ' Reload same XML object with just significative part of page content (=second node)

           Set Outlines = pageXML.DocumentElement.SelectNodes("//one:Outline") ' Store into XML object the collection of outlines of the page
           OutlineNumber = 0
           TableNumber = 0

           For Each Outline In Outlines
                OutlineNumber = OutlineNumber + 1
                TableNumber = 0
                Set TableNode = Outline.ChildNodes(2).ChildNodes(0).ChildNodes(0)  'Outline.SelectNodes("//one:Table").Context 'Outline.SelectNodes("//one:Table").Item(2)
'Debug.Print "Scanning outline n." & OutlineNumber & "..."
                     If TableNode Is Nothing Then
                         ' If page contains no tables (empty page?)...
                     Else
                         ContaRighe = 0
                         For Each RowNode In TableNode.ChildNodes ' Scan all rows of table
                             ContaRighe = ContaRighe + 1
                             If ContaRighe > 1 Then ' Skip first line (contains columns list)
                                 TestoRiga = "" ' Prepare variable to contain all cells of current row
                                 For x = 0 To RowNode.ChildNodes.Length - 1 ' Store all cells text into a variable
                                     TestoRiga = TestoRiga & Chr(9) & RowNode.ChildNodes(x).Text
                                 Next
                                 If InStr(UCase(TestoRiga), StringToSearch) > 0 Then ' Look for string in row.
                                     Debug.Print "FOUND: " & TestoRiga ' Print row if string found
                                 End If
                             End If
                         Next
                         Set TableNode = Nothing
                     End If ' Table exists
            Next ' Outlines
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."
    Else
        GetAttributeValueFromNode = node.Attributes.getNamedItem(attributeName).Text
    End If
End Function

Unfortunately it is very slow... but it works!

Usage:

  • Copy whole source into an empty VBA module
  • Launch SearchStringInOneNote()
  • Fill in the text and press OK
  • Look at VBA debug output window for results
jumpjack
  • 841
  • 1
  • 11
  • 17
1

Not VBA, but just in case it helps...

Old as it is, I stumbled across this question looking for the same answer (and here's what I found):


OneNote still lacks a VBA editor, however there is support for Macros (not VBA) via an addin called Onetastic - see here: https://www.microsoft.com/en-us/microsoft-365/blog/2013/08/01/try-the-onetastic-add-in-to-bring-tons-of-new-features-to-onenote/

It seems that Onetastic adds a lot of features to OneNote, including it's own scripting tool - see here: https://getonetastic.com/?r=macros

enter image description here

I know it isn't an exact answer to the question, but but but... if there's some flexibility around the requirement for VBA this will probably help.


For what it's worth, when I installed Onetastic on my laptop it 'just worked'. When I installed it on my desktop it didn't seem to do anything (even though the installer reported a successful installation).

I think the difference is that Laptop has OneNote 365/2016 (comes with Windows 10) whereas the desktop has both OneNote 2010 (from office 2010) and also OneNote 365; I suspect deleting one of the versions from the desktop will get everything working...

SlowLearner
  • 3,086
  • 24
  • 54