IsDate meno tollerante SOLVED

di il
43 risposte

IsDate meno tollerante SOLVED

IsDate (ma anche CVDate) hanno il vizio (a mio parere folle),  di tollerare le inversioni.

In pratica se chiedo isdate("16/02/2023") mi dice vero perchè è il 16 Febbraio.
Se chiedo isdate("02/16/2023") mi dice ugualmente vero perchè è sempre il 16 Febbraio.

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?

43 Risposte

  • Re: IsDate meno tollerante SOLVED

    Non mi sento propriamente all'altezza del problema, ma a livello di cosa stai facendo questo test? Intendo soprattutto query o VBA? In quest'ultimo caso prova a usare le sintassi in inglese dd/mm/yyyy.

  • Re: IsDate meno tollerante SOLVED

    La IsDate non ha nulla a che fare con le regole di input.

    Le regole seguite sono quelle anglosassoni ed europee.

    Prova a tradurre in formato

    isdate("16 feb 2023")

    per chiarezza

  • Re: IsDate meno tollerante SOLVED

    https://support.microsoft.com/it-it/office/funzione-isdate-6e73b294-7ea7-4838-bbe8-53f0dd8f70b5

    in particolare:

    “IsDate restituisce True se l'espressione è una data o è riconoscibile come data valida; in caso contrario, restituisce False. In Microsoft Windows l'intervallo di date valide è compreso tra l'1 gennaio 100 d.C. e il 31 dicembre 9999 d.C.; gli intervalli variano a seconda del sistema operativo.”

    in altre parole stai verificando se l'argomento è una data.

    https://support.microsoft.com/it-it/office/funzioni-di-conversione-tra-tipi-di-dati-8ebb0e94-2d43-4975-bb13-87ac8d1a2202

    cvdate o CDate?

  • 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.

    da maschera? da codice?

    https://support.microsoft.com/it-it/office/controllare-i-formati-di-immissione-dei-dati-con-maschere-di-input-e125997a-7791-49e5-8672-4a47832de8da

  • Re: IsDate meno tollerante SOLVED

    Non credo sia fattibile quello che chiedi, perchè il sistema rielabora la data a monte del tuo controllo, quindi per il sistema la data ha solo 2 opzioni o è Valida o No…!

    Esempio:

    #30/02/2023# Questo restituisce Errore non è una data, usando cDate o IsDate stessa cosa
    #13/13/2023# Questo restituisce Errore non è una data, usando cDate o IsDate stessa cosa

    ma

    #16/02/2023# e #02/16/2023# il sistema le considera lo stesso valore #02/16/2023#
    Quindi nessuna funzione legata alle date potrà fare quello che pensi debba essere invece normale fare.

    Puoi ottenere quello che chiedi solo se, converti con cStr(ValoreData) e vai ad analizzare le 3 Componenti singole con un sistema di Validazione a 2 caratteri per gg, mm ed aaaa

    Oppure spezzi l'inserimento con 3 TxtBox nelle quali vai adefinire il criterio di Validazione nella Singola TextBox…

    In quella dei gg metterai >0 AND < 31 (ovviamente se non sa il mese…)
    In quella dei mm metterai >0 AND <12
    Per gli anni… quello che vuoi >2020 AND <2050

    Saluti

  • Re: IsDate meno tollerante SOLVED

    Puoi scrivere una funzione di Validazione semplice…

    Function fValiDate(pDate As String) As Boolean
        Dim vDate   As Variant    
        vDate = Split(pDate, "/")
    
        fValiDate= (vDate(0) > 0 And vDate(0) < 32) And (vDate(1) > 0 And vDate(1) < 13) And (vDate(2) > 2020 And vDate(2) < 2050)
        
    End Function

    da richiamare ovviamente così:

    =fValiDate(TuaData)

    Attenzione che se passi un valore data, ti frega a prescindere in quanto #16/02/2023# non è una data valida dal momento che lui ragiona in accezione Anglosassone, quindi come dicevo sopra viene convertita ancor prima in #02/16/2023# e non ci puoi fare nulla.

  • Re: IsDate meno tollerante SOLVED

    27/09/2023 - OsvaldoLaviosa ha scritto:


    Non mi sento propriamente all'altezza del problema, ma a livello di cosa stai facendo questo test? Intendo soprattutto query o VBA? In quest'ultimo caso prova a usare le sintassi in inglese dd/mm/yyyy.

    VBA

  • Re: IsDate meno tollerante SOLVED

    27/09/2023 - @Alex ha scritto:


    Puoi scrivere una funzione di Validazione semplice…

    Function fValiDate(pDate As String) As Boolean
        Dim vDate   As Variant    
        vDate = Split(pDate, "/")
    
        fValiDate= (vDate(0) > 0 And vDate(0) < 32) And (vDate(1) > 0 And vDate(1) < 13) And (vDate(2) > 2020 And vDate(2) < 2050)
        
    End Function

    La validazione ‘da codice’ potevo farmela pure io, ma è decisamente più articolata di quella che hai scritto, deve tenere conto del 29 febbraio dei bisestili ecc.

    Nel codice lavoro sempre come 

    #mm/dd/yy#  

    diciamo che mi illudevo che esistesse qualcosa tipo 

    IsDateFormat(CheData,"dd/mm/yyyy")
  • Re: IsDate meno tollerante SOLVED

    Non esiste IsDateFormat ma, come ti ho già detto, se scrivi esplicitamente il mese nella stringa prima di controllarla, puoi ottenere quello che cerchi.

  • Re: IsDate meno tollerante SOLVED

    27/09/2023 - oregon ha scritto:


    Non esiste IsDateFormat ma, come ti ho già detto, se scrivi esplicitamente il mese nella stringa prima di controllarla, puoi ottenere quello che cerchi.

    La data magari arriva da un DB non ho il controllo della digitazione.
    Comunque mi sono scritto una routine che dai primi test sembra che funzioni.

    Function DataValida(ggBmmBaaaa As String) As Boolean
       Dim VDate   As Variant
       Dim GG, MM, AAAA
       Dim EsitoValida As Boolean
       
       VDate = Split(ggBmmBaaaa, "/")
       If (Len(VDate(0)) < 2) Or (Len(VDate(1)) < 2) Or (Len(VDate(2)) < 2) Then
          DataValida = False
          Exit Function
          End If
       
       GG = CInt(VDate(0))
       MM = CInt(VDate(1))
       AAAA = CInt(VDate(2))
       
       EsitoValida = True
       If (MM < 1) Or (MM > 12) Then EsitoValida = False
       If (AAAA < 1000) Or (AAAA > 2200) Then EsitoValida = False
       Select Case MM
           Case 11, 4, 6, 9
               If (GG < 1) Or (GG > 30) Then EsitoValida = False
           Case 2
               If (GG < 1) Or (GG > 29) Then EsitoValida = False
               If GG = 29 Then
                   ' controllo bisestili divisibili per 4 e non per 100
                   If AAAA Mod 4 = 0 Then
                       If AAAA Mod 100 = 0 Then
                           EsitoValida = False
                           End If
                       Else
                       EsitoValida = False
                       End If
                   End If
           Case Else
               If (GG < 1) Or (GG > 31) Then EsitoValida = False
       End Select
       DataValida = EsitoValida
    End Function
  • Re: IsDate meno tollerante SOLVED

    Ovvio che non hai controllo sul dato nel DB ma come hai fatto la tua funzione puoi farne una che controlla dopo la trasformazione che ti suggerivo. Mi sembrava ovvio.

    Qualcosa del genere

    Function test(dt As String) As Boolean
       Dim sd As String
       
       test = False
       
       On Error GoTo errD
       sd = Left(dt, 2) & " " & MonthName(Mid(dt, 3, 2)) & " " & Mid(dt, 5, 4)
       
       test = IsDate(sd)
       Exit Function
       
    errD:
       
    End Function
    
  • Re: IsDate meno tollerante SOLVED

    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
  • Re: IsDate meno tollerante SOLVED

    27/09/2023 - oregon ha scritto:


    Ovvio che non hai controllo sul dato nel DB ma come hai fatto la tua funzione puoi farne una che controlla dopo la trasformazione che ti suggerivo. Mi sembrava ovvio.

    Qualcosa del genere

    Function test(dt As String) As Boolean
       Dim sd As String
       
       test = False
       
       On Error GoTo errD
       sd = Left(dt, 2) & " " & MonthName(Mid(dt, 3, 2)) & " " & Mid(dt, 5, 4)
       
       test = IsDate(sd)
       Exit Function
       
    errD:
       
    End Function
    

    Bella idea… veramente pulita passando per la conversioen in stringa.

  • Re: IsDate meno tollerante SOLVED

    27/09/2023 - oregon ha scritto:


    Ovvio che non hai controllo sul dato nel DB ma come hai fatto la tua funzione puoi farne una che controlla dopo la trasformazione che ti suggerivo. Mi sembrava ovvio.

    Qualcosa del genere

    Function test(dt As String) As Boolean
       Dim sd As String
       
       test = False
       
       On Error GoTo errD
       sd = Left(dt, 2) & " " & MonthName(Mid(dt, 3, 2)) & " " & Mid(dt, 5, 4)
       
       test = IsDate(sd)
       Exit Function
       
    errD:
       
    End Function
    

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

Devi accedere o registrarti per scrivere nel forum
43 risposte