Переименуйте страницу в OneNote с помощью VBA, не можете применить изменения, не можете сохранить XML

Я хотел бы скопировать страницу из раздела шаблонов и переименовать ее. На данный момент я объединяю разделы, поскольку в разделе шаблонов у меня есть только одна страница. Поэтому мне нужно переименовать страницу в новом разделе, но я не могу заставить ее работать! Он меняет имя в коде, но не может применить его к документу.

Здесь код, который я использую с объявлением, следует за частью сразу после слияния этих разделов:

'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 не выдает ошибок, но не дает результатов, а doc.save выдает ошибку (неправильные параметры).

Это правильный способ сделать это?

Я перепробовал много решений, но ничего не работает. Исходный код был скопирован в Microsoft XML 6.0, но появилось много ошибок, поэтому я попытался адаптировать его для 5.0, и он работал, за исключением этой части.

Спасибо за помощь!

Добро пожаловать, patpower! Пожалуйста, уделите некоторое время прочтению введения в Stack Overflow и заработайте свой первый значок. Мы немного отличаемся от других сайтов. Вот как... stackoverflow.com/tour

MT1 28.05.2024 06:11

Мне также удалось создать новую страницу, поэтому, возможно, я объединил страницу шаблона с новой, чтобы получить ее содержимое, но созданная страница не имеет заголовка, а просто называется новой страницей.

patpower 28.05.2024 16:30

Я никогда не работал с OneNote и VBA из Excel. Не могли бы вы опубликовать код, показывающий, как вы создаете экземпляр OneNote, желательно какой-нибудь простой код, который я могу вырезать, вставить и запустить!

MT1 28.05.2024 17:00

Я добавил недостающую строку в сообщение, поэтому теперь оно должно работать как есть. Как я уже сказал, страница переименовывается в коде, но она доступна только для чтения, поэтому мне нужно сохранить XML, и она не работает. Updatepagecontent должно работать, но не может заставить его работать. Когда я создаю новую страницу, заголовка также нет, поэтому мне все равно нужно его переименовать, было бы здорово иметь возможность напрямую создать страницу с заголовком, а затем с помощью mergeobject, возможно, я мог бы объединиться со страницей шаблона, чтобы получить что-то на новой страница...

patpower 28.05.2024 19:25

Если это могло помочь, я взял код здесь: github.com/pierrms/Alphabetize-OneNote-Sections-VBA/blob/mas‌​ter/… Я попробовал это, и это работает, но я не хочу сортировать разделы, я просто хочу обновить иерархию страниц, изменив имя.

patpower 30.05.2024 17:36

еще одна информация: когда я пытаюсь выбрать узел заголовка, он все равно пуст, несмотря ни на что! Set titleNode = doc.SelectSingleNode("//one:Page/one:Title/one:OE/one:T")

patpower 03.06.2024 18:58
Преобразование HTML-таблицы в профессиональный документ Excel
Преобразование HTML-таблицы в профессиональный документ Excel
Это самый простой способ создания Excel из HTML-таблицы.
Импорт excel в laravel в базу данных
Импорт excel в laravel в базу данных
Здравствуйте, дорогой читатель, в этой статье я расскажу практическим и быстрым способом, как импортировать файл Excel в вашу базу данных с помощью...
0
6
88
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я наконец-то заработал. Я думаю, что мне нужно перезагрузить еще один XML-файл с содержимым страницы.

Вот весь код, если он может кому-то помочь! Он объединяет раздел шаблона (ongletNameOrigine) (индекс начального раздела) с разделом назначения (ongletNameDestination) (индекс раздела назначения), затем циклически проходит раздел назначения, чтобы найти страницу шаблона по ее имени TemplatePageName (у меня есть только одна страница в шаблоне раздел) и переименуйте его в правильное имя (MypageName). Он не оптимизирован, но вы можете использовать его для начала!

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

Вот код, который я использовал для переименования страницы в OneNote.

