Ciao Giuseppe.
Dato che non basta aggiungere un pulsante affinche', alla sua pressione,
il dato in una casella di testo vada scritto in una cella di un foglio
di lavoro, se ne deduce che tutto questo avvenga perche' tu hai scritto
del codice che viene eseguito alla pressione del pulsante. Dato che
probabilmente l'errore e' in tale codice, che ne dici di mostrarcelo?
--
(Facci sapere se e eventualmente come hai risolto. Grazie.)
Ciao :o) Microsoft MVP (Excel)
Maurizio <http://mvp.support.microsoft.com/profile/Maurizio.Borrelli>
--------
?SPQR(C)
X RIO - Risorse in italiano per gli utenti di office
-------- <http://www.riolab.org>
In attesa del tuo codice, prova:
Private Sub CommandButton1_Click()
With Worksheets("Foglio1")
If IsDate(TextBox1.Text) Then
.Range("A1").Value = CDate(TextBox1.Text)
Else
MsgBox "Data non valida"
End If
End With
End Sub
--
---------------------------
Mauro Gamberini
http://www.riolab.org/
Ciao Mauro.
... e con questo tuo post deduco che il ng e' definitivamente
norma(n)lizzato! :-)))
Purtroppo oltre che di IsNumeric bisogna diffidare anche di IsDate.
Mettiamo che lo sfortunato utente di quel codice voglia immettere la
data:
12/3/2007
e che invece gli scappi di digitare, per esempio:
12/13/2007
(succede! Oh, se succede!)
Il risultato sara' che si trovera' registrata la data:
13/12/2007
e quando (e se!!!) lo scoprira' si chiedera' chi e' stato quel @#§$& che
ha scritto quella bojata, senza nemmeno potersi rendere conto di essere
stato lui stesso ("Io non ho MAI digitato 13/12/2007!". Ed e' VERO!),
anche se col concorso di colpa del "programmatore" ("Il MIO codice
impedisce l'immissione di date non valide!". Ed e' FALSO!).
;-)
--
Può anche digitare 12/4/2007(sempre vicini sono,
secondo la tua teoria(condivisa
e non applicata...;-)) dei tasti vicini(IsNumeric e *e*)).
La domanda era diversa
(ho già le mani in alto come ai vecchi tempi)... 8-)
'------------
... e con questo tuo post deduco che il ng e' definitivamente
norma(n)lizzato! :-)))
[...]
'------------
ROTFL!
Visto che mi hai invocato ...
E, se per caso, volendo inserire 11/06/2007, io
digitassi 12 /06/2007 (oppure una qualsiasi altra
data valida), come potresti aiutare un povero utente
come me? Al fine, non credo che ci sia modo di
evitare *certi* errori dal parte del utente ...
Errare humanum est
Detto questo, c'e' un controllo calendario, e, per le
date, credo sia preferibile all'uso di una TextBox.
---
Regards,
Norman
Microsoft Excel MVP
50 centesimi vanno bene?
(non so al cambio quanto facciano, sorry)
> Detto questo, c'e' un controllo calendario, e, per le
> date, credo sia preferibile all'uso di una TextBox.
>
Potresti sempre sbagliare nel click sulla data! 8-)
> Potresti sempre sbagliare nel click sulla data! 8-)
Io, no!! :-)
Ma un altro ...certo!
'-------------
[...]
Al fine, non credo che ci sia modo di
evitare *certi* errori dal parte del utente ...
Errare humanum est
[...]
'-------------
Forse piu' affidible sarebbe un sistema di Voice
Recognition (il cosiddetto riconoscimento della
voce, ma... se avesse una balbuzie forte...!
Quindi *tu* non sei umano, ma inglese. A beh, ho capito...8-)
===> (via Voice recognition) ===>
Forse piu' affidable
"Mauro Gamberini" <maurogsc...@RIMUOVEREaliceposta.it> ha scritto nel
messaggio news:OuaWkTDr...@TK2MSFTNGP04.phx.gbl...
Noi stiamo sempre aspettando il tuo codice.
E, hai provato quanto postato?
Giuseppe io non lo vedo(il tuo codice).
Hai provato quanto ti avevo postato?
Mauro Gamberini
http://www.riolab.org/
> E, se per caso, volendo inserire 11/06/2007, io
> digitassi 12 /06/2007 (oppure una qualsiasi altra
> data valida), come potresti aiutare un povero utente
> come me? Al fine, non credo che ci sia modo di
> evitare *certi* errori dal parte del utente ...
> Errare humanum est
> Detto questo, c'e' un controllo calendario, e, per le
> date, credo sia preferibile all'uso di una TextBox.
Ciao Norman. Ciao Mauro.
Possibile che non sia chiara la differenza fra:
1) l'immissione di una data non valida che venga, senza avvertire
l'utente, trasformata in una (diversa!) data valida e quindi cosi'
registrata
e
2) l'immissione di una data non valida che venga rifiutata?
No! Non ci posso credere.
'--------------
Possibile che non sia chiara la differenza fra:
1) l'immissione di una data non valida che venga, senza avvertire
l'utente, trasformata in una (diversa!) data valida e quindi cosi'
registrata
e
2) l'immissione di una data non valida che venga rifiutata?
No! Non ci posso credere.
'--------------
In verita', non credo che sia un foglio di carta
sottilissmo tra di noi!
Credo che lo sviluppatore debba controlare ogni
errore possible; poi non credo che ci sia altro che
la preghiera!
---
Regards,
Norman
"Norman Jones" <norma...@whereforartthou.com> ha scritto nel messaggio
news:OmF1tSHr...@TK2MSFTNGP05.phx.gbl...
[...]
> Al fine, non credo che ci sia modo di
> evitare *certi* errori dal parte del utente ...
> Errare humanum est
[...]
Ciao Norman.
La questione infatti non e' di evitare gli errori dell'utente ma di
intercettarli, catturarli, filtrarli, intrappolarli, "trapparli"
(italiano informatichese derivato dall'inglese "to trap").
Mi ripeto, ma pare sia necessario. Un utente che ha intenzione di
immettere la data:
12/3/2007
e che per errore digita:
12/23/2007
si aspetta che il programma gli segnali:
Data non valida
Di certo non puo' immaginare, e nemmeno lo desidera, che il programma (a
sua insaputa!) registri invece:
23/12/2007
Tutto qui.
'----------------
La questione infatti non e' di evitare gli errori dell'utente ma di
intercettarli, catturarli, filtrarli, intrappolarli, "trapparli"
(italiano informatichese derivato dall'inglese "to trap").
Mi ripeto, ma pare sia necessario. Un utente che ha intenzione di
immettere la data:
12/3/2007
e che per errore digita:
12/23/2007
si aspetta che il programma gli segnali:
Data non valida
Di certo non puo' immaginare, e nemmeno lo desidera, che il programma (a
sua insaputa!) registri invece:
23/12/2007
Tutto qui.
'----------------
Sarebbe facile 'trappare' le date invalide se,
ad esempio, la tua data:
12/23/2007
non fosse una data valida dal punto di vista
(americano) di VBA. Se non ci fossero i due tipi
di date, si potrebbe controllare che il mese sia
<= 12.
Inoltre, sempre utlizanndo il tuo esempio di una
data voluta di 12/3/2007, io non vedo alcuna
differenxa di principio tra l'inserimento sbagliato
di 12/23/2007 e l'inserimento sbagliato di
12/4/2007. Che l'errore sia di un giorno, un mese
o un anno, e' sempre un errore!
Per evitatare le date 'invalide', io utilizzeri un
controllo calendario, oppure tre ComboBox:
cbGiorno, cbMese e cbAnno.
Comunque, sarebbe sempre possibile inserire
una data sbagliata in quanto sia possibilimisso
che la data sbagliata sia una data valida - sia in
Italia che America: ad esempio, inserendo
1/12/2007 anziche 1/2/2007.
Ovviamente, lo sviluppatore potrebbe filtrare le
date per intrappolare le date irragionevoli - ma
questo richiede una conoscenza approfondita dei
dati del cliente!
====>
di date, si potrebbe controllare che il mese fosse
<= 12.
> ho inserito in una userform una textbox nella quale vado a scrivere una
Ciao Giuseppe.
Un modo:
' modUtil - Modulo
Option Explicit
Option Private Module
Public Function VerificaData(ByVal Text _
As String) As Variant
On Error GoTo ErrorHandler
Const f = "0000""-""00""-""00"
Dim r As Variant
Dim s As String
Dim d() As String
s = Trim$(Text)
If Len(s) Then
s = Replace(s, " ", "-")
s = Replace(s, "/", "-")
d = Split(s, "-")
Select Case UBound(d)
Case 0
Select Case Len(s)
Case 4
r = Format$(CStr(Year(Date)) _
& Right$(s, 2) _
& Left$(s, 2) _
, f)
Case 6
r = Format$("20" & Right$(s, 2) _
& Mid$(s, 3, 2) _
& Left$(s, 2) _
, f)
Case 8
r = Format$(Right$(s, 4) _
& Mid$(s, 3, 2) _
& Left$(s, 2) _
, f)
Case Else
r = CVErr(13)
End Select
Case 1
r = Format$(CStr(Year(Date)) _
& Right$("0" & d(1), 2) _
& Right$("0" & d(0), 2) _
, f)
Case 2
If Len(d(0)) = 4 Then
r = Join(d, "-")
Else
r = Format$(Right$("20" & d(2), 4) _
& Right$("0" & d(1), 2) _
& Right$("0" & d(0), 2) _
, f)
End If
Case Else
r = CVErr(13)
End Select
If Not IsError(r) Then
r = CDate(r)
End If
End If
ExitProcedure:
VerificaData = r
Exit Function
ErrorHandler:
r = CVErr(13)
Resume ExitProcedure
End Function
Da usare per esempio cosi':
' modMacros - Modulo
Option Explicit
Public Sub Test()
UserForm1.Show
End Sub
' UserForm1 - UserForm
Option Explicit
Private Sub CommandButton1_Click()
Dim d As Variant
d = VerificaData(Me.TextBox1.Text)
If IsEmpty(d) Then
' DO NOTHING
ElseIf IsError(d) Then
MsgBox "Data non valida"
Else
With Worksheets("Foglio1").Range("A1")
.Value = d
End With
End If
End Sub
ATTENZIONE! Procedura (ri)scritta di fresco. Qualcuno dei frequentatori
del ng puo' per favore sottoporla a durissimi e spietati test e
appenderne l'esito in questo 3D? Grazie!
[...]
> Sarebbe facile 'trappare' le date invalide se,
> ad esempio, la tua data:
> 12/23/2007
> non fosse una data valida dal punto di vista
> (americano) di VBA.
[...]
Ciao Norman.
Il fatto e' che il punto di vista di un utente italiano e' italiano.
Come e' inglese quello di un utente inglese, I suppose.
Vaglielo a spiegare tu, al "fortunato", che deve essere felice, per
esempio, di incassare il 23 dicembre 2007 quello che avrebbe dovuto
essergli pagato il 12 marzo 2007 solo perche' un errore di immissione,
da un punto di vista americano, non e' un errore. :-)))
'--------------
Il fatto e' che il punto di vista di un utente italiano e' italiano.
Come e' inglese quello di un utente inglese, I suppose.
Vaglielo a spiegare tu, al "fortunato", che deve essere felice, per
esempio, di incassare il 23 dicembre 2007 quello che avrebbe dovuto
essergli pagato il 12 marzo 2007 solo perche' un errore di immissione,
da un punto di vista americano, non e' un errore. :-)))
'--------------
Dissento!
Nostra punto di vista non dovrebbe essere
sprovinciale; a mio avviso, *ogni* application
dovrebbe essere utilizzabile sia da un italiano
che un americano!
Per quanto riguarda l'accento americano di
VBA, credo che ci sia niente da fare; ma non
si puo fintare che il mondo sia encapsulato in
italia: Quando si sviluppa un progetto, si dovrebbe
sempre ricordarsi che l''utente potrebbe provenire
da qualsiasi paese; i problemi risultanti devono
essere confrontati - insomma:
'life is hard and then you die'
'---------------
[...]
ATTENZIONE! Procedura (ri)scritta di fresco. Qualcuno dei frequentatori
del ng puo' per favore sottoporla a durissimi e spietati test e
appenderne l'esito in questo 3D? Grazie!
'---------------
Senza alcun test, e visto che tu avevi parlato
di un errore di immissione, credo che si avrebbe
un crash se l'utente, volendo inserie la data
1/1/1999, scrivessi 1/1/1899.
====>
Il nostro punto di vista non dovrebbe essere
Ma ROTFL!
[...]
> Senza alcun test, e visto che tu avevi parlato
> di un errore di immissione, credo che si avrebbe
> un crash se l'utente, volendo inserie la data
> 1/1/1999, scrivessi 1/1/1899.
Ciao Norman.
Grazie!
Aggiunta anche la gestione 1900/1904.
Causa il noto problema delle date fino al 29 febbraio 1900 (sic!) ho
preferito limitare l'intervallo di validita' a partire dal 1° marzo
1900.
Si potrebbe anche gestire l'interpretazione dell'anno a due cifre
secondo lo stile di Excel ma io ho preferito non farlo.
' modUtil - Modulo
Option Explicit
Option Private Module
Public Function VerificaData(ByVal Text _
As String _
, Optional ByVal Date1904 _
As Boolean) As Variant
If Date1904 Then
If r < #1/2/1904# Then
r = CVErr(13)
End If
Else
If r < #3/1/1900# Then
r = CVErr(13)
End If
End If
End If
End If
ExitProcedure:
VerificaData = r
Exit Function
ErrorHandler:
r = CVErr(13)
Resume ExitProcedure
End Function
' UserForm1 - UserForm
Option Explicit
Private Sub CommandButton1_Click()
Dim d As Variant
d = VerificaData(Me.TextBox1.Text _
, ThisWorkbook.Date1904)
If IsEmpty(d) Then
' DO NOTHING
ElseIf IsError(d) Then
MsgBox "Data non valida"
Else
With Worksheets("Foglio1").Range("A1")
.Value = d
End With
End If
End Sub
--
Ciao Norman.
Mah!... Secondo me stai parlando di un'altro argomento che non c'entra
con IsDate e io, evidentemente, non sono capace di spiegarmi. Vediamo se
le parole di un MVP che suppongo tu stimi ti convincono:
VB and Dates have a few strange quirks. I generally don't trust the
IsDate function at all. IsDate is treating "31/04/01" as a yy/mm/dd
format, and it converts to 1-April-1931. "IsDate" should really be
renamed to "IsItPossibleToRearrangeThisStringToGetSomeSortOfDate".
It is a rather crappy function. Roll your own.
Cordially,
Chip Pearson
http://groups.google.com/group/microsoft.public.vb.general.discussion/browse_thread/thread/2d141c201d9465cf/7af93c1366394f86?lnk=st&q=isdate+pearson&rnum=8&hl=it#7af93c1366394f86
[...]
> un'altro argomento
[...]
Ops! Giuro, la frase era nata con "un'altra questione"!... :-(
'---------------
Mah!... Secondo me stai parlando di un'altro argomento che non c'entra
con IsDate e io, evidentemente, non sono capace di spiegarmi. Vediamo se
le parole di un MVP che suppongo tu stimi ti convincono:
VB and Dates have a few strange quirks. I generally don't trust the
IsDate function at all. IsDate is treating "31/04/01" as a yy/mm/dd
format, and it converts to 1-April-1931. "IsDate" should really be
renamed to "IsItPossibleToRearrangeThisStringToGetSomeSortOfDate".
It is a rather crappy function. Roll your own.
Cordially,
Chip Pearson
http://groups.google.com/group/microsoft.public.vb.general.discussion/browse_thread/thread/2d141c201d9465cf/7af93c1366394f86?lnk=st&q=isdate+pearson&rnum=8&hl=it#7af93c1366394f86
'---------------
Grazie per il link.
Il mio intervento in questo thread era in risposto
all'invocazione:
'-------------
... e con questo tuo post deduco che il ng e' definitivamente
norma(n)lizzato! :-)))
'-------------
e anche in risposta al tuo commento:
'-------------
Mettiamo che lo sfortunato utente di quel codice voglia immettere la
data:
12/3/2007
e che invece gli scappi di digitare, per esempio:
12/13/2007
(succede! Oh, se succede!)
Il risultato sara' che si trovera' registrata la data:
13/12/2007
e quando (e se!!!) lo scoprira' si chiedera' chi e' stato quel @#§$& che
ha scritto quella bojata, senza nemmeno potersi rendere conto di essere
stato lui stesso ("Io non ho MAI digitato 13/12/2007!". Ed e' VERO!),
anche se col concorso di colpa del "programmatore" ("Il MIO codice
impedisce l'immissione di date non valide!". Ed e' FALSO!).
'-------------
Certo che stimo Chip Pearson MVP, ma
stimo moltissimo anche il MVP che mi scrive
qua!
E' ben noto che ci sono dei problemi con le
funzione per trattare le date - vedi, ad esempio,
anche Cdate e DateValue. Queste funzioni sono
utilissime - ma si deve sempre capire e ricordarsi
delle sue limitazioni. Come gia' indicato in
precedenza in questo thread, i problemi con le
date sono dovuto, piu' che altro, ai due sitemi
utilizzati per ricordare le date.
Tuttavia, il problema diventa piu' ampio se si tratta
anche del tuo 'sfortunato utente' che sbaglia
l'inserimento di una data e, di conseguenza, inserisce
una data valida ma non voluta.
Pertanto, nella mia prima risposta avevo detto
'-------------
E, se per caso, volendo inserire 11/06/2007, io
digitassi 12 /06/2007 (oppure una qualsiasi altra
data valida), come potresti aiutare un povero utente
come me? Al fine, non credo che ci sia modo di
evitare *certi* errori dal parte del utente ...
Errare humanum est
Detto questo, c'e' un controllo calendario, e, per le
date, credo sia preferibile all'uso di una TextBox.
'-------------
Ovviamente, anche utilizzando un controllo
Calendario, l'utente potrebbe inserire una data
sbagliata - vedi la risposta di Mauro:
'-------------
Potresti sempre sbagliare nel click sulla data! 8-)
'-------------
Comunque, utilizzando il contrlllo calendario credo
che si eviti la possibilità che l'utente digiti una data
non valida!
Tornando alla tua funzione per verificare che una
data sia valida, avrei due preoccupazioni principali;
la prima di principio e la seconda riguarda la sua
practica,
In principio non vorrei utilizzare la funzione perche
non puo' essere utilizzata da un americano; se, ad
esempio, un americano digitasse la data odierna, la
tua funzione restituirebbe "non valida". Comunque,
a questo proposito, sarebbe possibile scrivere la tua
funzione in modo che cambiasse accento secondo
l'utente - forse sfruttando l'argomento xlCountrySetting
della proprieta' International.
Per illustrare la mia seconda preoccupazione, vedi i
seguenti risultati restituiti dalla funzione:
1/1/0000
==> 1-gen-2000
1/1/0000000000
==> 1-gen-2000
010101/001001/0010001010000
==> 1-gen-2000
324/2/10000
==> 1-gen-2000
010102/02010301/09010001010000
==> 24-feb-2000
91+%081802/02067145.20301/09801000101000098
==> 2-gen-2000
91+%081802/02067145.20301/098010001+55501000012
==> 12-gen-2002
ABC8%76^A2Bc502/02$$$$45.20301/098010001+9
==> 12-gen-2002
$$$87654321&^%PQR5007
===> 2-gen-5007
9+&?1+%081802/02067145.20301/098010011+98765432155050029
===> 29-gen-2002
76^A2Bc908/02$$$45.20307/098040003+9
$$$87IMaurizioBorelliA^%PQR5007
===> 8-lug-5007
Ovviamente, a meno che l'utente fosse ubriaco,
sarebbe improbabile che digitasse tali date, ma qua
ho provato, ubbidientemente, a seguire le tue
istruzioni :-)
'----------------
ATTENZIONE! Procedura (ri)scritta di fresco. Qualcuno dei frequentatori
del ng puo' per favore sottoporla a durissimi e spietati test e
appenderne l'esito in questo 3D? Grazie!
'----------------
Ho avuto un problema con la copia / incolla!
I risultati ottenuti con i miei test della tua
funzione erano:
1/1/0000
==> 1-gen-2000
1/1/0000000000
==> 1-gen-2000
010101/001001/0010001010000
==> 1-gen-2000
324/2/10000
==> 24-feb-2000
010102/02010301/09010001010000
==> 2-gen-2000
91+%081802/02067145.20301/09801000101000098
==> 2-gen-1998
91+%081802/02067145.20301/098010001+55501000012
==> 12-gen-2002
ABC8%76^A2Bc502/02$$$$45.20301/098010001+9
$$$87654321&^%PQR5007
===> 2-gen-5007
9+&?1+%081802/02067145.20301/098010011+98765432155050029
===> 29-gen-2002
76^A2Bc908/02$$$45.20307/098040003+9
$$$87IMaurizioBorelliA^%PQR5007
===> 8-lug-5007
---
(1)
[...]
> Ovviamente, anche utilizzando un controllo
> Calendario, l'utente potrebbe inserire una data
[...]
(2)
> Tornando alla tua funzione per verificare che una
> data sia valida, avrei due preoccupazioni principali;
> la prima di principio e la seconda riguarda la sua
> practica,
> In principio non vorrei utilizzare la funzione perche
> non puo' essere utilizzata da un americano; se, ad
> esempio, un americano digitasse la data odierna, la
> tua funzione restituirebbe "non valida". Comunque,
> a questo proposito, sarebbe possibile scrivere la tua
> funzione in modo che cambiasse accento secondo
> l'utente - forse sfruttando l'argomento xlCountrySetting
> della proprieta' International.
(3)
> Per illustrare la mia seconda preoccupazione, vedi i
> seguenti risultati restituiti dalla funzione:
[...]
Ciao Norman.
(1)
Esatto! Infatti la nostra estenuante :-) discussione deriva dal fatto
che non riusciamo a capire l'uno le ragioni dell'altro. Ovvero che io
non riesco a farti capire la differenza che c'e', secondo me, fra le
intenzioni dell'utente (cosa per me NON rilevante) e le intenzioni del
programmatore.
Non importa cosa intende scrivere l'utente ma solo cio' che
effettivamente scrive; e cio' che l'utente scrive *deve* essere validato
dal programmatore. Questa infatti e' l'intenzione del programmatore
quando usa IsDate: validare l'input dell'utente. Cio' che il
programmatore non si aspetta e' che vengano considerate valide date che
valide non sono. Da questo deriva il mio invito di partenza a
*diffidare* di IsDate, cosa che in tanti, da anni, ripetiamo; per
esempio la citazione di Pearson e' del 2001.
Concludendo, se un utente scrive una data valida avendo intenzione di
scriverne un'altra, non ci possiamo fare nulla, e questo rientra nelle
responsabilita' dell'utente. Al massimo possiamo agevolarlo con
strumenti piu' amichevoli come appunto il Controllo calendario o simili.
Se invece scrive una data non valida il nostro dovere e' di segnalarlo e
di impedire tale immissione. Cosa che usando IsDate non e' possibile
fare.
(2)
Ovviamente sono d'accordo con te. Quella funzione che sto scrivendo anzi
che stiamo scrivendo, visto che il ng e' pubblico, considera solo una
parte del problema. Vedremo in seguito se internazionalizzarla. Potrebbe
anche succedere che qualcuno individui in qualche sito una funzione
analoga gia' scritta, testata, stabile e che soddisfi tutti i requisiti
che ci interessano e allora potremo tranquillamente buttare quel mio
abbozzo.
(3)
Ancora grazie. Proprio questo mi interessava. Io non ho pazienza di
testare. Alcuni di quei risultati me li aspettavo e credo derivino
dall'uso di CDate, altra funzione di cui diffidare.
' modUtil - Modulo
Option Explicit
Option Private Module
' 1.0002
Public Function VerificaData(ByVal Text _
As String _
, Optional ByVal Date1904 _
As Boolean = False _
) As Variant
On Error GoTo ErrorHandler
Const f = "0000""-""00""-""00"
Dim r As Variant
Dim s As String
Dim d() As String
s = Trim$(Text)
If Len(s) Then
s = Replace(s, " ", "-")
s = Replace(s, "/", "-")
d = Split(s, "-")
Select Case UBound(d)
Case 0
Select Case Len(s)
Case 4
r = CStr(Year(Date)) _
& Right$(s, 2) _
& Left$(s, 2)
Case 6
r = "20" & Right$(s, 2) _
& Mid$(s, 3, 2) _
& Left$(s, 2)
Case 8
r = Right$(s, 4) _
& Mid$(s, 3, 2) _
& Left$(s, 2)
Case Else
Err.Raise 13
End Select
Case 1
r = CStr(Year(Date)) _
& Right$("0" & d(1), 2) _
& Right$("0" & d(0), 2)
Case 2
r = Right$("20" & d(2), 4) _
& Right$("0" & d(1), 2) _
& Right$("0" & d(0), 2)
Case Else
Err.Raise 13
End Select
r = Format$(r, f)
If Len(r) = Len(Format$(0, f)) Then
d = Split(r, "-")
If CLng(d(0)) >= 100 _
And CLng(d(1)) >= 1 _
And CLng(d(2)) >= 1 Then
r = CDate(r)
Else
Err.Raise 13
End If
Else
Err.Raise 13
End If
If Date1904 Then
If r < #1/2/1904# Then Err.Raise 13
Else
If r < #3/1/1900# Then Err.Raise 13
End If
End If
ExitProcedure:
VerificaData = r
Exit Function
ErrorHandler:
r = CVErr(13)
Resume ExitProcedure
End Function
--
'-----------------
1)
Esatto! Infatti la nostra estenuante :-) discussione deriva dal fatto
che non riusciamo a capire l'uno le ragioni dell'altro. Ovvero che io
non riesco a farti capire la differenza che c'e', secondo me, fra le
intenzioni dell'utente (cosa per me NON rilevante) e le intenzioni del
programmatore.
Non importa cosa intende scrivere l'utente ma solo cio' che
effettivamente scrive; e cio' che l'utente scrive *deve* essere validato
dal programmatore. Questa infatti e' l'intenzione del programmatore
quando usa IsDate: validare l'input dell'utente. Cio' che il
programmatore non si aspetta e' che vengano considerate valide date che
valide non sono. Da questo deriva il mio invito di partenza a
*diffidare* di IsDate, cosa che in tanti, da anni, ripetiamo; per
esempio la citazione di Pearson e' del 2001.
Concludendo, se un utente scrive una data valida avendo intenzione di
scriverne un'altra, non ci possiamo fare nulla, e questo rientra nelle
responsabilita' dell'utente. Al massimo possiamo agevolarlo con
strumenti piu' amichevoli come appunto il Controllo calendario o simili.
Se invece scrive una data non valida il nostro dovere e' di segnalarlo e
di impedire tale immissione. Cosa che usando IsDate non e' possibile
fare.
'-----------------
Grazie per la tua rispostta.
Posso concordare con molto di questo ma,
aggiiungerei due punti:
(1) L'uso del controllo Calendario non era
suggerito unicamente perche' sia piu'
amichevoli ma proprio anche perche' non
puo' fornire una data non valida e, pertanto,
non e' poi necessario controllare la validità
del risultato.
(2)
'--------------
Non importa cosa intende scrivere l'utente ma solo cio' che
effettivamente scrive
'--------------
Per il momento, rispondo con un piccolo
esempio per illustrare un mia aspirazione
in questo proposito:
Se io facessi una ricerca dell'Help di VBA,
utilizzando "IsDato"come chiave di ricerca,
Help risponderebbe "Non capisco!"; se, invece,
facessi una ricerca analoga con Google, otterrei
la risposta utilissima "Intendevi IsDate?"
Ovviamente una cosa del genere non sarebbe
spesso fattibile, ma non vorrei escluderla a
priori.
Infatti, vorrei che lo sviluppatore non si limitasse
a considerare se la 'data' fosse una data valida
(una 'verifica grammaticale', se vuoi), ma che
controllasse anche la ragionevolezza della data.
Comunque, forse questa rappresenta una
digressione e, per quanto riguarda il tuo punto
centrale - la funzione IsDate puo' essere
problematica - concordo pienamente con te.
Ti ringrazio della tua pazienza e ti chiederei di
scusare il mio italiano esecrabile
'--------------
[...]
' modUtil - Modulo
'--------------
Provando l'ultima verione della tua funzione -
sempre seguendo il tuo consiglio di "sottoporla
a durissimi e spietati test", ottengo i seguenti
risultati:
324/2/10
===> 24-Feb-2010
9876543210/2/05
===> 10-Feb-2005
9876543210/112/05
===> 10-Dec-2005
123498765432331/05/88
===> 31-May-2088
MaurizioBorell22/07/77
===> 22-Jul-2077
NormanJones"Ł987654321$%^&*()_+0111/07/54
===>11-Jul-2054
"Ł987654321$%^&*()+98765432101101/0765432107 5334
===> 1-Jul-5334
Non mi testa nessuno.... 8-(
'--------------
> MaurizioBorell22/07/77
> ===> 22-Jul-2077
>
> NormanJones"£987654321$%^&*()_+0111/07/54
> ===>11-Jul-2054
>
Non mi testa nessuno.... 8-(
'--------------
Ho provato ad utilizzare 'Mauro' ma, ogni
volta, Excel ha risposto con un saluto deferente
"Buon giorno Sig, Gamberini!" ed ha restituito
il risultato giusto!
Veramente pensavo che:
http://www.youtube.com/watch?v=xhxqtULpbm0&NR=1
[...]
> 324/2/10
> ===> 24-Feb-2010
> 9876543210/2/05
> ===> 10-Feb-2005
> 9876543210/112/05
> ===> 10-Dec-2005
> 123498765432331/05/88
> ===> 31-May-2088
> MaurizioBorell22/07/77
> ===> 22-Jul-2077
> NormanJones"£987654321$%^&*()_+0111/07/54
> ===>11-Jul-2054
> "£987654321$%^&*()+98765432101101/0765432107 5334
> ===> 1-Jul-5334
[...]
Ciao Norman.
Ho ridisegnato la funzione, mantendendo per ora l'uso delle funzioni VB6
only per comodita'. Intendo in seguito sostituirle per compatibilita'
con Excel 97.
Lo scopo della funzione e' quello di validare stringhe di testo
rappresentanti date immesse nel formato GMA.
I formati di immissione previsti sono:
Senza separatori:
GGMM
GGMMAA
GGMMAAAA
-oppure-
Con separatori:
i separatori accettati sono:
<spazio>
.
/
-
e i relativi formati (assumendo per esempio il separatore "/"):
G/M
GG/M
G/MM
GG/MM
G/M/AA
GG/M/AA
G/MM/AA
GG/MM/AA
G/M/AAAA
GG/M/AAAA
G/MM/AAAA
GG/MM/AAAA
In tutti i casi, se non immesso, viene assunto l'anno della data
corrente. Se immesso di due cifre viene assunto come anno le cui prime 2
cifre sono "20".
Il tipo Variant restituito dalla funzione puo' assumere il valore:
Empty = Nessuna data immessa
Errore 13 = Data non valida
Un valore di tipo Date nell'intervallo:
1900-03-01:9999-12-31, se l'argomento Data1904=False;
1904-01-02:9999-12-31, se l'argomento Data1904=True.
Non sono considerate valide le date nell'intervallo, accettato da Excel:
1900-01-01:1900-02-29
perche' l'anno 1900 non e' bisestile.
' modUtil - Modulo
Option Explicit
Option Private Module
Private Sub VerificaData_test()
Dim i As Long
For i = -1 To 0
Debug.Print "Date1904="; CBool(i)
Debug.Print "CDate", "myCDate", "Input"
VerificaData_Print "", i
VerificaData_Print "0101", i
VerificaData_Print "010107", i
VerificaData_Print "01012007", i
VerificaData_Print "010100", i
VerificaData_Print "01010000", i
VerificaData_Print "1/1", i
VerificaData_Print "1/1/07", i
VerificaData_Print "1/1/2007", i
VerificaData_Print "1/1/00", i
VerificaData_Print "1/1/0000", i
VerificaData_Print "01/01/0000", i
VerificaData_Print "1/1/0000000000", i
VerificaData_Print "324/2/10000", i
VerificaData_Print "1/1/1904", i
VerificaData_Print "010102/02010301/09010001010000", i
VerificaData_Print "91+%081802/02067145.20301/09801000101000098", i
VerificaData_Print
"91+%081802/02067145.20301/098010001+55501000012", i
VerificaData_Print
"ABC8%76^A2Bc502/02$$$$45.20301/098010001+9$$$87654321&^%PQR5007", i
VerificaData_Print
"9+&?1+%081802/02067145.20301/098010011+98765432155050029", i
VerificaData_Print
"76^A2Bc908/02$$$45.20307/098040003+9$$$87IMaurizioBorelliA^%PQR5007", i
VerificaData_Print "324/2/10", i
VerificaData_Print "9876543210/2/05", i
VerificaData_Print "9876543210/112/05", i
VerificaData_Print "123498765432331/05/88", i
VerificaData_Print "MaurizioBorell22/07/77", i
VerificaData_Print "NormanJones ""£987654321$%^&*()_+0111/07/54""",
i
VerificaData_Print """£987654321$%^&*()+98765432101101/0765432107
5334", i
Debug.Print
Next
End Sub
Private Sub VerificaData_Print(ByVal s As String _
, ByVal b As Boolean)
Dim d As Variant
On Error Resume Next
Debug.Print CDate(s);
Debug.Print ,
d = VerificaData(s, b)
If IsEmpty(d) Then
Debug.Print "Null String",
ElseIf IsError(d) Then
Debug.Print "Not Valid",
Else
Debug.Print d,
End If
Debug.Print "'"; s; "'"
End Sub
' 1.0003
Public Function VerificaData(ByVal Text _
As String _
, Optional ByVal Date1904 _
As Boolean = False _
) As Variant
On Error GoTo ErrorHandler
Const f = "0000""-""00""-""00"
Dim r As Variant
Dim s As String
Dim t As String
Dim d() As String
s = Trim$(Text)
If Len(s) Then
s = Replace(s, " ", "-")
s = Replace(s, ".", "-")
s = Replace(s, "/", "-")
t = Replace(s, "-", "")
If Not (t Like String$(Len(t), "#")) Then
Err.Raise 13
End If
d = Split(s, "-")
Select Case UBound(d)
Case 0
Select Case Len(s)
Case 4
d = Split(Format$(s, "00-00") & "-" & CStr(Year(Date)) _
, "-")
Case 6
d = Split(Format$(Left$(s, 4) & "20" & Right$(s, 2) _
, "00-00-0000") _
, "-")
Case 8
d = Split(Format$(s, "00-00-0000") _
, "-")
Case Else
Err.Raise 13
End Select
Case 1
d = Split(Join(d, "-") & "-" & CStr(Year(Date)) _
, "-")
Case 2
d(2) = Right$("20" & d(2), 4)
Case Else
Err.Raise 13
End Select
If UBound(d) = 2 Then
If CLng(d(2)) >= 100 _
And CLng(d(1)) >= 1 _
And CLng(d(0)) >= 1 Then
d(0) = Format$(d(0), "00")
d(1) = Format$(d(1), "00")
d(2) = Format$(d(2), "0000")
r = CDate(Format$(d(2) & d(1) & d(0), f))
Else
Err.Raise 13
End If
Else
Err.Raise 13
End If
If Date1904 Then
If r < #1/2/1904# Then Err.Raise 13
Else
If r < #3/1/1900# Then Err.Raise 13
End If
End If
ExitProcedure:
VerificaData = r
Exit Function
ErrorHandler:
r = CVErr(13)
Resume ExitProcedure
End Function
OUTPUT:
Date1904=True
CDate myCDate Input
Null String ''
10/04/1900 01/01/2007 '0101'
02/09/1927 01/01/2007 '010107'
11/10/4670 01/01/2007 '01012007'
26/08/1927 01/01/2000 '010100'
13/04/4665 Not Valid '01010000'
01/01/2007 01/01/2007 '1/1'
01/01/2007 01/01/2007 '1/1/07'
01/01/2007 01/01/2007 '1/1/2007'
01/01/2000 01/01/2000 '1/1/00'
01/01/2000 Not Valid '1/1/0000'
01/01/2000 Not Valid '01/01/0000'
01/01/2000 Not Valid '1/1/0000000000'
Not Valid '324/2/10000'
01/01/1904 Not Valid '1/1/1904'
Not Valid '010102/02010301/09010001010000'
Not Valid
'91+%081802/02067145.20301/09801000101000098'
Not Valid
'91+%081802/02067145.20301/098010001+55501000012'
Not Valid
'ABC8%76^A2Bc502/02$$$$45.20301/098010001+9$$$87654321&^%PQR5007'
Not Valid
'9+&?1+%081802/02067145.20301/098010011+98765432155050029'
Not Valid
'76^A2Bc908/02$$$45.20307/098040003+9$$$87IMaurizioBorelliA^%PQR5007'
10/02/324 Not Valid '324/2/10'
Not Valid '9876543210/2/05'
Not Valid '9876543210/112/05'
Not Valid '123498765432331/05/88'
Not Valid 'MaurizioBorell22/07/77'
Not Valid 'NormanJones
"£987654321$%^&*()_+0111/07/54"'
Not Valid
'"£987654321$%^&*()+98765432101101/0765432107 5334'
Date1904=False
CDate myCDate Input
Null String ''
10/04/1900 01/01/2007 '0101'
02/09/1927 01/01/2007 '010107'
11/10/4670 01/01/2007 '01012007'
26/08/1927 01/01/2000 '010100'
13/04/4665 Not Valid '01010000'
01/01/2007 01/01/2007 '1/1'
01/01/2007 01/01/2007 '1/1/07'
01/01/2007 01/01/2007 '1/1/2007'
01/01/2000 01/01/2000 '1/1/00'
01/01/2000 Not Valid '1/1/0000'
01/01/2000 Not Valid '01/01/0000'
01/01/2000 Not Valid '1/1/0000000000'
Not Valid '324/2/10000'
01/01/1904 01/01/1904 '1/1/1904'
Not Valid '010102/02010301/09010001010000'
Not Valid
'91+%081802/02067145.20301/09801000101000098'
Not Valid
'91+%081802/02067145.20301/098010001+55501000012'
Not Valid
'ABC8%76^A2Bc502/02$$$$45.20301/098010001+9$$$87654321&^%PQR5007'
Not Valid
'9+&?1+%081802/02067145.20301/098010011+98765432155050029'
Not Valid
'76^A2Bc908/02$$$45.20307/098040003+9$$$87IMaurizioBorelliA^%PQR5007'
10/02/324 Not Valid '324/2/10'
Not Valid '9876543210/2/05'
Not Valid '9876543210/112/05'
Not Valid '123498765432331/05/88'
Not Valid 'MaurizioBorell22/07/77'
Not Valid 'NormanJones
"£987654321$%^&*()_+0111/07/54"'
Not Valid
'"£987654321$%^&*()+98765432101101/0765432107 5334'
Come va adesso?
--
(Facci sapere se e eventualmente come hai risolto. Grazie.)