Använda Excel VBA för att skicka innehåll till OneNote - TechTV-artiklar

I augusti släppte Microsoft version SP1 av OneNote. Detta är en måste-uppgradering. De lade till många otroliga funktioner, inklusive ett applikationsprogrammeringsgränssnitt som gör att andra applikationer kan skicka data till OneNote.

Microsoft erbjuder flera utmärkta webbplatser som lär dig hur du använder VB.Net för att driva data till OneNote. Men eftersom det här är webbplatsen är du och jag och de andra 200 miljoner Office-användare mest bekymrade över hur man skickar data till OneNote med Office VBA. Jag är glad att kunna säga att detta KAN göras. Den här sidan guidar dig genom allt du behöver för att få det gjort.

Jag antar att du är måttligt bekant med VBA. Om du inte är det, rekommenderar jag starkt VBA och makron för Microsoft Excel, boken som är utformad för att ta någon upp i VBA: s inlärningskurva.

Översikt

Du kan skicka data till OneNote genom att formatera data som XML-data. XML är ett ganska nytt koncept. Det är ungefär som HTML. Tänk på det som en CSV-fil på steroider. Du kan läsa min introduktion till XML.

I grund och botten måste ditt VBA-program skriva ut en XML-fil och sedan skicka innehållet i XML-filen till OneNote med .Import-metoden. XML-filen måste innehålla dessa element:

  • Ett EnsurePage-element för varje sida som du vill skriva till. Om sidan inte finns skapar OneNote sidan åt dig. I teorin ska du ha kontroll och placera sidan efter en specifik befintlig sida. Men i praktiken verkar detta inte fungera.
  • Ett PlaceObject-element för varje objekt som du vill lägga till på sidan. Du anger X & Y-platsen för artikeln och källan för artikeln. Ett objekt kan antingen vara en bild, ett bläckobjekt eller text i HTML-format. Du skulle tro att eftersom OneNote läser från HTML, kan du faktiskt skicka en tabell med TR- och TD-taggar, men det fungerar inte. Du är begränsad till att skicka text med BR- och P-taggar för att lägga till linjeflöden. UL- och LI-taggar som verkar fungera. Font-taggar fungerar.

Gotcha

För att uppdatera en befintlig sida måste du känna till GUID (Globally Unique Identifier) ​​för den sidan. Det verkar inte finnas ett sätt att hitta GUID för en befintlig sida i OneNote. Det betyder att du bara kan uppdatera eller ta bort objekt på en befintlig sida om du programmatiskt har skapat sidan och har lagrat GUID som används för att skapa sidan i din arbetsbok. I exemplet nedan används en avvikande plats i kalkylbladet för att spara GUID för sidan, datatabellen och diagrammet.

GUID: er

Varje ny sida i OneNote behöver en GUID. Varje nytt objekt som placeras på en sida behöver en GUID. Även om det är enkelt att skapa GUID från VB.Net har det varit svårt att hitta ett sätt att generera GUID från VBA. Alla 200 miljoner Office VBA-användare behöver ge ett tips på taket till Michael Kaplan från Trigeminal Software. Michael verkar vara den enda killen i världen som bryter koden för hur man skapar en GUID från VBA. Han har nådigt delat den här koden med världen. Kolla in den fullständiga koden på hans webbplats. Med Michaels tillstånd har jag kopierat bara de funktioner som behövs för att skapa en ny GUID i VBA här. Sätt in en modul i ditt projekt och inkludera följande kod i den modulen.

'------------------------------------------ ' 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

Lägga till en referens

I VBA använder du Verktyg - Referenser för att lägga till en referens till objektbiblioteket OneNote 1.1. Detta gör att du kan deklarera ett nytt CSimpleImporter-objekt och sedan använda metoderna .Import och .NavigateToPage på objektet.

Fallstudie

Denna Excel-arbetsbok innehåller ett dagligt rapporteringssystem. Det finns ett kalkylblad för varje butik i en lokal butikskedja. Varje sida innehåller en tabell som visar daglig försäljning och ett diagram som visar framstegen mot det månatliga målet.

VBA-koden lägger till ett nytt avsnitt som heter DailySales. En ny sida läggs till för varje butik. Diagrammet från kalkylbladet exporteras som en GIF-fil och importeras till OneNote. Data från kalkylbladet läggs till OneNote som en HTML-kolumn.

Daglig försäljning

Följande kod används i 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.

Intressanta artiklar...