Използване на Excel VBA за изпращане на съдържание към OneNote - Статии от TechTV

През август Microsoft пусна версия SP1 на OneNote. Това е задължителен ъпгрейд. Те добавиха много невероятни функции, включват интерфейс за програмиране на приложения, който позволява на други приложения да изпращат данни към OneNote.

Microsoft предлага няколко отлични уебсайта, които ще ви научат как да използвате VB.Net, за да прехвърляте данни в OneNote. Но тъй като това е сайтът, ние с вас и останалите 200 милиона потребители на Office сме най-загрижени за това как да прехвърляме данни към OneNote с помощта на Office VBA. Щастлив съм да кажа, че това МОЖЕ да се направи. Тази страница ще ви преведе през всичко, от което се нуждаете, за да го направите.

Предполагам, че сте умело запознати с VBA. Ако не сте, горещо препоръчвам VBA и макроси за Microsoft Excel, книгата, предназначена да отведе някого до кривата на обучение по VBA.

Общ преглед

Можете да изпращате данни до OneNote, като ги форматирате като XML данни. XML е доста нова концепция. Това е нещо като HTML. Мислете за това като за CSV файл на стероиди. Можете да прочетете моето Въведение в XML.

По принцип вашата програма VBA трябва да запише XML файл, след което да предаде съдържанието на XML файла на OneNote, използвайки метода .Import. XML файлът трябва да съдържа следните елементи:

  • Елемент EnsurePage за всяка страница, на която искате да пишете. Ако страницата не съществува, OneNote ще създаде страницата за вас. На теория трябва да имате контрол и да поставите страницата след конкретна съществуваща страница. На практика обаче това изглежда не работи.
  • PlaceObject елемент за всеки елемент, който искате да добавите към страницата. Вие посочвате местоположението X & Y за елемента и източника на елемента. Елементът може да бъде изображение, обект с мастило или текст в HTML формат. Бихте си помислили, че тъй като OneNote чете от HTML, всъщност можете да предадете таблица с маркери TR и TD, но това не работи. Вие сте ограничени до предаване на текст с BR и P тагове, за да добавите емисии на линии. UL и LI маркерите изглежда да работят. Етикетите на шрифта работят.

The Gotcha

За да актуализирате съществуваща страница, трябва да знаете глобалния уникален идентификатор (GUID) за тази страница. Не изглежда да има начин да се намери GUID за съществуваща страница в OneNote. Това означава, че можете да актуализирате или изтривате елементи на съществуваща страница само ако сте създали програмно страницата и сте съхранили GUID, използван за създаването на тази страница във вашата работна книга. Примерът по-долу използва място извън работния лист, за да запази GUID за страницата, таблицата с данни и диаграмата.

GUID

Всяка нова страница в OneNote се нуждае от GUID. Всеки нов обект, поставен на страница, се нуждае от GUID. Въпреки че е лесно да се генерират GUID от VB.Net, намирането на начин за генериране на GUID от VBA е неуловим. Всички 200 милиона потребители на Office VBA трябва да дадат върха на Майкъл Каплан от Trigeminal Software. Майкъл изглежда единственият човек в света, който нарушава кода за това как да генерира GUID от VBA. Той любезно сподели този код със света. Вижте пълния код на уебсайта му. С разрешение на Майкъл копирах тук само функциите, необходими за генериране на нов GUID във VBA. Поставете модул във вашия проект и включете следния код в този модул.

