IsDate meno tollerante SOLVED

di il
43 risposte

43 Risposte - Pagina 2

  • Re: IsDate meno tollerante SOLVED

    27/09/2023 - @Alex ha scritto:


    Un suggerimento, non mettere [EsitoValida = True] all'inizio della Funzione… non ha senso, una Funzione di Validazione è FALSE se non dimostri il contrario, questo è il senso della validazione, non può essere VALIDO salvo non lo sia, sono 2 concetti molto diversi.

    Io farei una cosa simile, mi pare più pulita:

    Function DataValida(ggBmmBaaaa As String) As Boolean
        Dim VDate    As Variant
        Dim GG       As Integer
        Dim MM       As Integer
        Dim AAAA     As Integer
        
    	VDate = Split(ggBmmBaaaa, "/")
       	If (Len(VDate(0)) < 2) Or (Len(VDate(1)) < 2) Or (Len(VDate(2)) < 2) Then Exit Function
        
        GG = CInt(VDate(0))
        MM = CInt(VDate(1))
        AAAA = CInt(VDate(2))
        
        If (AAAA < 1000) Or (AAAA > 2200) Then Exit Function
        If (GG < 1) Or (GG > 32) Then Exit Function
        
        Select Case MM
            Case Is < 1, Is > 12:           Exit Function
            Case 11, 4, 6, 9
                If GG > 30 Then Exit Function
            Case 2
                If GG > 29 Then Exit Function
                If GG = 29 Then
                    ' controllo bisestili divisibili per 4 e non per 100
                    If (AAAA Mod 4 = 0) And (AAAA Mod 100 = 0) Then Exit Function
                End If
       End Select
       DataValida = True
    End Function

    Sì ci può stare, diciamo che non ero sicuro che se non forzi a true la funzione restituisce false.

  • Re: IsDate meno tollerante SOLVED

    27/09/2023 - paoloholzl ha scritto:

    Prende in input ggmmaaaa, bisognerebbe metterlo in chiaro.  Non funziona con i bisestili

    Che vuoi dire? Hai compreso il codice che ti ho proposto? Lo hai provato?

    Se il formato non è ggmmaaaa ma gg/mm/aaaa il codice va modificato di poco ma vale lo stesso.

    Ovvero

    Function test(dt As String) As Boolean
       Dim sd As String
       
       test = False
       
       On Error GoTo errD
       sd = Left(dt, 2) & " " & MonthName(Mid(dt, 4, 2)) & " " & Mid(dt, 7, 4)	' formato gg/mm/aaaa
       
       test = IsDate(sd)
       Exit Function
       
    errD:
       
    End Function
  • Re: IsDate meno tollerante SOLVED

    27/09/2023 - @Alex ha scritto:


    Un suggerimento, non mettere [EsitoValida = True] all'inizio della Funzione… non ha senso, una Funzione di Validazione è FALSE se non dimostri il contrario, questo è il senso della validazione, non può essere VALIDO salvo non lo sia, sono 2 concetti molto diversi.

    Io farei una cosa simile, mi pare più pulita:

    Function DataValida(ggBmmBaaaa As String) As Boolean
        Dim VDate    As Variant
        Dim GG       As Integer
        Dim MM       As Integer
        Dim AAAA     As Integer
        
    	VDate = Split(ggBmmBaaaa, "/")
       	If (Len(VDate(0)) < 2) Or (Len(VDate(1)) < 2) Or (Len(VDate(2)) < 2) Then Exit Function
        
        GG = CInt(VDate(0))
        MM = CInt(VDate(1))
        AAAA = CInt(VDate(2))
        
        If (AAAA < 1000) Or (AAAA > 2200) Then Exit Function
        If (GG < 1) Or (GG > 32) Then Exit Function
        
        Select Case MM
            Case Is < 1, Is > 12:           Exit Function
            Case 11, 4, 6, 9
                If GG > 30 Then Exit Function
            Case 2
                If GG > 29 Then Exit Function
                If GG = 29 Then
                    ' controllo bisestili divisibili per 4 e non per 100
                    If (AAAA Mod 4 = 0) And (AAAA Mod 100 = 0) Then Exit Function
                End If
       End Select
       DataValida = True
    End Function

    Attenzione che hai introdotto un errore nel controllo dei bisestili

    non ci va 

                    ' controllo bisestili divisibili per 4 e non per 100
                    If (AAAA Mod 4 = 0) And (AAAA Mod 100 = 0) Then Exit Function

    ma

                   ' controllo bisestili divisibili per 4 e non per 100
                   If AAAA Mod 4 = 0 Then
                      If AAAA Mod 100 = 0 Then Exit Function
                      Else: Exit Function
                      End If
  • Re: IsDate meno tollerante SOLVED

    27/09/2023 - oregon ha scritto:


    Che vuoi dire? Hai compreso il codice che ti ho proposto? Lo hai provato?

    Ho capito, sto parlando al muro. Tolgo il disturbo.

  • Re: IsDate meno tollerante SOLVED

    27/09/2023 - paoloholzl ha scritto:


    Attenzione che hai introdotto un errore nel controllo dei bisestili

    non ci va 

                    ' controllo bisestili divisibili per 4 e non per 100
                    If (AAAA Mod 4 = 0) And (AAAA Mod 100 = 0) Then Exit Function

    ma

                   ' controllo bisestili divisibili per 4 e non per 100
                   If AAAA Mod 4 = 0 Then
                      If AAAA Mod 100 = 0 Then Exit Function
                      Else: Exit Function
                      End If

    Paolo… nella tua versione una volta che è divisibile per 4, Esce a prescindere sia o meno divisibile per 100… o sbaglio…?

    Quindi se leggo il tuo commento, ed ha un senso tecnico, deve essere così, che è come avevo scritto:

    ' controllo bisestili divisibili per 4 e non per 100
    If (AAAA Mod 4 = 0) And (AAAA Mod 100 = 0) Then Exit Function

    Penso ci sia un errore di base, ma usa il suggerimento di Oregon è decisamente indipendente da tutte le pippe di controlli che fai ora.

  • Re: IsDate meno tollerante SOLVED

    @paoloholz, validare una data NON E' SOLO questione di formato, MA ANCHE di:

    1. quale calendario
    2. quali mesi (e quanti) 
    3. lunghezza di ogni mese
    4. anni bisestile (esistono in quasi tutti i calendari) 
    5. quale formato usato per la data

    yyyymmdd  - ddmmyyyy - mmddyyyy

    i separatori, che possono essere /, - o lo spazio

    ecc, ecc, ecc

    Non lo implementi in 20 righe di codice mostrate come esempio. 

    Uno, se vuole fare le cose per bene, SE LE STUDIA a partire dagli spunti forniti! 

  • Re: IsDate meno tollerante SOLVED

    27/09/2023 - paoloholzl ha scritto:


    Ti pare che non te lo avrei detto senza averlo provato?
    E soprattutto ti pare che non abbia capito il contenuto di un codice del genere?
    Sorvolo sul fatto (sono opinioni personali) che l'aver visto il goto mi ha fatto venire l'orticaria.
    La strada seguita era furba ma comunque il 29/02/2000 non è una data valida il tuo codice la dà valida.

    No, non l'hai capito perché la prima versione del codice lavora con il formato “ddmmaaaa” senza le barre.

    Nella seconda versione ho considerato le barre.

    Sul fatto del Goto ti faccio notare che fa parte della On Error e non ti può venire nessuna orticaria perché è così che si fa

    Il “29/02/2000" testato con la seconda versione che ti ho indicato (e che avresti dovuto modificare da solo avendo compreso la prima versione) viene correttamente valutata come False

  • Re: IsDate meno tollerante SOLVED

    27/09/2023 - paoloholzl ha scritto:


    Se io ho scelto di inserire Giorno/Mese/Anno vorrei una risposta coerente con l'insert che mi aspetto.
    Se chiedo gg/mm/aaaa e mi trovo 02/16/2023 deve darmi falso.

    C'è una funzione che faccia una cosa del genere?

    Ciao,

    se è un problema di inserimento delle date, al fine di avere sempre un valore corretto e coerente così come indicavi, sarebbe opportuno usare il calendario… esempio :

    Altrimenti, se si predilige la digitazione, potresti usare dei selettori … una cosa di questo tipo con le combobox:

    Pertanto le validazioni risultano molto più semplici e coerenti. 


    Edit:

    se poi devi leggere un file esterno e devi validare le date in esso presenti, allora si deve prediligere le soluzioni poste da @Alex e Oregon

    Ma in questo caso dovrebbe solo servire per capire il giusto formato data da utilizzare e non per validare la data, altrimenti significherebbe di avere una fonte dati poco attendibile e magari da validare ancor prima di leggerla con i dovuti controlli. Se la fonte dati non è affidabile ovviamente si possono avere dati importati o letti, altrettanto non affidabili.

    Sono solo considerazioni ed ipotesi non conoscendo il contesto del tuo caso.

  • Re: IsDate meno tollerante SOLVED

    27/09/2023 - oregon ha scritto:


    27/09/2023 - paoloholzl ha scritto:


    Ti pare che non te lo avrei detto senza averlo provato?
    E soprattutto ti pare che non abbia capito il contenuto di un codice del genere?
    Sorvolo sul fatto (sono opinioni personali) che l'aver visto il goto mi ha fatto venire l'orticaria.
    La strada seguita era furba ma comunque il 29/02/2000 non è una data valida il tuo codice la dà valida.

    No, non l'hai capito perché la prima versione del codice lavora con il formato “ddmmaaaa” senza le barre.

    Nella seconda versione ho considerato le barre.

    Sul fatto del Goto ti faccio notare che fa parte della On Error e non ti può venire nessuna orticaria perché è così che si fa

    Il “29/02/2000" testato con la seconda versione che ti ho indicato (e che avresti dovuto modificare da solo avendo compreso la prima versione) viene correttamente valutata come False

    Il problema non era quello delle barre è che nelle prove che avevo fatto il 31/12/2000 lo pensavo non bisestile e me lo dava vero.
    Ho poi controllato il calendario ed effettivamente era bisestile in quanto divisibile per 100.
    Ecco perchè poi il messaggio lo avevo cancellato.
    La tua routine funziona benissimo ed è molto compatta quanto al goto ognuno si tiene le sue opinioni.
    L'on-error lo trovo troppo generico lo uso proprio quando non posso farne a meno (comunicazioni RS2323 o altro).
    La sto usando così, grazie.

    
    Function DataValida(ggBmmBaaaa) As Boolean
      DataValida = IsDate(Left(ggBmmBaaaa, 2) & "/" & MonthName(Mid(ggBmmBaaaa, 4, 2)) & "/" & Mid(ggBmmBaaaa, 7, 4))
    End Function
    
  • Re: IsDate meno tollerante SOLVED

    Ti consiglio di non mettere  & "/" ed usare invece & " " perché il test lo fa su

    “29 gennaio 2023” 

    e non

    “29/gennaio/2023”

    (anche se funziona lo stesso, almeno per ora).

    Per l'On Error, non è una questione di gusti. E' l'istruzione che cattura le eccezioni in VBA e per quello va usata (come la Try in altri linguaggi).

    Nei casi in cui la stringa non sia valida per vari motivi, con la On Error risolvi, la tua funzione invece si ferma.

    Buon lavoro.

  • Re: IsDate meno tollerante SOLVED

    27/09/2023 - oregon ha scritto:


    Per l'On Error, non è una questione di gusti. E' l'istruzione che cattura le eccezioni in VBA e per quello va usata (come la Try in altri linguaggi).

    Nei casi in cui la stringa non sia valida per vari motivi, con la On Error risolvi, la tua funzione invece si ferma.

    Ma io voglio che si fermi e butti fuori.
    Se ho fatto tutti i test corretti a monte (controllo dei null ecc.) blocchi non ne devo avere, se la causa è lì appena debuggo la becco subito.
    Se va ‘avanti lo stesso’ magari ti ritrovi un esito imprevisto a valle e risalire all'origine di un problema può essere complesso magari dopo che ti ha fatto danni di cui non ti eri ancora accorto.
    Ma in questo caso si va off-topic.     :-)

  • Re: IsDate meno tollerante SOLVED

    27/09/2023 - paoloholzl ha scritto:


    27/09/2023 - oregon ha scritto:


    Per l'On Error, non è una questione di gusti. E' l'istruzione che cattura le eccezioni in VBA e per quello va usata (come la Try in altri linguaggi).

    Nei casi in cui la stringa non sia valida per vari motivi, con la On Error risolvi, la tua funzione invece si ferma.

    Ma io voglio che si fermi e butti fuori.
    Se ho fatto tutti i test corretti a monte (controllo dei null ecc.) blocchi non ne devo avere, se la causa è lì appena debuggo la becco subito.
    Se va ‘avanti lo stesso’ magari ti ritrovi un esito imprevisto a valle e risalire all'origine di un problema può essere complesso magari dopo che ti ha fatto danni di cui non ti eri ancora accorto.
    Ma in questo caso si va off-topic.     :-)

    Paolo, come ti ha detto Oregon, la funzione esce NON VALIDANDO, come dici tu si ferma nel senso che si PIANTA per errore non gestito, stai veramente sbagliando considerazione tecnica.

  • Re: IsDate meno tollerante SOLVED

    27/09/2023 - paoloholzl ha scritto:


    Ma io voglio che si fermi e butti fuori.

    Che vuol dire? Se c'è un errore si ferma tutto.

    Come fai a fare tutti i test prima se il dato arriva direttamente da un DB?

    E comunque, vai contro tutti i principi della “programmazione difensiva” 

    Saluti

  • Re: IsDate meno tollerante SOLVED

    27/09/2023 - @Alex ha scritto:

    Paolo, come ti ha detto Oregon, la funzione esce NON VALIDANDO, come dici tu si ferma nel senso che si PIANTA per errore non gestito, stai veramente sbagliando considerazione tecnica.

    Forse mi sono espresso male ma quello che volevo dire è che mettiamo che nella funzione che ha indicato per una serie di problemi a monte come parametro non venga passato giorno mese anno ma ‘pippo’.
    La funzione con l'on error impostato come nell'esempio restituisce falso (che può essere interpretato come data non valida).
    Io preferisco che il programma butti fuori come errore non gestito, lo rilancio col debugger attivo e si posiziona sull'istruzione che va in errore.
    E anche se cerchi di ipotizzare tutte le ipotesi plausibili per intercettare ciascun potenziale errore poi in seguito a valle, imbratti il codice e comunque non li beccherai mai tutti.
    Non uso quasi mai (tranne per la gestione di eventi particolari asincroni, per esempio le seriali), on error goto proprio per quello e piantamenti per errore non gestito non ne ho praticamente mai.
    Può capitare in particolare nelle prime installazioni di una gestione nuova in fase di test, ma il tutto si ferma lì.
    La rarissima volta che capita in produzione devo saperlo assolutamente perchè c'è qualcosa di serio a monte che non va (in questo caso manca il controllo a monte della correttezza strutturale del parametro). Sono controlli che cerco di fare prima e non dopo.

  • Re: IsDate meno tollerante SOLVED

    Infatti “pippo” è una data non valida. Valutazione corretta del software.

    E in quanto tale, il codice successivo la rifiuta e chiede nuovamente.

    27/09/2023 - paoloholzl ha scritto:


    Io preferisco che il programma butti fuori come errore non gestito,

    Questo comportamento, in produzione con degli utenti collegati è disastroso.

Devi accedere o registrarti per scrivere nel forum
43 risposte