Antonio Feliziani
a- a+

Interazioni e applicazioni Asp Net 2.0 con Excel e Word

Tecnologie utilizzate:

- Visual Studio 2005

- SQL 2005 Server Std

- VSTO 2005

- ASP.NET 2.0

 

Obiettivi:

- Panoramica VSTO e Framework 2.0

- Panoramica potenzialità Task Pane di Word ed Excel

- Creazione Webservice con VS 2005 e Framework 2.0 per agganciarsi ai dati

- Utilizzo dei VSTO per creare documenti Excel e Word che interagiscano con i webservice

 

Software Richiesto:

- Windows 2003 Server Std

- Office 2003 Professional

- VSTO 2005

- Visual Studio 2005 Professional

- SQL Server 2005 std

- IIS e ASP.NET 2.0

 

 

Grazie all’avvento del nuovo framework 2.0 e Visual Studio 2005 microsoft ha puntato decisamente alla programmazione Office introducendo I Visual Studio tools for Office 2005. A differenza dei precedenti (VSTO 2003), la programmazione Office è notevolmente migliorata grazie anche alla possibilità di poter avere integrato nel IDE di Visual Studio quello di Word o di Excel. Quindi oggi creare delle applicazioni office che possano interagire con I componenti che creiamo è molto più semplice.

In questo articolo andremo ad analizzare alcuni aspetti della nuova programmazione Office. Gli aspetti che andremo a toccare sono: Webservice, TaskPane, Word ed Excel.

L’applicazione che ho creato per questo articolo riprende il sito web AdventureWorks utilizzato durante gli eventi di lancio di Visual Studio 2005 (comunque sarà inserito nel file che andrete a scaricare). Questo sito è stato creato con la tecnologia ASP.NET 2.0 e come database usa SQL Server standard 2005. Creeremo due webservice: il primo che si occuperà di estrapolare tutti gli impiegati addetti alle vendite in base al territorio scelto e riempirà una lettera di ringraziamento scritta in Word 2003, il secondo si occuperà di estrapolare tutti gli acquisti avvenuti in un determinato periodo per popolare un diagramma su Excel 2003.

Di seguito troverete lo schema logico che la nostra applicazione seguirà:

http://blog.shareoffice.it/webmaster/gallery/image/145.aspx

Creazione webservice con Visual Studio 2005 e connettiamolo a SQL Server 2005

Prima di tutto creiamo un progetto vuoto che chiameremo AdventureWorks. A questo progetto vuoto aggiungiamo un progetto ASP.NET (il linguaggio utilizzato da me è il VB.NET) che chiameremo AdventureWeb.

NB: Nel progetto che potrete scaricare troverete anche il sito AdventureWorks completo

Per prima cosa aggiungiamo al nostro progetto web un primo webservice che chiameremo AdvOrders.asmx. Questo webservice verrà utilizzato dall’applicazione Excel per generare i grafici di fatturato in base ad ogni anno fiscale.

Visualizziamo il codice del webservice appena aggiunto al nostro progetto web e creiamo una funzione che chiameremo “Verify” .

NB: Questa funzione ho l’abitudine di crearla per verificare se il webservice è raggiungibile. E’ inutile che lanci una funzione senza prima aver controllato se il webservice è raggiungibile dalla mia applicazione. Immaginate di avere una funzione fondamentale (come quella del nostro esempio) nel webservice. Se quest’ultimo non è raggiungibile bloccherà tutta la nostra applicazione.

Il codice da inserire nel behind code del webservice:

 

 

"Returns “OK” if Webservice in online" , _

EnableSession:=False)> _

Public Function Verify() As String

Return "OK"

End Function

 

La funzione restituisce il valore “OK”.

Adesso possiamo passare a creare la funzione che genera il DataSet che utilizzeremo per il riempire l’oggetto ListObject del foglio di Excel.

Per prima cosa dobbiamo importare i NameSpace SQL, inseriamo nel codice del webservice le seguenti righe di codice:

 

 

Imports System.Web

Imports System.Data

Imports System.Data.SqlClient

Imports System.Web.Services

Imports System.Web.Services.Protocols

 

 

Importati i NameSpace principali di SQL possiamo creare la funzione che andrà a creare il DataSet. Questa funzione la chiameremo “RequestData”. Questa funzione si connetterà al Database SQL 2005 e lancerà una query che andrà ad estrapolare dalla tabella Sales.SalesOrderDetail tutti gli importi e li sommerà in base all’anno. (ES: Verranno estrapolati tutti gli ordini del anno 2004 e verranno sommati).

La funzione si presenterà così:

 

 

