Porting evolutivo di una applicazione per la gestione di riferimenti bibliografici in ambiente .net...
-
Upload
giulio-ambrogi -
Category
Education
-
view
334 -
download
2
Transcript of Porting evolutivo di una applicazione per la gestione di riferimenti bibliografici in ambiente .net...
DIPARTIMENTO DI INGEGNERIA
CORSO DI LAUREA TRIENNALE IN INGEGNERIA DELL'INFORMAZIONE
CURRICULUM INFORMATICA
PortingPortingPortingPorting evolutivo di una applicazione per la gestione di dati evolutivo di una applicazione per la gestione di dati evolutivo di una applicazione per la gestione di dati evolutivo di una applicazione per la gestione di dati
di riferimenti biliografici in ambiente .NET 4.5di riferimenti biliografici in ambiente .NET 4.5di riferimenti biliografici in ambiente .NET 4.5di riferimenti biliografici in ambiente .NET 4.5
Relatore : Prof. Prof. Prof. Prof. Maurizio FermegliaMaurizio FermegliaMaurizio FermegliaMaurizio Fermeglia
Laureando : Giulio AmbrogiGiulio AmbrogiGiulio AmbrogiGiulio Ambrogi
Anno Accademico : 2011 / 2012
2
Indice dei contenutiIndice dei contenutiIndice dei contenutiIndice dei contenuti
CAPITOLO 1CAPITOLO 1CAPITOLO 1CAPITOLO 1 Introduzione Introduzione Introduzione Introduzione (pag. 3)
CAPITOLO 2CAPITOLO 2CAPITOLO 2CAPITOLO 2 Analisi dei requisiti e della situazione esistente Analisi dei requisiti e della situazione esistente Analisi dei requisiti e della situazione esistente Analisi dei requisiti e della situazione esistente
2.1 Intervista al committente (pag. 5)
2.2 Analisi della situazione esistente (pag. 6)
2.2.1 Il database (pag. 6)
2.2.2 Applicazione esistente (pag. 9)
2.2.3 Data Bindig (pag 12)
2.2.4 SharePoint e Web Application (pag. 12)
CAPITOLO 3 ProgettazioneCAPITOLO 3 ProgettazioneCAPITOLO 3 ProgettazioneCAPITOLO 3 Progettazione
3.1 Principi generali di progettazione (pag. 13)
CAPITOLO 4 ImplementazioneCAPITOLO 4 ImplementazioneCAPITOLO 4 ImplementazioneCAPITOLO 4 Implementazione
4.1 Upload di file (pag. 15)
4.2 Cancellazione di file (pag. 22)
4.3 Opzioni utente (pag. 25)
4.4 Export (pag. 26)
4.5 Implementazioni di carattere generale (pag. 41)
CAPITOLO 5 ConclusioniCAPITOLO 5 ConclusioniCAPITOLO 5 ConclusioniCAPITOLO 5 Conclusioni
5.1 Possibili miglioramenti futuri (pag. 43)
5.2 Conclusioni (pag. 43)
3
CCCCAPITOLO 1APITOLO 1APITOLO 1APITOLO 1
IntroduzioneIntroduzioneIntroduzioneIntroduzione
L'obiettivo di questa tesi è estendere le funzionalità di un'applicazione client
esistente la quale è utilizzata per la gestione dei riferimenti bibliografici e delle
attività del laboratorio MOSE.
In particolare si vuole fornire all'utente, che utilizzerà l'applicazione,la possibilità di
gestire l'upload'upload'upload'upload e la cacacacancellazionencellazionencellazionencellazione di documenti relativi alle pubblicazione, di
esportare esportare esportare esportare in forma tabellare un insieme di record bibliograficirecord bibliograficirecord bibliograficirecord bibliografici e si intende
migliorare ulteriormente l'interfaccia utente ,per rendere l'applicazione
maggiormente user friendly , coerentemente con le nuove funzionalità da
implementare.
Nei capitoli successivi le singole funzionalità e la loro implementazione verranno
illustrate nello specifico.
La situazione iniziale vede l'esistenza di :
- versione beta dell'applicazione di cui si vuole effettuare il porting, ancora priva
delle sopracitate funzionalità;
- una base di dati ,su server remoto , nella quale sono immagazzinate tutte le
informazioni utilizzate dall'applicazione, come dati anagrafici, dati bibliografici,
ecc. ;
- un'istanza di SharePoint Server installata su un server remoto (un altro), utilizzata
dalla web application che lavora in parallelo all'applicazione in questione; è da
notare che quest'ultima ancora non comunica con tale istanza ;
4
in questo server vengono salvati i file pdf relativi alle pubblicazioni ;
- una web application che presenta sul Web i dati bibliografici e permette
all'utente di effettuare il download di un file pdf relativo ad una pubblicazione
Ciò che ha motivato la realizzazione di questo lavoro è la necessità di permettere
all'utente di svolgere alcune operazioni direttamente dall'applicazione, ovvero
svincolare l'utente dall'utilizzo di ulteriori softwaresvincolare l'utente dall'utilizzo di ulteriori softwaresvincolare l'utente dall'utilizzo di ulteriori softwaresvincolare l'utente dall'utilizzo di ulteriori software , garantendo così una maggiore
semplicità di esecuzione, una presentazione dei dati funzionale ed una maggiore
sicurezza relativamente all'integrità dei dati e all'aggiornamento degli stessi.
I vincoli progettualivincoli progettualivincoli progettualivincoli progettuali sono rappresentati in primo luogo dallo sviluppo in ambiente
.NET, utilizzando la tecnologia Windows Presentation Foundation e il linguaggio
di programmazione C#, in secondo luogo ,relativamente all'applicazione già
esistente, dall'attenersi per quanto possibile alla sua logica e infine
dall'implementare il tutto in modo tale che possa essere accessibile alla web
application.
Gli obiettivi di questo lavoro sono :
- analisi dei requisiti da parte del committente;
- analisi della situazione preesistente;
- studio delle tecnologie .NET, e nel particolare di WPF e C#;
- studio del funzionamento delle interazioni tra Database, applicazione e server;
- progettazione del front-end;
- realizzazione effettiva e compilazione su piattaforma .NET Framework 4.5;
- test e distribuzione dell'applicazione.
CAPITOLO 2CAPITOLO 2CAPITOLO 2CAPITOLO 2
Analisi dei requisitiAnalisi dei requisitiAnalisi dei requisitiAnalisi dei requisiti
2.1 Intervista al committente2.1 Intervista al committente2.1 Intervista al committente2.1 Intervista al committente
Le richieste del committente per la nuova
versione dell'applicazione sono :
• effettuare un analisi degli oggetti
programmabili (viste , stored
procedures , user defined functions
effettivamente utilizzati
dall'applicazione al fine di effettuare un lavoro di pulizia nella base di dati
• effettuare l'upload di un documento relativo ad una determinata
pubblicazione nel server sul quale
Server , aggiornando allo stesso tempo i
(Titolo del pdf e ID del documento)
Questo documento dovrà poi essere reperibile dalla
permette la visualizzazione dei contenuti dal web
• effettuare la cancellazione di un documento
bisogna gestire entrambi i "lati" : SharePoint e SQL Server)
disposizione opportuni controlli per verificare la presenza o meno di un
5
Analisi dei requisitiAnalisi dei requisitiAnalisi dei requisitiAnalisi dei requisiti e della situazione esistee della situazione esistee della situazione esistee della situazione esiste
2.1 Intervista al committente2.1 Intervista al committente2.1 Intervista al committente2.1 Intervista al committente
Le richieste del committente per la nuova
versione dell'applicazione sono :
ffettuare un analisi degli oggetti
viste , stored
procedures , user defined functions)
effettivamente utilizzati
dall'applicazione al fine di effettuare un lavoro di pulizia nella base di dati
ffettuare l'upload di un documento relativo ad una determinata
pubblicazione nel server sul quale è presente un'istanza di ShareP
Server , aggiornando allo stesso tempo i valori presenti nella base di dati
(Titolo del pdf e ID del documento).
Questo documento dovrà poi essere reperibile dalla web application
permette la visualizzazione dei contenuti dal web;
ffettuare la cancellazione di un documento (analogamente all'upload
bisogna gestire entrambi i "lati" : SharePoint e SQL Server) ed avere a
disposizione opportuni controlli per verificare la presenza o meno di un
e della situazione esistee della situazione esistee della situazione esistee della situazione esistentententente
dall'applicazione al fine di effettuare un lavoro di pulizia nella base di dati;
ffettuare l'upload di un documento relativo ad una determinata
è presente un'istanza di SharePoint
valori presenti nella base di dati
web application che
(analogamente all'upload
ed avere a
disposizione opportuni controlli per verificare la presenza o meno di un
6
documento, e potere gestire facilmente le azioni (upload , cancellazione,
presentazione) relative ad esso;
• poter esportare un file in formato Excel nel quale vengano riportati tutti i
dati relativi al titolo della pubblicazione, all'anno , agli autori, alla
denominazione e ai riferimenti, fornendo inoltre all'utente la possibilità di
filtrare i risultati a suo piacimento prima di effettuare l'export;
• eventuali accorgimenti per migliorare ulteriormente il front end.
2.22.22.22.2 Analisi della situazione esistenteAnalisi della situazione esistenteAnalisi della situazione esistenteAnalisi della situazione esistente
2.22.22.22.2.1 Il database.1 Il database.1 Il database.1 Il database
La base di dati esistente è sita in un server remoto ( di3.units.it ) ed è composta da
27 tabelle, 63 viste e 133 stored procedures.
Contiene tutti i dati inerenti la gestione del laboratorio come, ad esempio: dati
anagrafici dei dipendenti, dati delle pubblicazioni, congressi, progetti e tesi.
Le viste utilizzate dall'applicazione esistente sono:
• ViewPubblicazioniRivista : mette in relazione le informazioni delle riviste con
le informazioni dello staff;
• ViewPubblicazioniCongressi : mette in relazione i le informazioni dello staff
con il congresso relativo alla pubblicazione ;
• Staff_View : una raccolta dei dati anagrafici dei membri dello staff .
• ViewPubblicazioniRivista_Staff: variante della prima vista citata
Le stored procedures utilizzate dall'applicazione esistente sono:
7
• sp_PubbStaff : utilizzata per visualizzare le pubblicazioni relative ad un
membro dello staff. Riceve in input 2 parametri: @ID_staff è l'ID del
componente dello staff, mentre @ID_output è un parametro che se settato
a 0 fornisce sia le pubblicazioni presentate in un congresso che in una
rivista, se settato ad 1 fornisce solo le pubblicazioni presentate in un
congresso ed infine se settato a 2 fornisce solo le pubblicazioni presentate
in una rivista
• sp_PubbWeb: utilizzata per visualizzare le pubblicazioni presentate nel sito
web del MOSE. Riceve in input un parametro @ID_SitoWeb , che
rappresenta l'identificatore del sito web.
Non sono state trovate invece User Defined Functions.
Nella Figura 1 si riporta il Database Diagram della base di dati in questione :
8
TBL_Options
ID
FolderPDFDocument
TBL_PDFDocument
IDTitolo
NameFile
tblAnno
ID_Anno
Anno
tblCollegamentoKeywordsTitolo
Id_Keyword
ID_Titolo
tblCongressi
ID_Congresso
Denominazione
Data
Anno
CongressoIntenazionale
Referee
tblCorsi
ID_Corso
NomeCorso
EnteOrganizzatore
Periodo
Luogo
Anno
tblCurriculum
ID_Curriculum
Curriculum
CurriculumEN
tblGruppi
ID_Gruppo
Nome
NotetblKeyword
ID_Keyword
Keyword
tblProgetti
ID_Progetto
Progetto
SiglaProgetto
Anno_Inizio
Anno_Fine
Finanziatore
ResponsabileLocale
ResponsabileGlobale
FinanziamentoLocale
FinanziamentoGlobale
VIsualizzaSito
TipoProgetto
imgproject
summary
link
tblRiviste
ID_rivista
Denominazione
RivistaInternazionale
Referee
[Luogo pubblicazione]
ISSN
tblStaff
ID_Staff
Cognome
Nome
Attivo
Username
Amministratore
PhotoFileName
PhoneNumber
OfficeLocation
Summary
Education
ResearchActivity
ResearchProject
Collaborations
Enabled
tblStaffCongressi
ID_Staff
ID_Congresso
Presentazione
Organizzazione
Partecipazione
SuInvito
tblStaffCorsi
ID_Staff
ID_Corso
Organizzatore
tblStaffGruppi
ID_Gruppo
ID_Staff
Amministratore
tblStaffTitoli
ID_Staff
ID_Titoli
tblStatoTitolo
ID_Stato
Stato
Statoen
tblTesi
ID_Tesi
ID_Tipo
ArgomentoIT
ArgomentoEN
Collaborazione
Correlatori
ID_Curriculum
Stato
ID_Relatore
Autore
DataInizioTesi
MEseLAurea
AnnoLaurea
Voto
tblTesiDettaglio
ID_Tesi
DettaglioIT
DettaglioEN
tblTesiStato
ID_Stato
StatoTesi
tblTipiTesi
ID_Tipo
Tipo
tblTipoPubbl
ID_TipoPubb
TipoPubblicazione
TipoPubEnglish
Class_TS
Class_PD
tblTitoli
ID_Titolo
Autori
Riferimento
ID_Stato
ID_Rivista
ID_Congresso
Anno
Titolo
ID_tipoPubb
ID_SitoWeb
ImpactFactor
ID_Settore
tblTItoloProgetto
ID_progetto
ID_titolo
Versions
VersionId
Version
Id
UserName
TimeStamp
FinalizeTimeStamp
Mode
ModeStack
Updates
Notes
Figura 1
9
2.22.22.22.2.2.2.2.2 Analisi dell'applicazione esistenteAnalisi dell'applicazione esistenteAnalisi dell'applicazione esistenteAnalisi dell'applicazione esistente
Questa applicazione è stata implementata utilizzando la tecnologia Windows Windows Windows Windows
Presentation Foundation Presentation Foundation Presentation Foundation Presentation Foundation (linguaggi C# e XAML).
Il suo aspetto richiama quello delle applicazioni della suite Microsoft Office 2010.
Alcuni studi sulla User Experience condotti dalle più importanti software house,
hanno
dimostrato
come ,
attraverso
l'uso di
tecniche come
l'eye tracking,
l'utente tenda
a leggere i
contenuti delle pagine focalizzando maggiormente la propria attenzione su due
linee orizzontali nella parte alta della pagina e su una linea verticale nella parte
sinistra della pagina, secondo quello che è noto come schema ad F. Questo
rappresenta un grande punto di forza per l'applicazione.
La pagina visualizzata in Figura 2 è la home dell'applicazione , nella quale sono
presenti link testuali che rimandano alle diverse pagine, e pulsanti (nella banda in
grigio chiaro) che rimandano alle stesse.
L'applicazione esistente è di tipo navigationnavigationnavigationnavigation----basedbasedbasedbased, nello stile di numerose altre
applicazioni come Windows Explorer e Windows Media Player.
Le pagine sulle quali è stata focalizzata maggiormente l'attenzione sono quelle
relative alla gestione e alla presentazione dei dati relativi alle pubblicazionipubblicazionipubblicazionipubblicazioni.
Figura 2
10
Nella pagina relativa alle pubblicazioni si nota la presenza di 3 pulsanti: Dettaglio , Dettaglio , Dettaglio , Dettaglio ,
Griglia e Griglia e Griglia e Griglia e StaffStaffStaffStaff. Il primo di questi , lo si può già vedere nell'immagine, fornisce i
dettagli della pubblicazione selezionata attraverso gli appositi controlli (Figura 3), il
secondo fornisce una vista in un formato griglia, simulando l'interfaccia di una
tabella di SQL Server (Figura 4) ed il terzo infine raggruppa, in formato-griglia, le
pubblicazioni in base all'autore (Figura 5) ,che può essere selezionato attraverso
una apposita listbox.
Figura 3
Figura 4
11
I pulsanti Export e Upload non svolgono ancora alcuna funzione.
2.2.32.2.32.2.32.2.3 Data BindingData BindingData BindingData Binding
Lo scambio di dati tra applicazione e database avviene grazie ad una stringa di
connessione denominata MoseDBConnectionString.
Il tipo di autenticazione utilizzata è Windows Authentication.
<add name="MoseUXPrototype.Properties.Settings.MoseDBConnectionString"
connectionString="Data Source=SERVERNAME\SQLEXPRESS;
Initial Catalog=MoseDB;Integrated Security=True"
providerName="System.Data.SqlClient" />
Invece le interazioni tra applicazione e SharePoint (su server remoto) saranno
implementate come richieste HTTP corredate delle opportune credenziali e
verranno illustrate in seguito.
Figura 5
12
Questa stringa si trova nel file ./MoseUXPrototype.exe.config.xaml , il quale è
presente nel folder della versione distribuibile dell'applicazione.
2.2.42.2.42.2.42.2.4 Sharepoint ServerSharepoint ServerSharepoint ServerSharepoint Server e Web Applicatione Web Applicatione Web Applicatione Web Application
È presente inoltre una applicazione web che presenta le informazioni
bibliografiche su un sito web. Questo sito web è stato creato utilizzando Microsoft
SharePoint.
SharePoint è un software lato server che permette la creazione di particolari siti
web attraverso lo strumento software SharePoint Designer, con il quale è possibile
gestire, tra le varie cose, un archivio di file che possono essere utilizzati
dall'applicazione web.
I file delle pubblicazioni infatti sono salvati in una apposita cartella (
www.mose.units.it/doc ).
13
CAPITOLO 3CAPITOLO 3CAPITOLO 3CAPITOLO 3
ProgettazioneProgettazioneProgettazioneProgettazione
3.1 Principi generali di progettazione3.1 Principi generali di progettazione3.1 Principi generali di progettazione3.1 Principi generali di progettazione
L'idea di fondo è sempre quella di conservare il layout dell'applicazione esistente,
per quanto possibile, mantenendo vivace l'interfaccia e garantendone un facile e
sicuro utilizzo da parte dell'utente.
Per quanto riguarda sia l'upload che l'export si è deciso di implementare queste
due funzionalità su due diverse finestrefinestrefinestrefinestre, e non delle pagine : il motivo principale è
il voler marcare la differenza sostanziale tra la gestione di file gestione di file gestione di file gestione di file e la gestione di
record.
Si immagini di suddividere le funzionalità dell'applicazione su due livelli differenti:
• lettura/scrittura di record (comunicazioni tra applicazione e base di dati)
• gestione di file (upload / cancellazione) ed export (comunicazioni tra
applicazione , SharePoint e base di dati )
L'intera applicazione esistente si presenta all'utente su un'unica finestra e l'utente
può accedere ai diversi contenuti sfogliando tra le paginepaginepaginepagine di essa.
Si è preferito invece implementare le nuove funzionalità per la gestione dei file , su
finestrefinestrefinestrefinestre pop up , in modo tale da dare all'utente la sensazione di utilizzare uno
strumento con vero e proprio. Si intende implementare quindi un Uploader ed un
Exporter.
14
Si intende inoltre permettere all'utente di gestire le connessioni e le credenziali per
le interazioni web con i server, quindi sarà implementata un ulteriore finestra pop
up per la consolle delle opzioni.
Queste finestre saranno aperte da opportuni pulsanti posizionati nelle pagine
dell'applicazione coerentemente con la loro funzione.
CAPITOLO 4CAPITOLO 4CAPITOLO 4CAPITOLO 4
ImplementazioneImplementazioneImplementazioneImplementazione
4444.1 Upload.1 Upload.1 Upload.1 Upload
Si vuole caricare un file , relativo ad una determinata pubblicazione, su SharePoint
ed aggiornare i record del database SQL Server
pubblicazione" con "titolo del pdf
Il pulsante che permette di accedere a questa funzionalità è il pulsante
è implementato nella pagina
Cliccando su tale pulsante si accede ad un
(Figura 7).
L'interfaccia interfaccia interfaccia interfaccia (figura 7) di questa finestra è stata implementata in modo tale da
15
ImplementazioneImplementazioneImplementazioneImplementazione
Si vuole caricare un file , relativo ad una determinata pubblicazione, su SharePoint
ed aggiornare i record del database SQL Server che associano "id della
titolo del pdf" (Figura 6).
Il pulsante che permette di accedere a questa funzionalità è il pulsante
nella pagina Pubblicazioni (Figura 3,4,5).
Cliccando su tale pulsante si accede ad una nuova finestra : la console di upload
di questa finestra è stata implementata in modo tale da
Si vuole caricare un file , relativo ad una determinata pubblicazione, su SharePoint
id della
Il pulsante che permette di accedere a questa funzionalità è il pulsante UploadUploadUploadUpload che
nuova finestra : la console di upload
di questa finestra è stata implementata in modo tale da :
Figura 6
16
• selezionare, attraverso una listBox, la pubblicazione per la quale si vuole
effettuare l'upload del file;
• cercare e selezionare il file da caricare;
• selezionare il server e il percorso all'interno del quale caricare il
documento;
• di impostare le proprie credenziali (Username, Dominio e Password);
• eseguire effettivamente l'upload.
È presente inoltre un pulsante per effettuare un refresh della finestra.
Figura 7
17
La listbox che presenta le pubblicazioni esistenti viene popolata attraverso il
metodo RiempiListbox(), il quale esegue una query di tipo select sul database
descritto dalla stringa di connessione, si riporta di seguito il codice:
public void RiempiListBox()
{
try
{
string query = "select ID_Titolo, Anno, Titolo
from ViewPubblicazioniCongressi union
select ID_Titolo,Anno,Titolo
from ViewPubblicazioniRivista";
SqlConnection cn=new
SqlConnection(Properties.Settings.Default.MoseDBConnectionString);
SqlCommand cm = new SqlCommand(query);
cm.Connection = cn;
cn.Open();
SqlDataReader dr = cm.ExecuteReader();
while (dr.Read())
{
listBox1.Items.Add(dr["ID_Titolo"]+", "+dr["Anno"]+", "+dr["Titolo"]);
}
dr.Close();
dr.Dispose();
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
}
Il file dialog per la selezione del documento da caricare viene invece aperto
cliccando sul pulsante Sfoglia (btnSfoglia) , si riporta di seguito il codice relativo:
private void btnSfoglia_Click(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFil
Nullable<bool> result = dlg.ShowDialog();
if (result == true
{
string filename = dlg.FileName;
// aggiorno il contenuto della textbox
textBox1.Text = filename;
}
}
Una tipica esecuzione dell'upload è rappresenta
Di seguito è riportato il codice dell'effettivo upload del documento:
private bool Upload(string
{
try
Figura 8
18
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
> result = dlg.ShowDialog();
true)
filename = dlg.FileName;
// aggiorno il contenuto della textbox
textBox1.Text = filename;
Una tipica esecuzione dell'upload è rappresentata in pseudo codice in Figura 8
Di seguito è riportato il codice dell'effettivo upload del documento:
string myFile)
Microsoft.Win32.OpenFileDialog();
ta in pseudo codice in Figura 8 :
Di seguito è riportato il codice dell'effettivo upload del documento:
19
{
//UPLOAD SU SQL SERVER
SqlConnection connection1 = new
SqlConnection(Properties.Settings.Default.MoseDBConnectionString);
string id = listBox1.SelectedItem.ToString();
string[] words = id.Split(',');
//creo un array contenente i campi della selezione
SqlCommand command = new SqlCommand("select IDTitolo from TBL_PDFDocument
where IDTitolo=" + words[0]);
command.Connection = connection1;
connection1.Open(); //apro la connessione
if (command.ExecuteScalar() != null){
connection1.Close();
}
else { //se non c'è il documento nel db lo inserisco
connection1.Close();
SqlCommand insertPdf = new SqlCommand("insert into
TBL_PDFDocument values ("
+ words[0] + " , " + "'P" + returnID() + ".pdf')");
insertPdf.Connection = connection1;
connection1.Open();
insertPdf.ExecuteNonQuery();
connection1.Close();
}
connection1.Close();
//UPLOAD SU SHAREPOINT
WebClient client = new WebClient();
//vado a reperire le credenziali dell'utente
client.Credentials = new System.Net.NetworkCredential(textBox4.Text,
passwordBox1.Password, textBox5.Text);
string url="http://"+textBox2.Text+":" + textBox3.Text+"/";
client.UploadFile(url+"P"+returnID()+".pdf" , "PUT", myFile);
client.Dispose();
MessageBox.Show("upload su sharepoint e su sql eseguito
\nDocumento : p"+returnID()+".pdf");
}
catch (Exception err)
{
MessageBox.Show(err.Message);
20
return false;
}
return true;
}
Analisi del codice Analisi del codice Analisi del codice Analisi del codice [ metodo Upload ][ metodo Upload ][ metodo Upload ][ metodo Upload ]
Come si puo' notare il metodo è diviso fondamentalmente in due partidue partidue partidue parti:
l'aggiornamento di record su SQL Server e l'upload su SharePoint.
Per quanto riguarda l'aggiornamento del record su SQLl'aggiornamento del record su SQLl'aggiornamento del record su SQLl'aggiornamento del record su SQL ServerServerServerServer , le fasi di
realizzazione sono:
• creazione di un nuovo oggetto Connection (per poter comunicare con
l'istanza di SQL Server) e in particolare attraverso l'utilizzo della
MoseDBConnectionString.
• reperimento dell'ID del documento selezionato dalla listbox , attraverso un
metodo abbastanza rudimentale ma efficace: ovvero, viene effettuato un
parsing dell'elemento selezionato (in formato stringa) al fine di estrarre il
primo membro separato da virgola, ovvero l'ID della pubblicazione
• costruzione della query in linguaggio Transact-SQL
Questa query fornisce un risultato numerico, se il documento è già
presente nella tabella (tabella delle pubblicazioni aventi già un file relativo
caricato), altrimenti restituisce un valore nullo se questo file non è presente:
• Se il record è già presente nella tabella, questo record non viene
aggiornato;
• Se il record non è presente viene eseguita una nuova query
(statement di tipo INSERT ) che inserisce nella tabella (ID, nome del
file).
E' da notare che il nome del file , obbedisce ad uno standard dovuto ad un vincolo
imposto dalla web application ,che lavora in parallelo con questa applicazione , in
particolare il nome del file dovrà essere nel formato "Pxxxx.pdf" dove xxxx
21
rappresenta l'id della pubblicazione (ad es. se l'id della pubblicazione è 16 , il
documento si chiamerà "p0016.pdf").
Il metodo returnID() è un semplice metodo che utilizza l'ID della pubblicazione
selezionata e crea la parte numerica del nome del file apponendo a sinistra dell'ID
tanti zeri quanti sono necessari al fine di ottenere un nome con 4 cifre .
private string returnID()
{
string id = listBox1.SelectedItem.ToString();
string[] words = id.Split(',');
string returnstring;
if (words[0].Length == 1) {
returnstring = "000" + words[0];
return returnstring; }
else if (words[0].Length == 2) {
returnstring = "00" + words[0];
return returnstring; }
else if (words[0].Length == 3) {
returnstring = "0" + words[0]; return returnstring; }
else {
return words[0]; }
}
Per quanto riguarda l'upload upload upload upload del documento su SharePointSharePointSharePointSharePoint:
• in input si riceve il path del file (locale) da caricare;
• viene creato un oggetto di tipo client che sarà il virtuale esecutore
dell'upload;
• a questo oggetto vengono assegnate le credenziali per la richiesta http ,
che saranno reperite dalle textBox (Username e Dominio) e dalla
passwordBox (Password);
• viene costruita la stringa dell'url nel quale sarà caricato il file andando a
reperire le informazioni dalle textBox (Server e Folder);
• attraverso il metodo
caricato il documento
tipo PUT.
4444.2 Cancellazione di files.2 Cancellazione di files.2 Cancellazione di files.2 Cancellazione di files
E' stata implementata un interfaccia utente per migliorare l'interazione con le
funzionalità aggiunte e per dare all'utente la possibilità di cancellare un file pdf
Nella schermata relativa al dettaglio
aggiunti :
• un indicatore che segnala se è
relativo alla pubblicazione selezionata
• un pulsante che rimanda alla finestra di upload;
• un pulsante che permette, in caso di pre
È più interessante concentrarsi sull'implementazione di quest'ultimo considerata la
semplicità degli altri controlli citati.
Come per l'upload del documento, la cancellazione dovrà essere e
entrambi i "lati" (SQL Server e SharePoint)
Figura 9
22
ttraverso il metodo UploadFile dell'oggetto di tipo WebClient
caricato il documento su SharePoint , per mezzo di una richiesta HTTP di
.2 Cancellazione di files.2 Cancellazione di files.2 Cancellazione di files.2 Cancellazione di files
stata implementata un interfaccia utente per migliorare l'interazione con le
e per dare all'utente la possibilità di cancellare un file pdf
Nella schermata relativa al dettaglio della pubblicazione (Figura 9 )
indicatore che segnala se è presente o meno, nel database
relativo alla pubblicazione selezionata;
rimanda alla finestra di upload;
un pulsante che permette, in caso di presenza di un file, di cancellarlo.
È più interessante concentrarsi sull'implementazione di quest'ultimo considerata la
semplicità degli altri controlli citati.
Come per l'upload del documento, la cancellazione dovrà essere effettuata
SQL Server e SharePoint).
WebClient viene poi
di una richiesta HTTP di
stata implementata un interfaccia utente per migliorare l'interazione con le
e per dare all'utente la possibilità di cancellare un file pdf.
sono stati
nel database ,un file
senza di un file, di cancellarlo.
È più interessante concentrarsi sull'implementazione di quest'ultimo considerata la
ffettuata su
23
Per il primo contesto viene eseguita una query del tipo : "delete from
TBL_PDFDocument where IDTitolo= ".
Mentre per la cancellazione in ambiente SharePoint viene eseguita una richiesta
http di tipo DELETE, corredando la request delle credenziali opportune.
Si riporta di seguito il codice utilizzato per la cancellazione del documento.
private void DeletePDF()
{
try
{
//CANCELLAZIONE SU SQL SERVER
System.Windows.Window loading =
new System.Windows.Window { Height = 100, Width = 200,
WindowStartupLocation = WindowStartupLocation.CenterScreen,
WindowStyle = WindowStyle.None };
loading.Content = new TextBlock { Text = "Please Wait",
FontSize = 30, FontWeight = FontWeights.Bold,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center };
loading.Show();// Mostra finestra di attesa
tblTitoli currentTitle =
(tblTitoli)this.MasterView.CurrentItem;
Figura 10
24
int IDTitolo = currentTitle.ID_Titolo;
SqlConnection connection1 =
new
SqlConnection(Properties.Settings.Default.MoseDBConnectionString);
SqlCommand command =
new SqlCommand("delete from TBL_PDFDocument
where IDTitolo=" + IDTitolo);
command.Connection = connection1;
connection1.Open();
command.ExecuteNonQuery();
connection1.Close();
label1.Content= SetLabel();
//CANCELLAZIONE SU SHAREPOINT
string nomeFile = "P" + returnID() + ".pdf";
string url = "http://"+Properties.Settings.Default.Server+":"
+Properties.Settings.Default.Sito
+"/"+nomeFile; //server:sito
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
req.Credentials =
new System.Net.NetworkCredential(Properties.Settings.Default.Username,
Properties.Settings.Default.Password,
Properties.Settings.Default.Dominio);
req.Method="DELETE";
HttpWebResponse response = (HttpWebResponse)req.GetResponse();
loading.Close();
MessageBox.Show("Il documento : P" + returnID()
+ ".pdf è stato eliminato");
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
25
4.34.34.34.3 Opzioni UtenteOpzioni UtenteOpzioni UtenteOpzioni Utente
Il pulsante Opzioni (Figura 11) permette all'utente di visualizzare una nuova finestra
(Figura 12) all'interno della quale sarà possibile impostare dei valori di default per
le credenziali, in modo tale da non dover selezionare il server ed autenticarsi ogni
qualvolta si dovesse caricare o cancellare un documento da SharePoint.
Queste impostazioni di configurazione, sono salvate, al primo utilizzo
dell'applicazione, nel file MoseUXPrototype,xml.config , mentre successivamente in
automatico, l'applicazione andrà a reperire questi settaggi da un file presente in
C:/Users/NomeUser/AppData/Local/ che viene creato al primo utilizzo di questa .
All'interno di questa finestra, il pulsante Conferma esegue una modifica del valore
delle stringhe di default presenti nelle file di configurazione dell'applicazione:
• Properties.Settings.Default.Server,
• Properties.Settings.Default.Sito,
• Properties.Settings.Default.Username,
• Properties.Settings.Default.Password,
• Properties.Settings.Default.Dominio.
Figura 11
26
4.44.44.44.4 ExportExportExportExport
Questa funzione permette all'utente di esportare in un foglio elettronico Excel i
dati delle pubblicazioni.
In particolare le informazioni che possono essere reperite sono:
• Anno di pubblicazione;
• Titolo ;
• Autore/i ;
• Riferimento ;
• Congresso (nel quale è stata presentata la pubblicazione) .
Sono presenti inoltre alcuni filtri aggiuntivi che permettono di raffinare la ricerca:
• intervallo di tempo (anni);
• tipo di pubblicazione;
• membro dello staff (autore).
Come si può notare nell'immagine (Figura 13), l'utente può scegliere se inserire o
meno ognuno dei 5 campi in alto a sinistra , selezionando o deselezionando le
checkbox.
Figura 12
27
Il processo di esportazione
in formato Excel dei dati
richiesti dall'utente si
svolge in 4 passaggi
fondamentali:
1. operazioni
preliminari (ad es.
popolamento
combobox)
2. costruzione della
query da eseguire
sulla base di dati, in
base ai campi
selezionati
dall'utente
3. compilazione di un
file di testo semplice , utilizzando il delimitatore tab (\t), utilizzando i dati di
output della query
4. apertura del file di testo da parte dell'applicazione Excel riconoscendo il tab
Primo passo
La comboBox relativa ai membri dello staff si popola grazie ad una query eseguita
sulla base di dati, questa query estrapola Nome e Cognome dei membri dello staff
public void LoadCmbStaff() {
try
{
Figura 13
28
SqlConnection cn = new
SqlConnection(Properties.Settings.Default.MoseDBConnectionString);
SqlCommand cm = new SqlCommand("SELECT Cognome , Nome FROM tblStaff");
cm.Connection = cn;
cn.Open();
SqlDataReader dr = cm.ExecuteReader();
while (dr.Read())
{
//popolamento della combobox
cmbStaff.Items.Add(dr["Cognome"]+" , "+dr["Nome"]);
}
dr.Close();
dr.Dispose();
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
}
Secondo passo
L'idea che sta alla base di questa implementazione è quella di analizzare elemento
per elemento (Titolo, Autore, Anno, ecc ) le richieste dell'utente e costruire
coerentemente la query.
L'algoritmo per la costruzione della stringa , che sarà il contenuto della query si
costituisce di 3 steps fondamentali, in base ai campi che vengono selezionati e in
base ai filtri che vengono attivati:
• costruzione della stringa "SELECT …FROM…"
• costruzione della stringa "WHERE …"
• coordinamento del tutto e costruzione della stringa completa
29
Nelle pagine seguenti viene riportato l'algoritmo in pseudocodice (Figure 14 e
15):
Figura 14
Stringa = «SELECT»
Anno is checked
Stringa = Stringa + «Anno»
Titolo is checked
Stringa = Stringa + «Titolo»
Autori is checked
Stringa = Stringa + «Autori»
Riferimento is checked
Stringa = Stringa + «Riferimento»
Denominazione is checked
Stringa = Stringa +
«Denominazione»
Stringa1 = «WHERE»
IF Dal != null
Stringa1 = Stringa1 +
«ANNO >= Dal »
IF Al != null
Stringa1 = Stringa1 +
«ANNO <= Al »
IF Autore != Tutti
Stringa1 = Stringa1 +
«AUTORI LIKE ‘CognomeAutore’»
F
F
F
F
T
T
T
T
T T
T
T
F
F
F
strWhere = Stringa1
strSelect = Stringa
F
Figura 14
30
Il passaggio finale (Figura 15) è motivato dal fatto che è possibile che una
pubblicazione sia riferita contemporaneamente ad una rivistarivistarivistarivista e ad un congressocongressocongressocongresso, e
quindi bisogna fornire all'utente la possibilità di scegliere che tipo di dato
visualizzare , se la prima, se la seconda o se entrambe.
Di seguito si riporta il metodo per la creazione della parte iniziale della query:
string CorpoStringCongressi = " FROM dbo.ViewPubblicazioniCongressi ";
string CorpoStringRiviste = " FROM dbo.ViewPubblicazioniRivista ";
private string CostruisciQueryIniziale()
{
string SelectBase = "SELECT ";
string Supporto = SelectBase;
if (checkBoxAnno.IsChecked == true)
{
/*
Questi IF interni servono ad evitare il caso in cui ci si
trovi ad avere una
Select del tipo: >> SELECT , NOME << (virgola in mezzo)
*/
if (Supporto == "SELECT ") { Supporto = Supporto + " Anno ";}
else
{
Supporto = Supporto + ", Anno ";
X = tipoPubblicazione
X==1
X==2
X==0
F
F
T
F
T
T
Query = strSelect + «FROM dbo.ViewPubblicazioniCongressi» +strWhere
Query = strSelect + «FROM dbo.ViewPubblicazioniRiviste» +strWhere
Query = strSelect + «FROM dbo.ViewPubblicazioniCongressi» +strWhere
+ «UNION» + strSelect + «FROM dbo.ViewPubblicazioniRiviste» +strWhere
Figura 15
31
}
}
if (checkBoxTitolo.IsChecked == true)
{
if (Supporto == "SELECT ") { Supporto = Supporto + " Titolo "; }
else
{
Supporto = Supporto + ", Titolo ";
}
}
if (checkBoxAutori.IsChecked == true)
{
if (Supporto == "SELECT ") { Supporto = Supporto + " Autori "; }
else
{
Supporto = Supporto + ", Autori ";
}
}
if (checkBoxRiferimento.IsChecked == true)
{
if (Supporto == "SELECT "){ Supporto = Supporto+" Riferimento"; }
else
{
Supporto = Supporto + ", Riferimento ";
}
}
if (checkBoxCongresso.IsChecked == true)
{
if (Supporto == "SELECT "){ Supporto =Supporto+" Denominazione";}
else
{
Supporto = Supporto + ", Denominazione ";
}
}
return Supporto;
}
32
Di seguito si riporta il codice relativo allo statement WHERE della query:
private string CostruisciQueryWhere()
{
string Original = " WHERE ";
string Supporto = Original;
if (cmbStaff.Text != null && checkBoxStaff.IsChecked==false )
{
//nella combobox sono presenti COGNOME,NOME io vado ad utilizzare
solo
//il cognome facendo un parsing della stringa cmbbox.text
string autore =cmbStaff.Text.ToString();
string[] arr = autore.Split(',');
if (Supporto == Original) //per risolvere il problema di "WHERE ,
//NOME STAFF.." SINTASSI T-SQL
{
Supporto = Supporto + " Autori LIKE '%" + arr[0] + "%' ";
}
else
{
Supporto = Supporto + " AND " + " Autori LIKE '%"
+ arr[0] + "%' ";
}
}
if ( textBoxDal.Text!=null && textBoxDal.Text!=""){
if (Supporto == Original)
{
Supporto = Supporto + " Anno >= "+ textBoxDal.Text + " ";
}
else
{
Supporto = Supporto + " AND " + " Anno >= "
+ textBoxDal.Text + " ";
}
}
if (textBoxAl.Text != null && textBoxAl.Text != "")
{
33
if (Supporto == Original)
{
Supporto = Supporto + " Anno <= " + textBoxAl.Text + " ";
}
else
{
Supporto = Supporto + " AND " + " Anno <= "
+ textBoxAl.Text + " ";
}
}
//passaggio finale
if (Supporto == Original)
{
return "";
}
else
{
return Supporto;
}
}
Infine si riporta il codice relativo alla concatenazione delle diverse sottostringhe e
alla formazione query completa:
private string CostruisciQuery()
{
string vuota = "";
string TotalQuery = vuota;
if (cmbTipoPubb.SelectedIndex == 0)
{
TotalQuery = TotalQuery + CostruisciQueryIniziale() + " " +
CorpoStringCongressi + CostruisciQueryWhere() + " UNION " +
CostruisciQueryIniziale() + CorpoStringRiviste +
CostruisciQueryWhere();
}
else if (cmbTipoPubb.SelectedIndex == 1)
34
{
TotalQuery = TotalQuery + CostruisciQueryIniziale() +
CorpoStringCongressi + CostruisciQueryWhere();
}
else if (cmbTipoPubb.SelectedIndex == 2)
{
TotalQuery = TotalQuery + CostruisciQueryIniziale() +
CorpoStringRiviste + CostruisciQueryWhere();
}
else
{
TotalQuery = TotalQuery + CostruisciQueryIniziale() +
CorpoStringCongressi + CostruisciQueryWhere() + " UNION " +
CostruisciQueryIniziale() + CorpoStringRiviste +
CostruisciQueryWhere();
}
Console.WriteLine(TotalQuery);
if (TotalQuery != vuota)
{
return TotalQuery;
}
else return vuota;
}
Terzo passo
Di seguito si riporta il codice per la costruzione del file di testo:
public string generaCsv(int colonne, string sqlCommand)
{
string csvFile = ".//TempFile.txt";
try
{
string connectionString =
Properties.Settings.Default.MoseDBConnectionString;
using (SqlConnection connection = new SqlConnection(connectionString))
{
35
try
{
connection.Open();
}
catch (System.Data.SqlClient.SqlException ex)
{
// handle
return "";
}
using (SqlDataAdapter adapter =
new SqlDataAdapter(sqlCommand, connection))
{
using (System.Data.DataTable table =
new System.Data.DataTable("tbl"))
{
adapter.Fill(table);
StringBuilder commaDelimitedText = new StringBuilder();
foreach (DataRow row in table.Rows)
{
for (int i = 0; i < colonne; i++)
{
/*Qui era sorto un problema, il mio "Generatore di Csv" , quando trovava 2 spazi
consecutivi li considerava come una nuova
colonna. risolto usando espressione regolare */
row[i] = Regex.Replace(row[i].ToString(), @"\s+", " ");
}
switch (colonne)
{
case 1:
{
string value = string.Format("{0}",
row[0]);
commaDelimitedText.AppendLine(value);
File.WriteAllText(csvFile,commaDelimitedText.ToString());
break;
}
case 2:
{
36
string value=string.Format("{0}\t{1}",
row[0], row[1]);
commaDelimitedText.AppendLine(value);
File.WriteAllText(csvFile,commaDelimitedText.ToString());
break;
}
case 3:
{
string value =
string.Format("{0}\t{1}\t{2}", row[0], row[1],
row[2]);
commaDelimitedText.AppendLine(value);
File.WriteAllText(csvFile,commaDelimitedText.ToString());
break;
}
case 4:
{
string value =
string.Format("{0}\t{1}\t{2}\t{3}",row[0], row[1], row[2],
row[3]);
commaDelimitedText.AppendLine(value);
File.WriteAllText(csvFile,commaDelimitedText.ToString());
break;
}
case 5:
{
string value =
string.Format("{0}\t{1}\t{2}\t{3}\t{4}",
row[0], row[1], row[2], row[3], row[4]);
commaDelimitedText.AppendLine(value);
File.WriteAllText(csvFile,commaDelimitedText.ToString());
break;
}
}
}
}
}
}
37
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.Message);
}
return csvFile;
}
Analisi del codiceAnalisi del codiceAnalisi del codiceAnalisi del codice
Questo metodo sfrutta il metodo Contacolonne() che restituisce il numero di colonne
che andranno a formare la tabella in formato Excel, il risultato di questo metodo è
passato come input (int colonne).
È necessario contare le colonne perché la sintassi del comando string.Format(..)
permette di stabilire un unico tipo di formattazione.
L'input string sqlCommand è invece la query che sarà eseguita sulla base di dati.
Sono stati identificati 5 casi possibili in base al risultato del metodo Contacolonne().
Il riempimento del file di testo è effettuato attraverso un ciclo , all'interno del
quale vengono copiati nel file i dati della tabella (risultato della query) apponendo
un delimitatore /t/t/t/t, eccezion fatta per l'ultima colonna ( /n).
Questo file viene salvato con il nome TempFile.txtTempFile.txtTempFile.txtTempFile.txt nella cartella in cui è presente
l'eseguibile dell'applicazione, ed ogni qual volta verrà eseguita un'operazione di
questo tipo lo stesso file verrà riscrittoriscrittoriscrittoriscritto prevenendo problemi di capienza di
memoria o di semplice esubero di file non necessari.
Quarto passo
Una volta creato il file di testo viene aperto un foglio elettronico Excel il quale
attraverso l'impostazione che prevede il riconoscimento del delimitatore tab ( "/t" )
popola le sue celle in base a quanto contenuto nel file di testo.
38
Successivamente verranno inserite le intestazioni delle colonne attraverso il
metodo generaIntestazioniExcel().
Il metodo CSVtoExcel prende in input:
• il path del file che si vuole aprire;
• il foglio Excel nel quale aprire il file;
• le coordinate della cella da cui iniziare la popolazione delle celle;
• un array di tipi di dato per le rispettive colonne;
• un valore booleano che che imposta l'autodimensionamento (o meno)
delle colonne.
Di seguito si riporta il codice del metodo in questione:
public void CSVtoExcel(string importFileName, Excel.Worksheet destinationSheet,
Excel.Range destinationRange, int[] columnDataTypes, bool autoFitColumns)
{
destinationSheet.QueryTables.Add( "TEXT;" +
System.IO.Path.GetFullPath(importFileName),destinationRange,
Type.Missing);
destinationSheet.QueryTables[1].Name =
System.IO.Path.GetFileNameWithoutExtension(importFileName);
destinationSheet.QueryTables[1].FieldNames = true;
destinationSheet.QueryTables[1].RowNumbers = false;
destinationSheet.QueryTables[1].FillAdjacentFormulas = false;
destinationSheet.QueryTables[1].PreserveFormatting = true;
destinationSheet.QueryTables[1].RefreshOnFileOpen = false;
destinationSheet.QueryTables[1].RefreshStyle =
XlCellInsertionMode.xlInsertDeleteCells;
destinationSheet.QueryTables[1].SavePassword = false;
destinationSheet.QueryTables[1].SaveData = true;
destinationSheet.QueryTables[1].AdjustColumnWidth = true;
destinationSheet.QueryTables[1].RefreshPeriod = 0;
destinationSheet.QueryTables[1].TextFilePromptOnRefresh = false;
//l'id 65001 rappresenta l'id della piattaforma che decodifica i
contenuti in UTF-8
destinationSheet.QueryTables[1].TextFilePlatform = 65001;
destinationSheet.QueryTables[1].TextFileStartRow = 1;
39
destinationSheet.QueryTables[1].TextFileParseType =
XlTextParsingType.xlDelimited;
destinationSheet.QueryTables[1].TextFileTextQualifier =
XlTextQualifier.xlTextQualifierDoubleQuote;
destinationSheet.QueryTables[1].TextFileConsecutiveDelimiter = false;
destinationSheet.QueryTables[1].TextFileTabDelimiter = true;
destinationSheet.QueryTables[1].TextFileSemicolonDelimiter = false;
destinationSheet.QueryTables[1].TextFileCommaDelimiter = false;
destinationSheet.QueryTables[1].TextFileSpaceDelimiter = false;
destinationSheet.QueryTables[1].TextFileColumnDataTypes =
columnDataTypes;
destinationSheet.QueryTables[1].Refresh(false);
if (autoFitColumns == true) {
destinationSheet.QueryTables[1].Destination.EntireColumn.AutoFit();
}
}
Mentre il pulsante che aziona questo meccanismo agisce in questo modo: viene
aperta inizialmente una finestra che avvisa l'utente di attendere l'esecuzione del
processo, viene aperto un foglio Excel (non visibile ancora all'utente), viene
generato il file di testo sopra citato, viene eseguito il metodo CsvToExcel ,
vengono generate le intestazioni per le colonne del file Excel , dunque sparisce la
finestra di attesa e viene visualizzato il file.
private void button1_Click(object sender, RoutedEventArgs e)
{
try
{
System.Windows.Window loading = new System.Windows.Window {
Height = 100,
Width = 200, WindowStartupLocation =
WindowStartupLocation.CenterScreen,
WindowStyle = WindowStyle.None };
40
loading.Content = new TextBlock { Text = "Please Wait",
FontSize = 30,FontWeight = FontWeights.Bold,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center };
loading.Show();
Excel.Application xla = new Excel.Application();
Excel.Workbook wb =
xla.Workbooks.Add(Excel.XlSheetType.xlWorksheet);
Excel.Worksheet ws = (Excel.Worksheet)xla.ActiveSheet;
xla.Visible = false;
int cln = contacolonne();
string filepath = generaCsv(cln, CostruisciQuery());
CSVtoExcel(filepath, (Excel.Worksheet)(wb.Worksheets[1]),
(Excel.Range)(((Excel.Worksheet)wb.Worksheets[1]).get_Range("$A$2")),
new int[] { 2, 2, 2, 2, 2 }, true);
//Come ultima cosa inserisco le intestazioni delle colonne
List<string> lista = generaIntestazioniExcel();
for (int i = 0; i < cln; i++)
{
ws.Cells[1, i + 1] = lista[i];
}
xla.Visible = true;
wb.ActiveSheet.QueryTables[1].Delete();
loading.Close();
}
catch (Exception myex)
{
MessageBox.Show(myex.Message);
}
}
41
Il risultato di un possibile Export può essere:
(a) Creazione del file txt, non visibile all'utente
(b) Apertura del file da parte di Excel
4.5 Implementazioni di carattere generale4.5 Implementazioni di carattere generale4.5 Implementazioni di carattere generale4.5 Implementazioni di carattere generale
Sempre nell'ottica di migliorare ulteriormente l'interfaccia utente per renderla più
funzionali ai bisogni del committente sono implementate alcune features , di
minor rilevanza per, ma di indubbia utilità per l'utente:
• nella pagina relativa alle pubblicazioni in formato-griglia, viene aggiunta
una colonna che presenta il nome del documento pdf , se presente, o nulla
in caso contrario (Figura 16);
• per le pagine "PubblicationGrid" e "PubblicationCustom" è stato riscritto , in
modo coerente con le modifiche apportate, il codice che permette
all'utente di accedere ai dettaglidettaglidettaglidettagli della pubblicazione selezionata cliccando cliccando cliccando cliccando
due voltedue voltedue voltedue volte sulla riga della griglia;
• sono stati abilitati, nella home page, i linklinklinklink testuali che rimandano alle
pagine relative (come Upload e Export) e sono stati modificati i label relativi
alla versione ed al nome dell'applicazione.
43
CAPITOLO 5CAPITOLO 5CAPITOLO 5CAPITOLO 5
ConclusioniConclusioniConclusioniConclusioni
5.15.15.15.1 Possibili miglioramentiPossibili miglioramentiPossibili miglioramentiPossibili miglioramenti
Svolgendo questo lavoro si è pensato inoltre a possibili miglioramenti , che
potrebbero essere sviluppati in futuro.
Tra i quali quelli di maggior rilevanza sono:
• funzionalità di import: permettere all'utente di effettuare un importazione
di dati, da tabella excel, in modo tale da non dover inserire i record
manualmente (ad esempio : nome, cognome e dati anagrafici di un nuovo
membro dello staff).
Questa feature alleggerirebbe ancor di più il lavoro per l'utente che
attualmente deve inserire i nuovi dati , pur sempre via applicazione, ma
manualmente
• versione web dell'applicazione, completamente svincolata quindi dal Pc
dell'utente .
Possibile utilizzo della tecnologia ASP.NET
5.2 Conclusioni5.2 Conclusioni5.2 Conclusioni5.2 Conclusioni
Features implementate
� Upload PDF
� Cancella PDF
� Export
� Gestione Credenziali
44
L'obiettivo di implementare tutte le funzionalità richieste dal committente è stato
raggiunto.
Per quanto riguarda invece le conoscenze e le abilità acquisite, sono stati raggiunti
i seguenti obiettivi:
• raccolta dei requisiti mediante intervista al committente
• analisi della situazione esistente
• studio di .NET e di Windows Presentation Foundation
• studio di Database Relazionali
• studi sulle comunicazioni tra le diverse entità (server, applicazione, db)
L'applicazione ora non è più in fase di test (beta), ma è a tutti gli effetti in uso ,
nella sua versione 2.0versione 2.0versione 2.0versione 2.0.
Righe di codice scritte :
• C# : 700
• XAML : 300
45
Bibliografia
• http://msdn.microsoft.com/en-us/library/aa970268.aspx (Introduction to
WPF - MSDN)
• M. Miotto, "Progettazione e sviluppo di una applicazione per la gestione di
dati bibliografici in ambiente .NET " , Tesi per corso di laurea triennale in
Ingegneria Informatica (Università degli studi di Trieste)
• Dispense del corso di Basi di Dati tenuto dal Dott. Fermeglia presso
l'Università degli Studi di Trieste
• http://msdn.microsoft.com/it-it/library/ms254978(v=vs.110).aspx
• http://stackoverflow.com/questions/8947410/using-settings-settings-in-a-
windows-wpf-app-vs2010
• http://www.codeproject.com/Articles/19509/Write-Data-to-Excel-using-C
• Adam Nathan - WPF 4 Unleashed - Pearson Education (US) – 2010
• http://blogs.msdn.com/b/pietrobr/archive/2007/09/07/parliamo-di-linq-
parte-3.aspx
• http://msdn.microsoft.com/it-it/vcsharp/cc788743(en-us).aspx