Reputation: 1
I would like to copy a page from my template section and rename it. For now, I merge sections because I only have one page in the template section. So I need to rename the page in the new section but I m not able to make it works! It changes the name in the code but not able to get it applied to the document.
Here the code that I use with declaration followed the part just after merging those sections:
'Microsoft OneNote 15.0 Object Library
'Microsoft XML, 5.0 (comes from 6.0 originally but a lot of code not working on 6.0)
Private Sub CommandButton5_Click()
Dim onenote As onenote.Application
Set onenote = New onenote.Application
Dim MypageName as string
MypageName = "page title"
' Get the XML that represents the OneNote sections
Dim oneNoteSectionsXml As String
onenote.GetHierarchy "", 4, oneNoteSectionsXml
Dim doc As MSXML2.DOMDocument
Set doc = New MSXML2.DOMDocument
If doc.LoadXML(oneNoteSectionsXml) Then
Dim nodeNoteBooks As MSXML2.IXMLDOMNodeList
Dim nodeSections As MSXML2.IXMLDOMNodeList
Dim nodepages As MSXML2.IXMLDOMNodeList
Set nodeNoteBooks = doc.DocumentElement.SelectNodes("//one:Notebook")
Set nodeSections = doc.DocumentElement.SelectNodes("//one:Section")
Set nodepages = doc.DocumentElement.SelectNodes("//one:Page")
Dim nodeNoteBook As MSXML2.IXMLDOMNode
Dim nodeSection As MSXML2.IXMLDOMNode
Dim nodePage As MSXML2.IXMLDOMNode
`For Each nodePage In nodepages
If nodePage.Attributes.getNamedItem("name").Text = nodeSections.item(2).ChildNodes(0).Attributes.getNamedItem("name").Text Then nodePage.Attributes.getNamedItem("name").Text = MypageName
onenote.UpdateHierarchy doc.XML
doc.Save doc.XML
next
end if
end sub `
UpdateHierarchy gives no error but no results and doc.save gives an error (wrong parameters).
Is it the right way to do it ?
I tried a lot of solutions all around but nothing works. The original code was copied and it was on microsoft xml 6.0 but a lot of error came out so I tried to adapt it for 5.0 and its working, exept for this part.
Thanks for help!
Upvotes: 0
Views: 217
Reputation: 984
Here is the code I used to rename a page in OneNote.
The name of a page in OneNote is part of the page content, pages are uniquely identified by their GUID.
I used the following code to get a list of page GUIDs (known as ID to OneNote).
This makes it simpler to illustrate here as pages can then be retrieved by their GUID.
I have several pages with the same name so if the same applies to you then it may be worth alphabetising the pages before changing their names.
OneNote also allows a blank page name.
Sub sbGetPagesXML()
Dim oneNote As oneNote.Application
Set oneNote = New oneNote.Application
Dim sPagesXML As String
oneNote.GetHierarchy "", hsPages, sPagesXML, xs2013
'MsgBox sPagesXML
sbPrint (sPagesXML)
End Sub
Sub sbPrint(sText As String): Open "C:\tmp\z-" & Format(Now(), "HHMMSS") & ".txt" For Output As #1: Print #1, sText: Close #1: End Sub
I then used this code to retrieve a specific page XML to check when the page has be renamed.
Sub sbGetPageContent()
Dim oneNote As oneNote.Application
Set oneNote = New oneNote.Application
Dim sPageContentXML As String
oneNote.GetPageContent "{9D710DD4-704A-4F0C-B2E0-54153AA5EB42}{1}{E195 ... your GUID here }", sPageContentXML, piAll, xs2013
'MsgBox sPageContentXML
sbPrint (sPageContentXML)
End Sub
The following is the simple procedure to rename a page.
Option Explicit
Sub sbUpdatePageContent()
Dim oneNote As oneNote.Application
Set oneNote = New oneNote.Application
Dim sPageContentXML As String
Dim PgRenDoc As MSXML2.DOMDocument60
Set PgRenDoc = New MSXML2.DOMDocument60
oneNote.GetPageContent "{9D710DD4-704A-4F0C-B2E0-54153AA5EB42}{1}{E195 ... your GUID here }", sPageContentXML, piAll, xs2013
' Load Page's XML into a MSXML2.DOMDocument object.
PgRenDoc.LoadXML (sPageContentXML)
' Find the Title element.
Dim titleNode As MSXML2.IXMLDOMNode
PgRenDoc.SetProperty "SelectionNamespaces", "xmlns:one='http://schemas.microsoft.com/office/onenote/2013/onenote'"
Set titleNode = PgRenDoc.SelectSingleNode("//one:Page/one:Title/one:OE/one:T")
' Get the CDataSection where OneNote stores the Title text.
Dim cdataChild As MSXML2.IXMLDOMNode
Set cdataChild = titleNode.SelectSingleNode("text()")
' Change the title in the local XML copy.
cdataChild.Text = "This page was renamed - " & Format(Now(), "YYYYMMDD HH:MM ")
' Write the update to OneNote.
oneNote.UpdatePageContent PgRenDoc.XML
End Sub
Then use sbGetPageContent
to check the XML and OneNote displays the changed page name.
Notes.
I do not have XML 5.0 available on my Windows 11 computer, only XML 3.0 and XML 6.0.
The DOMDocument
should be referred to as MSXML2.DOMDocument60
The references I used were as follows,
Visual Basic For Applications
Microsoft Excel 16.0 Object Library
OLE Automation
Microsoft Office 16.0 Object Library
Microsoft XML, v6.0
Microsoft Visual Basic for Applications Extensibility 5.3
Microsoft OneNote 15.0 Object Library
and the code I used to list the references was -
Sub Grab_References()
'Comments:
'
'Purpose: List all references used in the workbook
'Additional information: http://www.cpearson.com/Excel/vbe.aspx
'
'References: Microsoft Visual Basic for Applications Extensibility 5.3
'
'Date Developer Action
'---------------------------------------------
'01/18/12 ws Created
Dim wb As Workbook
Dim ws As Worksheet
Dim n As Integer
Dim x As Integer
Set wb = ThisWorkbook
Set ws = wb.Worksheets("Sheet1")
With wb
On Error Resume Next
x = 1
For n = 1 To .VBProject.References.Count
ws.Cells(x, 1) = n
ws.Cells(x, 2) = .VBProject.References.Item(n).Description
ws.Cells(x, 3) = .VBProject.References.Item(n).Major
ws.Cells(x, 4) = .VBProject.References.Item(n).Minor
ws.Cells(x, 5) = .VBProject.References.Item(n).FullPath
ws.Cells(x, 6) = .VBProject.References.Item(n).GUID
x = x + 1
Next n
ws.Columns("A:G").EntireColumn.AutoFit
End With
'Tidy up
Set wb = Nothing
Set ws = Nothing
End Sub
The version of OneNote I used was "Microsoft® OneNote® for Microsoft 365 MSO (Version 2405 Build 16.0.17628.20006) 64-bit" Apparently there is a pre-installed version of OneNote which comes with Windows known as "OneNote for Windows 10". I uninstalled it to make sure I knew what version I was using.
My OneNote is not synced to OneDrive, pages are saved to the local computer only. The default directory is "C:\Users\david\Documents\OneNote Notebooks"
I used fragments of many of the examples of OneNote VBA code from SO and MS Support. Not many of them worked for the following reasons.
The namespace must be xs2013 in the .GetPageContent
call or the call returns nothing with no message and this counts as success, obviously.
This is despite the version of OneNote installed on my computer being "Build 16...".
To use the abbreviation "one:Notebook", for example, the following property must be set on the XML object before using SelectNodes
Dim doc As MSXML2.DOMDocument60
doc.SetProperty "SelectionNamespaces", "xmlns:one='http://schemas.microsoft.com/office/onenote/2013/onenote'" ' set this property before using SelectNodes
This property must also refer to the namespace 2013.
The VBA code is run from Excel and may not work if OneNote is open when the code runs. The error is likely to be "Automation Error".
Upvotes: 0
Reputation: 1
I finally get it working. I think that I must reload another xml with page content.
Here the entire code if it could help someone! It merge the template section (ongletNameOrigine
) (index of the start section) with the destination section (ongletNameDestination)
(index of destination section), then it loop through the destination section to find the template page by its name TemplatePageName
(I only have one page in template section) and rename it with the right name (MypageName)
. Its not optimized but you can use it to get started!
Private Sub CommandButton5_Click()
'Make sure to add the references to:
'Microsoft OneNote 15.0 Object Library
'Microsoft XML, 5.0
'ref to: https://github.com/pierrms/Alphabetize-OneNote-Sections-VBA/blob/master/OneNote_Sort_VBA.bas
Unload Me
Dim notebookSortName As String
Dim ongletNameOrigine As Integer
Dim ongletNameDestination As Integer
Dim MypageName As String
Dim contrat As String
Dim item As String
Dim Mac As String
Dim TemplatePageName As String
Dim templatePageID As String
'Templates = 2, Projets en cours =3, Projets en appro =4, Projets terminés =5
'set section value
contrat = Cells(ActiveCell.Row, 1).Value
item = Cells(ActiveCell.Row, 2).Value
notebookSortName = "11A-Famille Expert C1SCAN"
ongletNameOrigine = 2: ongletNameDestination = 3
Mac = Application.InputBox("numero machine (911-912-913-871)")
MypageName = "PL-" + contrat + "-" + item + " (" + Mac + ")"
TemplatePageName = "PL-Contrat-Item (871,911,912,913)"
Dim onenote As onenote.Application
Set onenote = New onenote.Application
' Get the XML that represents the OneNote sections
Dim oneNoteSectionsXml As String
onenote.GetHierarchy "", 4, oneNoteSectionsXml
Dim doc As MSXML2.DOMDocument
Set doc = New MSXML2.DOMDocument
If doc.LoadXML(oneNoteSectionsXml) Then
Dim nodeNoteBooks As MSXML2.IXMLDOMNodeList
Dim nodeSections As MSXML2.IXMLDOMNodeList
Dim nodepages As MSXML2.IXMLDOMNodeList
Set nodeNoteBooks = doc.DocumentElement.SelectNodes("//one:Notebook")
Set nodeSections = doc.DocumentElement.SelectNodes("//one:Section")
Set nodepages = doc.DocumentElement.SelectNodes("//one:Page")
Dim nodeNoteBook As MSXML2.IXMLDOMNode
Dim nodeSection As MSXML2.IXMLDOMNode
Dim nodepage As MSXML2.IXMLDOMNode
Dim sectionIDXML As String
Dim section2IDXML As String
Dim pageXML As String
Dim updatedPageXML As String
Dim pageID As String
'VÉRIFICATION DES ONGLETS
If nodeSections.item(ongletNameDestination).Attributes.getNamedItem("name").Text <> "Projets en cours" Then MsgBox "onglet de destination erroné, supposé être Projets en cours mais " & nodeSections.item(ongletNameDestination).Attributes.getNamedItem("name").Text: Exit Sub
If nodeSections.item(ongletNameOrigine).Attributes.getNamedItem("name").Text <> "Templates" Then MsgBox "onglet de destination erroné, supposé être Templates mais " & nodeSections.item(ongletNameOrigine).Attributes.getNamedItem("name").Text: Exit Sub
'vérif template page name
If nodeSections.item(ongletNameOrigine).ChildNodes(0).Attributes.getNamedItem("name").Text <> TemplatePageName Then MsgBox "nom de page de template incorrect, devrait être " + TemplatePageName + " mais est: " + nodeSections.item(ongletNameOrigine).ChildNodes(0).Attributes.getNamedItem("name").Text: Exit Sub
'check if good notebook
If nodeSections.item(ongletNameDestination).ParentNode.Attributes.getNamedItem("name").Text <> notebookSortName Then MsgBox "mauvais notebook, supposé être " & notebookSortName & " mais " & nodeSections.item(ongletNameDestination).ParentNode.Attributes.getNamedItem("name").Text: Exit Sub
If nodeSections.item(ongletNameOrigine).ParentNode.Attributes.getNamedItem("name").Text <> notebookSortName Then MsgBox "mauvais notebook, supposé être " & notebookSortName & " mais " & nodeSections.item(ongletNameOrigine).ParentNode.Attributes.getNamedItem("name").Text: Exit Sub
sectionIDXML = nodeSections.item(ongletNameOrigine).Attributes.getNamedItem("ID").Text
section2IDXML = nodeSections.item(ongletNameDestination).Attributes.getNamedItem("ID").Text
onenote.MergeSections sectionIDXML, section2IDXML
onenote.GetHierarchy "", 4, oneNoteSectionsXml
Set doc = New MSXML2.DOMDocument
If doc.LoadXML(oneNoteSectionsXml) Then Set nodeSections = doc.DocumentElement.SelectNodes("//one:Section")
'onglet destination, rename template page
If nodeSections.item(ongletNameDestination).ChildNodes.Length > 0 Then
For x = 1 To nodeSections.item(ongletNameDestination).ChildNodes.Length
If nodeSections.item(ongletNameDestination).ChildNodes(x).Attributes.getNamedItem("name").Text = TemplatePageName Then
pageID = nodeSections.item(ongletNameDestination).ChildNodes(x).Attributes.getNamedItem("ID").Text
onenote.GetPageContent pageID, pageXML, 0
doc.LoadXML pageXML
doc.SelectSingleNode("//one:Page/one:Title/one:OE/one:T").Text = MypageName
updatedPageXML = doc.XML
'objShell.Popup updatedPageXML
onenote.UpdatePageContent updatedPageXML
onenote.UpdateHierarchy updatedPageXML
Exit For
End If
Next
End If
End If
End Sub
Upvotes: 0