"Returns dataset with information about orders" , _

EnableSession:=False, BufferResponse:=True, CacheDuration:=600000)> _

Public Function RequestData() As DataSet


Dim OrdersData As New DataSet 'This is the dataset to return

Dim ConnectionToSql As New SqlConnection(System.Configuration.ConfigurationManager.AppSettings("ConnectionSql"))

ConnectionToSql.Open()

Dim daLinks As New SqlDataAdapter("SELECT TOP (100) PERCENT SUM(Sales.SalesOrderDetail.LineTotal) AS Total, DATEPART(yy, Sales.SalesOrderHeader.OrderDate) AS Year FROM Sales.SalesOrderDetail INNER JOIN Sales.SalesOrderHeader ON Sales.SalesOrderDetail.SalesOrderID = Sales.SalesOrderHeader.SalesOrderID GROUP BY DATEPART(yy, Sales.SalesOrderHeader.OrderDate)ORDER BY Year" , ConnectionToSql)

daLinks.Fill(OrdersData, "View1")


Return OrdersData

End Function

 

Adesso che abbiamo completato il webservice, salviamolo pubblichiamolo sul server web con IIS 6.0 e le ASP.NET 2.0 abilitate.

NB: Ricordatevi di settare la stringa di connessione al DB nel file web.config

 

Creazione Foglio di excel per la generazione del grafico con i dati estrapolati dal Webservice.

 

Aggiungiamo alla soluzione AdventureWorks un progetto Excel scritto con il linguaggio Visual Basic .NET. Chiamiamo il progetto DiagramOrder.

Visual Studio 2005 ci chiederà se vogliamo creare un documento Excel vuoto con il nome DiagramOrder.xls. Accettiamo premendo OK.

Come potrete notare si aprirà l’IDE di Excel 2003 all’interno di Visual Studio 2005.

Aggiungiamo una referenza al webservice precedentemente creato facendo click con il tasto destro sul progetto excel e selezionando la voce “Add Web Reference”.

Visual Studio ci chiederà dove possiamo trovare il webservice e selezioniamo la voce “Webservice in this solution” e chiamiamola “AdvWebservice”.

Trasciniamo dalla “Toolbox” di VS il controllo ListObject nella casella A-5 del foglio1 di Excel e chiamiamolo “List1”.

Referenziamo nel progetto il namespace del webservice:

 

Imports DiagramOrder.AdvWebservice

 

Inseriamo nello startup del foglio il seguente codice:

 

 

'Verify if Webservice is online

If AdvWebService.Verify.ToString = "OK" Then

'If Webservice is online i create a new dataset and fill List1

Dim ds As New DataSet

ds = AdvWebService.RequestData


List1.AutoSetDataBoundColumnHeaders = True 'Autoset cell

List1.DataSource = ds

List1.DataMember = "View1"

Else

'If Webservice is Down, excel write a message to the user

MessageBox.Show("Attenction: The webservice is unreacheable" , "Error" , MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly, False)

End If

 

Questo codice ci permette di verificare se effettivamente il webservice è online, se questo viene raggiunto, creiamo un DataSet e riempiamo il controllo List1 precedentemente creato.

Ritorniamo al nostro foglio di excel, selezioniamo il controllo ListObject. Si aprirà un menu che ci permetterà di aggiungere il grafico (<< graph.bmp >>).

Si[FG1] aprirà il wizard per la creazione del grafico. Selezioniamo il grafico Istogramma “3D non in pila” e premiamo sul pulsante “OK”.

Excel ci chiederà di selezionare la fonte di dati, selezioniamo il menu “Serie”. Nel campo “Nome” inseriamo “=Foglio1!$A$5”, nel campo “Valori” inseriamo “=Foglio1!$A$6”, nel campo “Etichette asse categorie (X)” inseriamo “=Foglio1!$B$6”.

Premiamo il tasto “Fine” per concludere il wizard.

Facciamo click con il tasto destro del mouse sul progetto “DiagramOrder”, selezioniamo la voce Debug e facciamo click su “Start new instance”. Visual Studio 2005 lancerà l’applicazione e sarà simile a questa:

http://blog.shareoffice.it/webmaster/gallery/image/175.aspx

Creazione webservice per estrapolare i dati degli impiegati addetti alle vendite

Questo webservice verrà utilizzato dalla nostra applicazione Word 2003 per riempire in maniera automatica una lettera di ringraziamento per il lavoro svolto e il fatturato raggiunto.

Questo webservice sarà composto da 4 funzioni di tipo public.

