Usando Excel VBA para enviar conteúdo ao OneNote - Artigos da TechTV

Em agosto, a Microsoft lançou a versão SP1 do OneNote. Esta é uma atualização obrigatória. Eles adicionaram muitos recursos incríveis, incluindo uma interface de programação de aplicativo que permite que outros aplicativos enviem dados para o OneNote.

A Microsoft oferece vários sites excelentes que irão ensiná-lo a usar o VB.Net para enviar dados para o OneNote. Mas, como este é o site, você, eu e os outros 200 milhões de usuários do Office estamos mais preocupados em como enviar dados para o OneNote usando o Office VBA. Estou feliz em dizer que isso PODE ser feito. Esta página irá guiá-lo por tudo que você precisa para fazer isso.

Presumo que você esteja moderadamente familiarizado com o VBA. Se não for, eu recomendo fortemente VBA & Macros for Microsoft Excel, o livro projetado para levar alguém até a curva de aprendizado do VBA.

Visão geral

Você pode enviar dados para o OneNote formatando os dados como dados XML. XML é um conceito bastante novo. É uma espécie de HTML. Pense nisso como um arquivo CSV com esteróides. Você pode ler minha introdução ao XML.

Basicamente, seu programa VBA precisa gravar um arquivo XML e, em seguida, passar o conteúdo do arquivo XML para o OneNote usando o método .Import. O arquivo XML deve conter estes elementos:

  • Um elemento VerifyPage para cada página que você deseja escrever. Se a página não existir, o OneNote criará a página para você. Em teoria, você deve ter controle e colocar a página após uma página existente específica. No entanto, na prática, isso não parece funcionar.
  • Um elemento PlaceObject para cada item que você deseja adicionar à página. Você especifica a localização X e Y para o item e a origem do item. Um item pode ser uma imagem, um objeto de tinta ou um texto no formato HTML. Você pensaria que, como o OneNote lê HTML, você poderia realmente passar uma tabela com tags TR e TD, mas isso não funciona. Você está limitado a passar texto com marcas BR e P para adicionar avanços de linha. As tags UL e LI parecem funcionar. Tags de fonte funcionam.

The Gotcha

Para atualizar uma página existente, você deve conhecer o Globally Unique Identifier (GUID) dessa página. Não parece haver uma maneira de localizar o GUID de uma página existente no OneNote. Isso significa que você só pode atualizar ou excluir itens em uma página existente se tiver criado a página programaticamente e tiver armazenado o GUID usado para criar essa página em sua pasta de trabalho. O exemplo abaixo usa um local isolado na planilha para salvar o GUID da página, a tabela de dados e o gráfico.

GUIDs

Cada nova página do OneNote precisa de um GUID. Cada novo objeto colocado em uma página precisa de um GUID. Embora seja fácil gerar GUIDs a partir do VB.Net, encontrar uma maneira de gerar GUIDs a partir do VBA tem sido difícil. Todos os 200 milhões de usuários do VBA do Office precisam dar uma olhada no limite para Michael Kaplan da Trigeminal Software. Michael parece ser o único cara no mundo a quebrar o código de como gerar um GUID a partir do VBA. Ele gentilmente compartilhou este código com o mundo. Confira o código completo em seu site. Com a permissão de Michael, copiei apenas as funções necessárias para gerar um novo GUID no VBA aqui. Insira um módulo em seu projeto e inclua o código a seguir nesse módulo.

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

Adicionando uma Referência

No VBA, use Ferramentas - Referências para adicionar uma referência à Biblioteca de Objetos do OneNote 1.1. Isso permitirá que você declare um novo objeto CSimpleImporter e, em seguida, use os métodos .Import e .NavigateToPage no objeto.

Estudo de caso

Esta pasta de trabalho do Excel contém um sistema de relatórios diários. Existe uma planilha para cada loja em uma rede local de lojas. Cada página contém uma tabela que mostra as vendas diárias e um gráfico que mostra o progresso em direção à meta mensal.

O código VBA adicionará uma nova seção chamada DailySales. Uma nova página será adicionada para cada loja. O gráfico da planilha é exportado como um arquivo GIF e importado para o OneNote. Os dados da planilha são adicionados ao OneNote como uma coluna HTML.

Vendas diárias

O código a seguir é usado no 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.

Artigos interessantes...