Имя страницы в OneNote является частью содержимого страницы, страницы уникально идентифицируются по своему GUID.

Я использовал следующий код, чтобы получить список GUID страниц (известных как идентификатор в OneNote).

Это упрощает иллюстрацию, поскольку затем страницы можно будет получить по их GUID.

У меня есть несколько страниц с одинаковым названием, так что, если то же самое относится и к вам, возможно, это так. стоит расположить страницы в алфавитном порядке, прежде чем менять их названия.

OneNote также позволяет использовать пустое имя страницы.

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

Затем я использовал этот код для получения XML-кода конкретной страницы, чтобы проверить, когда страница была переименована.

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

Ниже приведена простая процедура переименования страницы.

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

Затем используйте sbGetPageContent, чтобы проверить XML, и OneNote отобразит измененное имя страницы.

Примечания.

На моем компьютере с Windows 11 нет XML 5.0, только XML 3.0 и XML 6.0. DOMDocument следует называть MSXML2.DOMDocument60 Ссылки, которые я использовал, были следующими:

Visual Basic для приложений

Библиотека объектов Microsoft Excel 16.0

OLE-автоматизация

Библиотека объектов Microsoft Office 16.0

Microsoft XML, версия 6.0

Microsoft Visual Basic для расширения приложений 5.3

Библиотека объектов Microsoft OneNote 15.0

и код, который я использовал для перечисления ссылок, был -

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

Я использовал версию OneNote: «Microsoft® OneNote® для Microsoft 365 MSO (версия 2405, сборка 16.0.17628.20006), 64-разрядная версия». Судя по всему, существует предустановленная версия OneNote, поставляемая с Windows, известная как «OneNote для Windows 10». Я удалил его, чтобы убедиться, что знаю, какую версию использую.

Мой OneNote не синхронизируется с OneDrive, страницы сохраняются только на локальном компьютере. Каталог по умолчанию — «C:\Users\david\Documents\OneNote Notebooks».

Я использовал фрагменты многих примеров кода OneNote VBA из SO и MS Support. Не многие из них работали по следующим причинам.

Пространство имен в вызове .GetPageContent должно быть xs2013, иначе вызов ничего не вернет без сообщения, и это, очевидно, считается успехом. И это несмотря на то, что на моем компьютере установлена ​​версия OneNote «Build 16...».

Например, чтобы использовать сокращение «one:Notebook», перед использованием SelectNodes для объекта XML необходимо установить следующее свойство.

Dim doc As MSXML2.DOMDocument60
doc.SetProperty "SelectionNamespaces", "xmlns:one='http://schemas.microsoft.com/office/onenote/2013/onenote'" ' set this property before using SelectNodes

Это свойство также должно ссылаться на пространство имен 2013.

Код VBA запускается из Excel и может не работать, если OneNote открыт во время выполнения кода. Вероятно, ошибка будет «Ошибка автоматизации».

Другие вопросы по теме

Похожие вопросы

VBA – рассчитать точную разницу между датами (краевые случаи)
Как проверить, содержит ли ячейка фигуру?
Макрос стал очень медленным после функции фильтра
В Excel мне интересно, как использовать функцию ВПР в логике ИЛИ
Использование списка (диапазона) из нескольких критериев столбца и строки в формуле ФИЛЬТР
Вычисление СУММПРОИЗВ с использованием критериев нескольких столбцов и критериев одной строки (с пустыми столбцами и текстовыми столбцами в диапазоне данных)
Функция фильтра Доставляет пустые ячейки массива как нули, а другие пустые ячейки в ячейки, отформатированные по времени, как 12:00
Вычислить СУММПРОИЗВ с несколькими критериями столбца и одним критерием строки (с пустыми столбцами в диапазоне данных)
Диаграмма Excel: цветные метки данных по категориям — строки
Функция фильтра или альтернатива для вертикальных и горизонтальных критериев