1) Verify (Questa funzione verrà utilizzata dall’applicazione word 2003 per verificare se il webservice è raggiungibile

2) TerritoryReturn (Questa funzione estrapola tutti i territori dal database)

3) ListEmployeeSales (Questa funzione estrapola tutti i commerciali in base al territorio di appartenenza)

4) EmployeeInformation (Questa funzione estrapola le informazioni di un dipendente in base al suo ID)

 

Per prima cosa creiamo un nuovo webservice all’interno del progetto web AdventureWeb, chiamiamo questo webservice EmployeeSales.asmx .

Creiamo la funzione TerritoriReturn che andrà ad estrapolare tutti i territori dal DB e restituirà un oggetto DataSet contenente tutti i dati sui territori:

 

 

'Return all Territory from Database

"Return all Territory" , _

EnableSession:=False)> _

Public Function TerritoryReturn() As DataSet

Dim TerritoryTable As New DataSet

Dim ConnectionToSQL As New SqlConnection(System.Configuration.ConfigurationManager.AppSettings("ConnectionSql"))

Dim daLinks As New SqlDataAdapter("SELECT Sales.SalesTerritory.*" _

& "FROM Sales.SalesTerritory" , ConnectionToSQL)


ConnectionToSQL.Open()

daLinks.Fill(TerritoryTable, "Territory")


Return TerritoryTable


ConnectionToSQL.Close()


End Function

 

 

Creaiamo la funzione LIstEmployeeSales che estrapolerà tutti gli impiegati addetti alle vendite in base ad un determinato territorio e restituirà un DataSet:

 

 

'Return a DataSet with Sales Employee selected by Territory

"Returns dataset with information about Sales Employee" , _

EnableSession:=False, BufferResponse:=True, CacheDuration:=600000)> _

Public Function ListEmployeeSales(ByVal Territory As String) As DataSet


Dim SalesData As New DataSet 'This is the dataset to return

Dim ConnectionToSql As New SqlConnection(System.Configuration.ConfigurationManager.AppSettings("ConnectionSql"))

ConnectionToSql.Open()

Dim daLinks As New SqlDataAdapter("SELECT Person.Contact.FirstName, Person.Contact.LastName, Sales.SalesTerritory.TerritoryID, HumanResources.Employee.EmployeeID " _

& "FROM Person.Contact INNER JOIN HumanResources.Employee ON Person.Contact.ContactID = HumanResources.Employee.ContactID " _

& "INNER JOIN Sales.SalesPerson AS SalesPerson_1 ON HumanResources.Employee.EmployeeID = SalesPerson_1.SalesPersonID " _

& "INNER JOIN Sales.SalesTerritory ON SalesPerson_1.TerritoryID = Sales.SalesTerritory.TerritoryID " _

& "WHERE (SalesPerson_1.TerritoryID = " & Territory & ")" , ConnectionToSql)

daLinks.Fill(SalesData, "SalesEmployeeTable")


Return SalesData


ConnectionToSql.Close()

End Function

 

 

L’ultima funzione che andremo a creare è quella che estrapola tutte le informazioni relative al dipendente (via, città, CAP, ecc …) in base ad un ID. La funzione restituirà un DataSet con tutte l informazioni estrapolate.

 

 

'Return all information about Sales Employee

"Return all information about sales employee" , _

EnableSession:=False)> _

Public Function EmployeeInformation(ByVal EmployeeID As String) As DataSet

Dim EmployeeInfo As New DataSet

Dim ConnectionToSQL As New SqlConnection(System.Configuration.ConfigurationManager.AppSettings("ConnectionSql"))

Dim daLinks As New SqlDataAdapter("SELECT Person.Contact.FirstName, Person.Contact.LastName, Sales.SalesTerritory.TerritoryID, HumanResources.Employee.EmployeeID, " _

& "Person.Address.AddressLine1, Person.Address.City, Person.Address.PostalCode, SalesPerson_1.SalesLastYear, SalesPerson_1.SalesQuota " _

& "FROM Person.Contact INNER JOIN " _

& "HumanResources.Employee ON Person.Contact.ContactID = HumanResources.Employee.ContactID INNER JOIN " _

& "Sales.SalesPerson AS SalesPerson_1 ON HumanResources.Employee.EmployeeID = SalesPerson_1.SalesPersonID INNER JOIN " _

& "Sales.SalesTerritory ON SalesPerson_1.TerritoryID = Sales.SalesTerritory.TerritoryID INNER JOIN " _

& "HumanResources.EmployeeAddress ON HumanResources.Employee.EmployeeID = HumanResources.EmployeeAddress.EmployeeID INNER JOIN " _

& "Person.Address ON HumanResources.EmployeeAddress.AddressID = Person.Address.AddressID AND " _

& "HumanResources.EmployeeAddress.AddressID = Person.Address.AddressID AND " _

& "HumanResources.EmployeeAddress.AddressID = Person.Address.AddressID AND " _

& "HumanResources.EmployeeAddress.AddressID = Person.Address.AddressID " _

& "WHERE (HumanResources.Employee.EmployeeID = " & EmployeeID & ")" , ConnectionToSQL)


