Utilizzo di Excel VBA per inviare il contenuto a OneNote - Articoli TechTV

Ad agosto, Microsoft ha rilasciato la versione SP1 di OneNote. Questo è un aggiornamento indispensabile. Hanno aggiunto molte funzionalità incredibili, tra cui un'interfaccia di programmazione dell'applicazione che consente ad altre applicazioni di inviare dati a OneNote.

Microsoft offre diversi ottimi siti Web che ti insegneranno come utilizzare VB.Net per trasferire i dati in OneNote. Tuttavia, poiché questo è il sito, tu, io e gli altri 200 milioni di utenti di Office siamo più preoccupati di come inviare i dati a OneNote utilizzando Office VBA. Sono felice di dire che questo PU essere fatto. Questa pagina ti guiderà attraverso tutto ciò di cui hai bisogno per farlo.

Presumo che tu abbia una discreta familiarità con VBA. Se non lo sei, consiglio vivamente VBA e macro per Microsoft Excel, il libro progettato per portare qualcuno sulla curva di apprendimento VBA.

Panoramica

È possibile inviare dati a OneNote formattando i dati come dati XML. XML è un concetto abbastanza nuovo. È una specie di HTML. Pensalo come un file CSV con steroidi. Puoi leggere la mia Introduzione a XML.

Fondamentalmente, il tuo programma VBA deve scrivere un file XML, quindi passare il contenuto del file XML a OneNote utilizzando il metodo .Import. Il file XML deve contenere questi elementi:

  • Un elemento GuarantePage per ogni pagina in cui vuoi scrivere. Se la pagina non esiste, OneNote creerà la pagina per te. In teoria, dovresti avere il controllo e posizionare la pagina dopo una specifica pagina esistente. Tuttavia, in pratica, questo non sembra funzionare.
  • Un elemento PlaceObject per ogni elemento che desideri aggiungere alla pagina. Si specifica la posizione X e Y per l'elemento e l'origine dell'elemento. Un elemento può essere un'immagine, un oggetto Ink o un testo in formato HTML. Potresti pensare che poiché OneNote legge dall'HTML, potresti effettivamente passare una tabella con tag TR e TD, ma questo non funziona. Sei limitato a trasmettere testo con tag BR e P per aggiungere avanzamenti di riga. I tag UL e LI sembrano funzionare. I tag dei caratteri funzionano.

Il Gotcha

Per aggiornare una pagina esistente, devi conoscere l'identificatore univoco globale (GUID) per quella pagina. Non sembra essere un modo per trovare il GUID per una pagina esistente in OneNote. Ciò significa che è possibile aggiornare o eliminare elementi in una pagina esistente solo se la pagina è stata creata a livello di codice e se è stato memorizzato il GUID utilizzato per creare quella pagina nella cartella di lavoro. L'esempio seguente utilizza una posizione fuori mano nel foglio di lavoro per salvare il GUID per la pagina, la tabella dati e il grafico.

GUID

Ogni nuova pagina in OneNote richiede un GUID. Ogni nuovo oggetto inserito in una pagina necessita di un GUID. Sebbene sia facile generare GUID da VB.Net, trovare un modo per generare GUID da VBA è stato difficile. Tutti i 200 milioni di utenti di Office VBA devono dare una mancia a Michael Kaplan di Trigeminal Software. Michael sembra essere l'unico ragazzo al mondo a rompere il codice su come generare un GUID da VBA. Ha gentilmente condiviso questo codice con il mondo. Controlla il codice completo sul suo sito web. Con il permesso di Michael, ho copiato qui solo le funzioni necessarie per generare un nuovo GUID in VBA. Inserisci un modulo nel tuo progetto e includi il codice seguente in quel modulo.

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

Aggiunta di un riferimento

In VBA, usa Strumenti - Riferimenti per aggiungere un riferimento alla libreria di oggetti di OneNote 1.1. Ciò consentirà di dichiarare un nuovo oggetto CSimpleImporter e quindi utilizzare i metodi .Import e .NavigateToPage sull'oggetto.

Argomento di studio

Questa cartella di lavoro di Excel contiene un sistema di report giornaliero. È disponibile un foglio di lavoro per ogni negozio in una catena di negozi locale. Ogni pagina contiene una tabella che mostra le vendite giornaliere e un grafico che mostra i progressi verso l'obiettivo mensile.

Il codice VBA aggiungerà una nuova sezione chiamata DailySales. Verrà aggiunta una nuova pagina per ogni negozio. Il grafico del foglio di lavoro viene esportato come file GIF e importato in OneNote. I dati del foglio di lavoro vengono aggiunti a OneNote come colonna HTML.

Vendite giornaliere

Il codice seguente viene utilizzato in 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.

Articoli interessanti...