Bruke Excel VBA til å skyve innhold til OneNote - TechTV-artikler

I august ga Microsoft ut versjon SP1 av OneNote. Dette er en må-ha-oppgradering. De la til mange utrolige funksjoner, inkludert et applikasjonsprogrammeringsgrensesnitt som lar andre applikasjoner skyve data til OneNote.

Microsoft tilbyr flere gode nettsteder som vil lære deg hvordan du bruker VB.Net for å skyve data inn i OneNote. Men siden dette er nettstedet, er du og jeg og de andre 200 millioner Office-brukerne mest bekymret for hvordan du kan skyve data til OneNote ved hjelp av Office VBA. Jeg er glad for å si at dette KAN gjøres. Denne siden vil lede deg gjennom alt du trenger for å få det gjort.

Jeg vil anta at du er moderat kjent med VBA. Hvis du ikke er det, anbefaler jeg VBA og makroer for Microsoft Excel, boka designet for å ta noen opp i VBA-læringskurven.

Oversikt

Du kan sende data til OneNote ved å formatere dataene som XML-data. XML er et ganske nytt konsept. Det er liksom HTML. Tenk på det som en CSV-fil på steroider. Du kan lese min introduksjon til XML.

I utgangspunktet må VBA-programmet skrive ut en XML-fil, og deretter sende innholdet i XML-filen til OneNote ved hjelp av .Import-metoden. XML-filen må inneholde disse elementene:

  • Et EnsurePage-element for hver side du vil skrive til. Hvis siden ikke eksisterer, oppretter OneNote siden for deg. I teorien skal du ha kontroll og plassere siden etter en bestemt eksisterende side. I praksis ser det imidlertid ikke ut til å fungere.
  • Et PlaceObject-element for hvert element du vil legge til på siden. Du angir X & Y-plasseringen for varen og kilden til varen. Et element kan enten være et bilde, et blekkobjekt eller tekst i HTML-format. Du tror at siden OneNote leser fra HTML, kan du faktisk passere en tabell med TR- og TD-koder, men dette fungerer ikke. Du er begrenset til å sende tekst med BR- og P-koder for å legge til linjematinger. UL & LI-koder som ser ut til å fungere. Fontetiketter fungerer.

The Gotcha

For å oppdatere en eksisterende side, må du kjenne den globalt unike identifikatoren (GUID) for den siden. Det ser ikke ut til å være en måte å finne GUID for en eksisterende side i OneNote. Dette betyr at du bare kan oppdatere eller slette elementer på en eksisterende side hvis du programmatisk opprettet siden og har lagret GUID som ble brukt til å lage den siden i arbeidsboken din. Eksemplet nedenfor bruker et sted utenfor regnearket for å lagre GUID for siden, datatabellen og diagrammet.

GUIDer

Hver nye side i OneNote trenger en GUID. Hvert nytt objekt plassert på en side trenger en GUID. Selv om det er enkelt å generere GUID-er fra VB.Net, har det vært vanskelig å finne en måte å generere GUID-er fra VBA på. Alle 200 millioner Office VBA-brukere trenger å gi tipset av taket til Michael Kaplan fra Trigeminal Software. Michael ser ut til å være den eneste fyren i verden som bryter koden for hvordan man genererer en GUID fra VBA. Han har nådig delt denne koden med verden. Sjekk ut den fullstendige koden på nettstedet hans. Med Michaels tillatelse har jeg bare kopiert funksjonene som trengs for å generere en ny GUID i VBA her. Sett inn en modul i prosjektet og inkluder følgende kode 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

Legge til en referanse

I VBA bruker du Verktøy - Referanser for å legge til en referanse til OneNote 1.1-objektbiblioteket. Dette vil tillate deg å erklære et nytt CSimpleImporter-objekt og deretter bruke metodene .Import og .NavigateToPage på objektet.

Casestudie

Denne Excel-arbeidsboken inneholder et daglig rapporteringssystem. Det er ett regneark for hver butikk i en lokal butikkjede. Hver side inneholder en tabell som viser daglig salg og et diagram som viser fremgang mot det månedlige målet.

VBA-koden vil legge til en ny seksjon kalt DailySales. Én ny side vil bli lagt til for hver butikk. Diagrammet fra regnearket eksporteres som en GIF-fil og importeres til OneNote. Dataene fra regnearket blir lagt til OneNote som en HTML-kolonne.

Daglig salg

Følgende kode brukes 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.

Interessante artikler...