Creare un riquadro attività per Word 2007 con Visual Basic 2008 e VSTO
a cura di Alessandro Del Sole (requisiti: conoscenze di base Visual Studio Tools for Office)Introduzione
Molti di voi avranno sicuramente sentito parlare dei Visual Studio Tools for Office, quell'insieme di strumenti che permette di interagire con le applicazioni della nota suite Microsoft Office scrivendo codice managed. A differenza delle precedenti versioni, in Visual Studio 2008 (Professional o superiore) i Visual Studio Tools for Office vengono inclusi nell'ambiente di sviluppo e non è necessario ricorrere a componenti aggiuntivi. Questi tool, definiti per brevità anche VSTO, permettono di creare componenti aggiuntivi e/o di interagire con i documenti prodotti dalle applicazioni di Office scrivendo codice nel linguaggio di programmazione desiderato, sfruttando la consueta potenza di .NET Framework 3.5.In questo articolo ci occuperemo di creare un riquadro delle attività (Task Pane) personalizzato per Word 2007 mediante la realizzazione di una soluzione progettata in Visual Basic 2008. Approfitteremo, in questo modo, per dare un'occhiata più da vicino ai VSTO e per prendere confidenza con questi strumenti. Se non lo avete ancora fatto, potete scaricare dal sito Microsoft ed installare una delle edizioni Trial di Visual Studio 2008, che sono sufficienti per lo scopo.
Scopo del gioco
Le applicazioni di Office 2007 possono essere estese mediante componenti aggiuntivi. In questa sede, pertanto, ci occuperemo di creare un componente aggiuntivo (Add-in) per Word 2007 che avrà l'aspetto di un riquadro delle attività e si occuperà, mediante due pulsanti, di mostrare il numero totale delle revisioni in un documento e di esportare le revisioni sotto forma di file di testo. Il codice sorgente a corredo di questo articolo può essere scaricato, come di consueto, dall'Area Download di VB T&T.Creazione della soluzione
Avviate Visual Studio 2008 e utilizzate il comando New Project del menu File per aprire la finestra New Project. All'interno della categoria di progetti per Visual Basic 2008, espandete la cartella denominata Office, quindi selezionate la cartella denominata 2007. Selezionate il modello chiamato Word 2007 Add-in ed assegnate alla soluzione il nome TotalRevisionsWordAddIn, come in figura:![]()
Nel corso dell'articolo noterete che utilizzerò spesso il termine soluzione, piuttosto che progetto. Questo perché la documentazione ufficiale MSDN definisce due ambiti di sviluppo con i VSTO: soluzioni a livello di applicazione (componenti aggiuntivi) e soluzioni a livello di documento (con le quali è possibile interagire da codice con i documenti di Office).
Quando la soluzione viene creata, nella finestra Solution Explorer potete osservare la presenza di un file chiamato ThisAddIn.vb. Questo file di codice implementa una classe chiamata ThisAddIn, che rappresenta l'istanza del nostro componente aggiuntivo. Prima di passare ad esaminare questa classe, si rende però necessario fare una precisazione. Un riquadro delle attività di Word 2007 può ospitare un qualunque controllo Windows Forms. Tuttavia aggiungere un controllo già esistente non ha molto senso, poiché le operazioni che sarebbe possibile compiere sarebbero davvero limitate. Di conseguenza è conveniente sviluppare un controllo utente personalizzato, che descriveremo nel prossimo paragrafo.
Creazione di un controllo utente
Come accennato all'inizio dell'articolo, il nostro riquadro attività ha due finalità: mostrare il totale delle revisioni in un documento e l'esportazione delle revisioni in un file di testo. Il nostro controllo utente, quindi, conterrà due pulsanti, uno per obiettivo da raggiungere. Selezionate il comando Add user control del menu Project e, quando appare l'apposita finestra di dialogo, assegnate al controllo il nome RevisionsCounter. Una volta che il controllo è stato aggiunto alla soluzione e il designer diviene attivo, trascinate due pulsanti sulla superficie del controllo, come in figura:
Assegnate al primo pulsante il nome revButton e al secondo il nome exportRevButton. Passate ora all'editor di codice. In primo luogo inserite le due seguenti direttive Imports:
Imports System.Runtime.InteropServices Imports System.Windows.FormsCome osserveremo tra breve, le direttive ci occorrono per abbreviare il richiamo ad alcuni oggetti. Ora posizionate il cursore all'interno della classe. In primo luogo digitate il seguente codice:
Imports System.Runtime.InteropServices Imports System.Windows.FormsUn documento di Word è rappresentato da un oggetto Word.Document. Poiché il nostro controllo utente non agisce all'interno del componente aggiuntivo (quindi non può conoscere in anticipo con quale documento si trova ad operare) è necessario recuperare l'istanza attiva del documento correntemente aperto in Word. Tramite la proprietà ActiveDocument dell'oggetto Application (che rappresenta l'applicazione di Office con la quale si opera) è possibile ottenere detta istanza. Notate l'utilizzo della classe Globals, necessaria per evitare conflitti con altri oggetti dallo stesso nome. L'istanza del documento viene memorizzata in un campo document privato, di modo che venga recuperata una sola volta.
Il passo successivo è scrivere il codice relativo al gestore dell'evento Click per il pulsante revButton:
Private Sub revButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles revButton.Click Try 'La proprietà Count dell'oggetto Revisions riporta 'il numero totale delle revisioni in un documento MessageBox.Show("Il documento contiene " + document.Revisions.Count.ToString + " revisioni.", _ "", MessageBoxButtons.OK, MessageBoxIcon.Information) Catch ex As COMException MessageBox.Show(ex.ToString()) End Try End SubLe revisioni in un documento di Word sono rappresentate dall'oggetto Revisions. Come potete osservare, tramite la sua proprietà Count, ottenere il numero totale delle revisioni è un gioco da ragazzi. La COMException viene intercettata dal momento che i componenti aggiuntivi per Office, come vedremo più avanti, sfruttano proprio l'architettura COM. Il passaggio finale per il nostro user control è la scrittura del codice relativo al secondo pulsante:
Private Sub exportRevButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles exportRevButton.Click 'Campi per memorizzare alcune proprietà delle revisioni Dim author, revTime, range As String 'qui torna utile la Local Type Inference Dim allRevisions = document.Revisions 'Questa stringa conterrà la concatenazione delle revisioni. 'In uno scenario non didattico, è opportuno utilizzare un altro 'oggetto, come ad esempio una collection Dictionary(Of T,T) Dim revisionsList As String = Nothing Try 'ottiene una collection di revisioni nel documento 'e per ogni revisione concatena alcune proprietà in una stringa For Each revision As Word.Revision In allRevisions author = revision.Author revTime = revision.Date.ToString range = revision.Range.Text 'concatena la stringa revisionsList += String.Concat(author, ", ", revTime, ", Testo revisione: ", range, _ Environment.NewLine) Next 'Scrive in un file di testo le revisioni My.Computer.FileSystem.WriteAllText("C:\Revisioni.txt", revisionsList, False) 'ricordare che in scenari reali si intercettano eccezioni specifiche Catch ex As Exception MessageBox.Show(ex.ToString) End Try End SubSebbene in uno scenario reale ci siano modi migliori per raggiungere l'obiettivo desiderato, per brevità concateneremo tutte le revisioni in un'unica stringa, che verrà poi scritta in un file di testo. L'oggetto Revisions è, in realtà, una collection di oggetti Revision. Ciascun oggetto Revision gode di alcune proprietà, come ad esempio l'autore della revisione, il testo della revisione e un campo data-ora. Per ottenere queste proprietà per ciascuna revisione, è sufficiente utilizzare un ciclo For..Each per iterare sulla collection Revisions, come potete notare nel codice sopra esposto, concatenando nella stessa stringa le proprietà stesse. Al termine dell'iterazione, la stringa viene esportata in un file di testo che, per comodità, è stato chiamato Revisioni.txt e che viene memorizzato nella cartella C:\. Ad ogni buon conto, nulla vieta di estendere il codice prevedendo la possibilità di selezionare un pathname diverso, ad esempio con una finestra di dialogo.
Il nostro controllo utente è pronto per essere aggiunto al riquadro attività personalizzato, di cui ci occuperemo nel prossimo paragrafo.
Istanza del controllo utente ed aggiunta del riquadro attività a Word 2007
La parte finale del nostro lavoro riguarda l'aggiunta del riquadro attività a Word 2007. Il ciclo di vita di ogni componente aggiuntivo, quindi anche dei riquadri attività, è scandito da due speciali eventi: Startup e Shutdown. Potete facilmente intuire come il primo si verifichi al caricamento dell'add-in e il secondo alla chiusura. Tenuto conto di questa considerazione, il codice che inizializza il nostro add-in e lo aggiunge a Word 2007 va aggiunto nell'evento Startup della classe ThisAddIn. Ciò posto, attivate l'editor di codice sul file ThisAddIn.vb e sostituite il codice di default con il seguente:Imports Microsoft.Office.Tools 'La classe non è compatibile con le Common Language Specifications per via della sua classe base 'AddIn, che non aderisce alle specifiche <CLSCompliant(False)> Public Class ThisAddIn 'Un riquadro attività delle applicazioni Office è costituito da un oggetto CustomTaskPane Private riquadroAttivita As CustomTaskPane 'Con due sole righe di codice \u232 ? possibile aggiungere e mostrare il nostro riquadro attività Private Sub ThisAddIn_Startup(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles Me.Startup riquadroAttivita = Me.CustomTaskPanes.Add(New RevisionsCounter, "Conta/Esporta Revisioni") riquadroAttivita.Visible = True End Sub Private Sub ThisAddIn_Shutdown(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles Me.Shutdown End Sub End ClassIl namespace Microsoft.Office.Tools espone classi che operano direttamente sull'applicazione Office considerata e la direttiva Imports ci serve, come vedremo tra breve, per abbreviare la dichiarazione di istanza del riquadro attività. Un'altra importante considerazione va fatta in merito all'attributo CLSCompliant, impostato su False. Ciò si rende opportuno, sebbene non obbligatorio, dal momento che la classe AddIn (da cui ThisAddIn eredita) non aderisce alle specifiche Microsoft, per un discorso di interoperabilità con l'architettura COM.
Ciascun riquadro attività personalizzato è rappresentato da un oggetto CustomTaskPane. È possibile aggiungere i propri riquadri attività alla collection CustomTaskPanes mediante il suo metodo Add, che riceve come argomenti il controllo utente da visualizzare e il titolo per il riquadro. Impostando la proprietà Visible del riquadro su True, lo renderemo automaticamente disponibile all'utente. Con questi pochi e semplici passaggi abbiamo istanziato il nostro riquadro. Prima di vederlo in azione, dobbiamo curare un ultimo dettaglio. Come già detto, Microsoft Office sfrutta l'architettura COM. Poiché il nostro lavoro è stato compilato in un assembly .NET, prima di proseguire è necessario rendere l'assembly visibile all'architettura COM. Per farlo, aprite la finestra My Project, selezionate la scheda Application e fate clic sul pulsante Assembly Information. Apponete un segno di spunta sulla casella Make Assembly COM-Visible, come in figura:
![]()
Dopo questo piccolo accorgimento, siamo pronti per eseguire il test della nostra soluzione.
Test della soluzione
La nostra soluzione è pronta per essere provata. Premendo F5, la soluzione verrà compilata e, se la generazione non produce errori, verrà aperto Microsoft Word 2007 all'interno del quale potrete vedere in bella mostra il risultato del nostro lavoro. La figura seguente mostra un documento nel quale sono state aggiunte delle revisioni e per il quale è stato mostrato il totale delle revisioni utilizzando il pulsante Numero Revisioni, disponibile nel riquadro attività personalizzato Conta revisioni posto a destra (per ragioni di impaginazione, l'immagine è stata ridotta, se ci cliccate sopra potrete vederla nelle dimensioni naturali):Durante la generazione l'IDE aggiunge uno strong-name che ha valore di firma digitale per l'assembly ed è costituito da un file .pfx, del quale potrete scorgere la presenza nella finestra Solution Explorer.
Conclusioni
I Visual Studio Tools for Office non sono solo un'alternativa managed a VBA; in realtà, questo insieme di strumenti consente di avere un controllo pressoché completo sia sulle applicazioni costituenti la suite Microsoft Office, sia sui documenti da esse prodotti. Questo articolo è solo un assaggio delle potenzialità offerte, che potete approfondire tramite la documentazione ufficiale MSDN. Per ulteriori informazioni potete contattarmi al mio indirizzo visitare il mio blog.