'------------------------------------------ ' basGuid from http://www.trigeminal.com/code/guids.bas ' You may use this code in your applications, just make ' sure you keep the (c) notice and don't publish it anywhere ' as your own ' Copyright (c) 1999 Trigeminal Software, Inc. All Rights Reserved '------------------------------------------ Option Compare Binary ' Note that although Variants now have ' a VT_GUID type, this type is unsupported in VBA, ' so we must define our own here that will have the same ' binary layout as all GUIDs are expected by COM to ' have. Public Type GUID Data1 As Long Data2 As Integer Data3 As Integer Data4(7) As Byte End Type Public Declare Function StringFromGUID2 Lib "ole32.dll" _ (rclsid As GUID, ByVal lpsz As Long, ByVal cbMax As Long) As Long Public Declare Function CoCreateGuid Lib "ole32.dll" _ (rclsid As GUID) As Long '------------------------------------------------------------ ' StGuidGen ' ' Generates a new GUID, returning it in canonical ' (string) format '------------------------------------------------------------ Public Function StGuidGen() As String Dim rclsid As GUID If CoCreateGuid(rclsid) = 0 Then StGuidGen = StGuidFromGuid(rclsid) End If End Function '------------------------------------------------------------ ' StGuidFromGuid ' ' Converts a binary GUID to a canonical (string) GUID. '------------------------------------------------------------ Public Function StGuidFromGuid(rclsid As GUID) As String Dim rc As Long Dim stGuid As String ' 39 chars for the GUID plus room for the Null char stGuid = String$(40, vbNullChar) rc = StringFromGUID2(rclsid, StrPtr(stGuid), Len(stGuid) - 1) StGuidFromGuid = Left$(stGuid, rc - 1) End Function

Добавяне на справка

Във VBA използвайте Инструменти - Препратки, за да добавите препратка към библиотеката на обекти на OneNote 1.1. Това ще ви позволи да декларирате нов обект CSimpleImporter и след това да използвате методите .Import и .NavigateToPage за обекта.

Казус

Тази работна книга на Excel съдържа система за ежедневно отчитане. Има един работен лист за всеки магазин в местна верига магазини. Всяка страница съдържа таблица, показваща дневните продажби и диаграма, показваща напредъка към месечната цел.

Кодът на VBA ще добави нов раздел, наречен DailySales. За всеки магазин ще бъде добавена по една нова страница. Диаграмата от работния лист се експортира като GIF файл и се импортира в OneNote. Данните от работния лист се добавят към OneNote като HTML колона.

Ежедневни продажби

Следният код се използва в Excel.

Sub CreateUpdateOneNoteReport() ' Requires basGuid module from above Dim Cht As Chart fname = "C:OneNoteImport.xml" On Error Resume Next Kill (fname) On Error GoTo 0 ' Do we need new GUID's? For Each ws In ThisWorkbook.Worksheets If Not ws.Range("J22").Value> "" Then ws.Range("J22").Value = StGuidGen() End If If Not ws.Range("J23").Value> "" Then ws.Range("J23").Value = StGuidGen() End If If Not ws.Range("J24").Value> "" Then ws.Range("J24").Value = StGuidGen() End If Next ws ' Build a temporary XML file fname = "C:OneNoteImport.xml" On Error Resume Next Kill (fname) On Error GoTo 0 Open fname For Output As #1 Print #1, " " Print #1, " " ' Make sure that for each page, we have a page FirstPage = True DateStr = Format(Date - 1, "yyyy-mm-dd") & "T21:00:00-06:00" For Each ws In ThisWorkbook.Worksheets ThisTitle = ws.Name ThisGuid = ws.Range("J22").Value Print #1, " " FirstPage = False LastGuid = ThisGuid Next ws For Each ws In ThisWorkbook.Worksheets ThisTitle = ws.Name ThisImage = "C: " & ThisTitle & ".gif" ThisGuid = ws.Range("J22").Value ChartGuid = ws.Range("J24").Value TableGuid = ws.Range("J23").Value ' Export the Chart Set Cht = ws.ChartObjects(1).Chart Cht.Export Filename:=ThisImage, FilterName:="GIF" ' Place the Chart on the top, right side Print #1, "" Print #1, " " Print #1, "" Print #1, " " Print #1, " " Print #1, "  
Resulting OneNote Notebook

Apparent Bugs

In the book, I mentioned an apparent bug with "insertafter". I forgot that XML is case sensitive. If you use "insertAfter", then everything works fine. Thanks to Donovan Lange at Microsoft for pointing this out.

I am guessing that the next issue is not a bug - the code is probably working like Microsoft intended, but they missed an opportunity to do something the right way. You are allowed to specify a date and time in the EnsurePage section of the XML. This date and time is only used if the page does not exist. Given that Microsoft later allows us to update the page by remembering the GUID, they really should have allowed us to update the date and time on the page. In the example here, we are pushing new data each day, yet the date is always going to show that it is as of the first time that the program was run. This is disappointing.

Интересни статии...