martedì 9 marzo 2010
#
Lavorando (“smanettando”) coi Web Services si potrebbe incorrere nella seguente eccezione di Visual Studio:
“Impossibile caricare la sezione di configurazione endpoint per il contratto 'mio Web Service Soap'. Trovata più di una configurazione per il contratto. Indicare la sezione di configurazione endpoint preferita per nome.”
L’errore non sta nella configurazione del server, bensì nella configurazione dell’applicazione che deve collegarsi al Web Service.
Succede che nel file di configuazione dell’applicazione talvolta vengano generati in automatico due riferimenti uguali allo stesso Web Service.
Per correggere l’errore basta aprire il file di configurazione dell’applicazione selezionandolo da Esplora Soluzioni di Visual Studio:
Scorrerlo ed identificare il tag <endpoint> in cui viene configurata la chiamata al Web Service.
A questo punto è possibile notare la doppia dichiarazione:
Basterà quindi eliminare la seconda (terza, o quarta… :-P) dichiarazione per far funzionare correttamente la nostra applicazione.
HTH
PS: Perchè in italiano c’è pochissima documentazione a riguardo??…
Sfruttando gli ultimi 2 post: Macro per utilizzare lo scanner da Word 2007 e Esportare un documento Office 2007 in PDF, ho leggermente automatizzato il procedimento aziendale di “scansione, inserimento immagni, esportazione in PDF”.
Tutta la procedura viene svolta da una semplice macro:
Sub Crea_PDF()
'
' Crea_PDF Macro
' Riduce i margini del foglio.
With Selection.PageSetup
.LineNumbering.Active = False
.Orientation = wdOrientPortrait
.TopMargin = CentimetersToPoints(1.27)
.BottomMargin = CentimetersToPoints(1.27)
.LeftMargin = CentimetersToPoints(1.27)
.RightMargin = CentimetersToPoints(1.27)
.Gutter = CentimetersToPoints(0)
.HeaderDistance = CentimetersToPoints(1.25)
.FooterDistance = CentimetersToPoints(1.25)
.PageWidth = CentimetersToPoints(21)
.PageHeight = CentimetersToPoints(29.7)
.FirstPageTray = wdPrinterDefaultBin
.OtherPagesTray = wdPrinterDefaultBin
.SectionStart = wdSectionNewPage
.OddAndEvenPagesHeaderFooter = False
.DifferentFirstPageHeaderFooter = False
.VerticalAlignment = wdAlignVerticalTop
.SuppressEndnotes = False
.MirrorMargins = False
.TwoPagesOnOne = False
.BookFoldPrinting = False
.BookFoldRevPrinting = False
.BookFoldPrintingSheets = 1
.GutterPos = wdGutterPosLeft
End With
' Scannerizza le immagini.
On Error Resume Next
WordBasic.InsertImagerScan
' Esporta in PDF.
ActiveDocument.ExportAsFixedFormat OutputFileName:= _
"C:\Documents and Settings\Andrea\Desktop\Doc1.pdf", ExportFormat:= _
wdExportFormatPDF, OpenAfterExport:=True, OptimizeFor:= _
wdExportOptimizeForPrint, Range:=wdExportAllDocument, From:=1, To:=1, _
Item:=wdExportDocumentContent, IncludeDocProps:=True, KeepIRM:=True, _
CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
BitmapMissingFonts:=True, UseISO19005_1:=False
' Messaggio di notifica.
MsgBox "Creazione del file PDF completata.", vbInformation, "Crea PDF"
' Chiude Word chiedendo conferma.
Application.Quit
End Sub
NB: In questo caso il file PDF viene generato nel “C:\Documents and Settings\Andrea\Desktop”, sempre col solito nome (Doc1.pdf). Questa è una soluzione rapida per chi, come me, crea dei semplici file temporanei. E’ invece possibile personalizzare i nomi dei file inserendo ad esempio una inputbox prima dell’esportazione.
Per esportare un documento Office 2007 (Word, Excel) in PDF, basta installare questo componente aggiuntivo scaricabile direttamente dal sito Microsoft:
http://www.microsoft.com/downloads/details.aspx?familyid=4d951911-3e7e-4ae6-b059-a2e79ed87041&displaylang=it
Una volta installato il componente basterà poi cliccare su: Pulsante Office=>Salva con nome=>PDX o XPS.
That's all folks!
Per scrivere una macro che utilizza lo scanner da Word 2007 basta una sola riga di codice:
WordBasic.InsertImagerScan
In questo modo, appena effettuata la scansione, l’immagine verrà inserita automaticamente all’interno del documento.
lunedì 14 dicembre 2009
#
Sfortunatamente la CheckedListBox non possiede un evento che si scatena dopo che è stato “flaggato” un item, percui è difficile poter interagire direttamente con l’elemento selezionato.
E’ possibile aggirare il problema creando degli items personalizzati visto che all’interno della CheckedListBox è possibile aggiungere qualunque oggetto indicizzato (che espone l’interfaccia IDictionary).
Creiamo una classe personalizzata che rappresenti un item e che abbia una proprietà di tipo CheckState che memorizzi il flag impostato dalla CheckedListBox che lo contiene.
' Oggetto personalizzato myChekedItem.
Public Class myChekedItem
Private _Nome As String
Property Nome() As String
Get
Return _Nome
End Get
Set(ByVal value As String)
_Nome = value
End Set
End Property
Private _Stato As CheckState
Property Stato() As CheckState
Get
Return _Stato
End Get
Set(ByVal value As CheckState)
_Stato = value
End Set
End Property
Public Sub New(ByVal nome As String, ByVal stato As CheckState)
Me.Nome = nome
Me.Stato = stato
End Sub
Public Overrides Function ToString() As String
Return Me.Nome
End Function
End Class
Eseguendo l’overrides della funzione .ToString della classe base, permetteremo alla CheckedListBox di visualizzare automaticamente la proprietà Nome nell’item personalizzato, senza dover impostare la proprietà (nascosta) DisplayMember.
Popoliamo la CheckedListBox con gli items personalizzati.
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' Aggiunge gli oggetti myChekedItem alla CheckedListBox.
Me.CheckedListBox1.Items.Add(New myChekedItem("prova Item personalizzato 1", CheckState.Indeterminate))
Me.CheckedListBox1.Items.Add(New myChekedItem("prova Item personalizzato 2", CheckState.Indeterminate))
End Sub
Intercettiamo l’evento .ItemCheck della CheckedListBox e risaliamo all’item personalizzato selezionato:
Private Sub CheckedListBox2_ItemCheck(ByVal sender As Object, ByVal e As System.Windows.Forms.ItemCheckEventArgs) Handles CheckedListBox1.ItemCheck
' Imposta il checkstate all'oggetto myChekedItem selezionato.
Dim chkItem As myChekedItem = DirectCast(Me.CheckedListBox1.Items(e.Index), myChekedItem)
chkItem.Stato = e.NewValue
' Aggiunge l'item selezionato.
If e.NewValue = CheckState.Checked Then
Me.ListBox1.Items.Add(chkItem)
ElseIf e.NewValue = CheckState.Unchecked Then
Me.ListBox1.Items.Remove(chkItem)
End If
End Sub
All’interno dell’evento .ItemCheck gestiremo i nostri items come oggetti indipendenti sfruttandone tutte le loro funzionalità. In questo caso li abbiamo aggiunti o rimossi ad una ListBox sfruttandone i metodi .Items.Add e .Items.Remove a seconda del valore della loro prorietà Stato.
venerdì 23 ottobre 2009
#
Generalmente per salvare un file di testo è molto comodo utilizzare uno StreamWriter:
Dim sw As New IO.StreamWriter("C:\SW prova.txt")
sw.Write("Mio testo")
sw.Flush()
sw.Close()
Se il testo da salvare però è di grandi dimensioni, lo StreamWriter sarà lento ad eseguire la scrittura su disco. Per evitare rallentamenti è possibile salvare il file come flusso di byte utilizzando la classe IO.FileStream:
Dim fs As New IO.FileStream("C:\FS prova.txt", IO.FileMode.OpenOrCreate)
Dim enc As New System.Text.UTF8Encoding
Dim bytes() As Byte = enc.GetBytes("Mio testo molto lungo")
fs.Write(bytes, 0, bytes.Length)
fs.Flush()
fs.Close()
lunedì 12 ottobre 2009
#
Niente di eccezionale ma abbastanza utile:
Public Class myDaysOfYear
Public Shared Function GetFirstDayOfMonth(ByVal data As Date) As Date
Return DateTime.Parse(String.Format("01/{0}/{1}", data.Month, data.Year))
End Function
Public Shared Function GetNameOfFirstDayOfMonth(ByVal data As Date) As String
Return Globalization.CultureInfo.CurrentCulture.DateTimeFormat.GetDayName(GetFirstDayOfMonth(data).DayOfWeek)
End Function
Public Shared Function GetLastDayOfMonth(ByVal data As Date) As Date
Return DateTime.Parse(String.Format("{0}/{1}/{2}", Date.DaysInMonth(data.Year, data.Month), data.Month, data.Year))
End Function
Public Shared Function GetNameOfLastDayOfMonth(ByVal data As Date) As String
Return Globalization.CultureInfo.CurrentCulture.DateTimeFormat.GetDayName(GetLastDayOfMonth(data).DayOfWeek)
End Function
End Class
Le funzioni della classe si richiamano così:
Dim NomeDelPrimoGiornoDelMese As String = myDaysOfYear.GetNameOfFirstDayOfMonth(DateTime.Today)
Dim DataPrimoGiornoDelMese As Date = myDaysOfYear.GetFirstDayOfMonth(DateTime.Today)
Dim NomeUltimoGiornoDelMese As String = myDaysOfYear.GetNameOfLastDayOfMonth(DateTime.Today)
Dim DataUltimoGiornoDelMese As Date = myDaysOfYear.GetLastDayOfMonth(DateTime.Today)
mercoledì 23 settembre 2009
#
Non ho mai parlato nel blog del mio mito… che con la sua musica mi ha accompagnato per più di vent’anni.
Oggi però è il suo 60eimo compleanno ed uno strappo alla regola lo devo proprio fare:
TANTI AUGURI BOSS!!!
lunedì 17 agosto 2009
#
Può capitare di ritrovarsi con una DataTable contenente delle DataColumns nominate in modo non convenzionale, ossia con caratteri non validi o con spazi.
In questo caso le proprietà .RowFilter e .Sort dell’oggetto DataView non funzionano correttamente.
Per aggirare questo problema basta rinominare le colonne interessate prima di impostare il filtro di ricerca o di ordinamento:
' Rinomina la colonna "Nome colonna con spazi" in "Nome_colonna_con_spazi".
dt.Columns(13).ColumnName = dt.Columns(13).ColumnName.Replace(" ", "_")
' Imposta il filtro sulla colonna rinominata.
dt.DefaultView.RowFilter = String.Format("{0} = '{1}'", dt.Columns(13).ColumnName, "Italia")
Volendo è possibile ripristinare il nome originale eseguendo l’operazione inversa dopo aver impostato i filtri.
dt.Columns(13).ColumnName = dt.Columns(13).ColumnName.Replace("_", " ")
martedì 4 agosto 2009
#
Non ho mai avuto l'esigenza di censurare l'input dell'utente ma leggendo un post su DNW ho capito che è una cosa da fare necessariamente, soprattutto se si gestiscono forum o altre discussioni pubbliche.
Proviamo quindi a realizzare una funzione che effettui il controllo delle parole non gradite.
La censura potrebbe avvenire semplicemente sovrascrivendo le parole indesiderate con dei caratteri non leggibili (es. l'asterisco).
Il sistema presentato avrà una contronidicazione: censurarà parti di parole che in realtà non devono essere censurate. Prendiamo ad esempio una frase come questa:
Cazzottare un figaro siculo (prendere a pugni un barbiere siciliano)
la versione censurata risulterà in questo modo:
c****ttare un f***ro sic***
Per evitare censure di questo tipo bisognerà lavorare molto sulla logica del programma tenendo in considerazione svariati scenari (parole singole, parole incorporate, parole con spazi, ecc…)
La funzione che segue non tiene conto della sopracitata logica ma effettua una censura indistinta delle parole indesiderate.
Il codice della funzione è molto semplice.
Creiamo un elenco in un file di testo (o in un database) delle parole da censurare (parolaccie, offese, riferimenti religiosi, ecc...)
parolaA
parolaB
parolaC
…
Cicliamo ognuna di queste parole e controlliamo se è presente nel testo da controllare. Se la parola è presente nel testo, la sovrascriveremo con una serie di caratteri non leggibili utilizzando una regular expression.
Chi non ha dimestichezza con le regex può sfruttare direttamente il metodo .Replace dell'oggetto stringa (String, Textbox.Text, ecc...) ma questa soluzione non è performante come l'utilizzo delle regular expression. Un trucco per velocizzare comunque questo procedimento potrebbe essere quello di appoggiarsi ad uno stringbuilder ma a conti fatti il codice da scrivere risulterebbe più articolato di quello delle regex.
' VB.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.TextBox2.Text = Me.CensorRegex(Me.TextBox1.Text)
End Sub
Private Function CensorRegex(ByVal text As String) As String
Dim path As String = "c:\Parole sgradite.txt"
If My.Computer.FileSystem.FileExists(path) Then
Using sr As New IO.StreamReader(path)
Do While sr.Peek() >= 0
' Crea il pattern per la regex.
Dim pattern As String = String.Format("{0}", sr.ReadLine)
' Crea la stringa di censura.
Dim mask As String = String.Format("{0}{1}", pattern.Substring(0, 1), New String("*"c, pattern.Length - 1))
' Esegue la censura.
text = Regex.Replace(text, pattern, mask, RegexOptions.IgnoreCase)
Loop
sr.Close()
End Using
' Ritorna il valore.
Return text
Else
MessageBox.Show(String.Format("File {0} non è stato trovato.", path), "Errore", MessageBoxButtons.OK, MessageBoxIcon.Error)
Return String.Empty
End If
End Function
Un altro problema di questo codice è che non riesce a mantenere maiuscuola la prima lettera della parola da censurare. Ovviamente il problema è aggirabile ma richiederebbe un overhead che annullerebbe ogni beneficio dell'utilizzo delle regex in termini di velocità.