ConnectionToSQL.Open()

daLinks.Fill(EmployeeInfo, "EmployeeInformation")


Return EmployeeInfo


ConnectionToSQL.Close()


End Function

 

 

Ripubblichiamo nuovamente il progetto web AdwentureWeb sul server con IIS 6 o 5 e le ASP.NET 2.0 abilitate.

NB: Per testare il corretto funzionamento del webservice possiamo lanciare un’istanza di Debug su Visual Studio 2005. I webservice, essendo lanciati in modalità localhost, dovrebbero darci la possibilità di inserire i dati per verificare il corretto funzionamento delle funzioni appena scritte.

http://blog.shareoffice.it/webmaster/gallery/image/178.aspx

http://blog.shareoffice.it/webmaster/gallery/image/179.aspx

Creazione applicazione word 2003 e TaskPane

Cosa dovrà fare l’applicazione:

Questa applicazione word, dovrà connettersi al webservice e visualizzare sul tast pane i territori all’interno di un controllo “DropDownList”. Una volta selezionato il territorio dovremo prmere il pulsante “Search” per estrapolare tutti gli addetti alle vendite del territorio selezionato.

Apparirà sul TaskPane un altro controllo DropDownList che verrà popolato con i cognomi dei dipendenti.

Selezioneremo il cognome che ci interessa e premendo il tasto “Select Employee” verranno estrapolati tutti i dati relativi a quel dipendente e verranno popolati tutti i bookmark sul foglio di Word 2003

 

Una volta creato il webservice possiamo passare alla creazione della lettera (che renderemo dinamica grazia ai VSTO 2005) scritta in Word 2003.

Per prima cosa aggiungiamo alla soluzione AdwentureWorks un nuovo progetto Office Word 2003 scritto in Visual Basic .NET. Questo progetto lo chiamiamo CongratulationLetter. Come per il progetto Excel, Visual Studio 2005 ci richiederà se vogliamo utilizzare come template un documento word già scritto in precedenza o se vogliamo utilizzare un documento word bianco.

Selezioniamo la voce “Copy an existing document” e premiamo il tasto “Browse … “.

Selezioniamo il documento word CongratulationLetter.doc (si trova all’interno della soluzione che scaricherete insieme a questo articolo), premete il tasto “OK” per confermare. Se tutto è andato bene, Visual Studio dovrebbe presentarsi così:

 

Come per Excel anche l’IDE di Word 2003 verrà integrato all’interno di Visual Studio 2005.

NB: Come avrete potuto notare, all’interno del documento word vi sono già dei Bookmark (parole all’interno di parentesi quadre di colore grigio chiaro). I Bookmark per i VSTO 2005 sono a tutti gli effetti degli oggetti e quindi hanno delle proprietà. Per dare un’occhiata alle proprietà di ogni singolo bookmark, basta posizionare il cursore all’interno del bookmark.

Per prima cosa dobbiamo creare l’ “Actions Pane Controls” che andremo a caricare all’interno del TaskPane. Facciamo click con il tasto destro del mouse ad aggiungiamo una nuova cartella che chiameremo “TaskPane”.

Aggiungiamo all’interno di questa cartella un nuovo “Item” di tipo “Actions Pane Control” e chiamiamolo “TaskMenu.vb”.

Aggiungiamo a questo oggetto i seguenti controlli:

N° 2 DropDownList

N° 3 Label

N° 2 Button

Una volta aggiunti i controlli, graficamente dovrebbe apparire così:

<< TaskMenu1.bmp >>

Andiamo nel Behindcode del controllo “TaskMenu.vb”. Per prima cosa dobbiamo popolare il primo DropDownList (nel mio progetto si chiama ListTerritory):

 

 

Private Sub TaskMenu_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

Dim Ds As New DataSet


Ds = AdvWebService.TerritoryReturn


ListTerritory.DataSource = Ds

ListTerritory.DisplayMember = "Territory.Name"

ListTerritory.ValueMember = "Territory.TerritoryID"


End Sub

 

Poi dobbiamo creare la funzione per i due pulsanti:

 

 

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

ListEmployee.Visible = True

Label3.Visible = True


Dim Ds2 As New DataSet


Ds2 = AdvWebService.ListEmployeeSales(ListTerritory.SelectedValue.ToString)

ListEmployee.DataSource = Ds2

ListEmployee.DisplayMember = "SalesEmployeeTable.LastName"

ListEmployee.ValueMember = "SalesEmployeeTable.EmployeeID"


End Sub


Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

Dim Ds3 As New DataSet

Ds3.Clear()

Ds3 = AdvWebService.EmployeeInformation(ListEmployee.SelectedValue.ToString)


Dim FName As New Binding("Text" , Ds3, "EmployeeInformation.FirstName")

Dim LName As New Binding("Text" , Ds3, "EmployeeInformation.LastName")

Dim AddressL As New Binding("Text" , Ds3, "EmployeeInformation.AddressLine1")

Dim PCode As New Binding("Text" , Ds3, "EmployeeInformation.PostalCode")

Dim City As New Binding("Text" , Ds3, "EmployeeInformation.City")

Dim DearName As New Binding("Text" , Ds3, "EmployeeInformation.FirstName")

Dim TotalSales As New Binding("Text" , Ds3, "EmployeeInformation.SalesLastYear")

Dim TotalRevenue As New Binding("Text" , Ds3, "EmployeeInformation.SalesQuota")



CongratulationLetter.Globals.ThisDocument.FirstName.DataBindings.Clear()

CongratulationLetter.Globals.ThisDocument.FirstName.DataBindings.Add(FName)


CongratulationLetter.Globals.ThisDocument.LastName.DataBindings.Clear()

CongratulationLetter.Globals.ThisDocument.LastName.DataBindings.Add(LName)


CongratulationLetter.Globals.ThisDocument.address.DataBindings.Clear()

CongratulationLetter.Globals.ThisDocument.address.DataBindings.Add(AddressL)


CongratulationLetter.Globals.ThisDocument.zip.DataBindings.Clear()

CongratulationLetter.Globals.ThisDocument.zip.DataBindings.Add(PCode)


CongratulationLetter.Globals.ThisDocument.city.DataBindings.Clear()

CongratulationLetter.Globals.ThisDocument.city.DataBindings.Add(City)


CongratulationLetter.Globals.ThisDocument.Dear.DataBindings.Clear()

CongratulationLetter.Globals.ThisDocument.Dear.DataBindings.Add(DearName)


CongratulationLetter.Globals.ThisDocument.TotalSales.DataBindings.Clear()

CongratulationLetter.Globals.ThisDocument.TotalSales.DataBindings.Add(TotalSales)


CongratulationLetter.Globals.ThisDocument.revenue.DataBindings.Clear()

CongratulationLetter.Globals.ThisDocument.revenue.DataBindings.Add(TotalRevenue)


End Sub

 

 

 

Ora passiamo al Behindcode del documento word. Aggiungiamo all’interno della subroutine “ThisDocument_Startup” le seguenti linee di codice:

 

 

'Add to Taskpane the usercontrol TaskMenu.vb

Me.ActionsPane.Controls.Add(ActionMenu)

Me.ActionsPane.Visible = True

 

In questo modo stiamo aggiungendo al documento word l’ “Action Task Pane” contenente il controllo TaskMenu.

Lanciamo il debug dell’applicazione “CongratulationLetter.doc” e noteremo che al cambiare del territorio e del dipendente cambieranno anche i dati presenti nel documento word.

http://blog.shareoffice.it/webmaster/gallery/image/180.aspx

 

Conclusioni

In questo progetto abbiamo visto come le applicazioni office 2003 possano interagire con i webservice presenti su di un sito web. Immaginate quante altre applicazioni possono essere create per ogni singola necessità (fatture, documenti di trasporto, cedolini ecc ecc).

 

-------------------------------

Fulvio Giaccari è Project Manager della Società SB Soft S.r.l. (Azienda Partner Microsoft). Si occupa di gestire progetti Office e Web per aziende private e per la pubblica amministrazione. Ha scritto diversi articoli in italiano su riviste di settore, sta per pubblicare un libro dedicato interamente ai VSTO. E’ speaker in moltissimi eventi Microsoft dedicati ad Office.

Inoltre è il responsabile di una Community dedicata ad ASP.NET (www.freeaspx.it) e del primo Usergroup Italiano dedicato agli sviluppatori Office (www.ShareOffice.it).
 



Ti potrebbe interessare anche

commenta la notizia

C'è 1 commento
Sara
Hai dubbi su questo articolo?