Newsgroup: it.comp.appl.access
Titolo: CODICE FISCALE







C'è una procedura che mi controlli la validità del 
C.F. ? 


Grazie anticipatamente.


 


Non rispondetemi con : 


 


Sito Comune di it.comp.appl.access
http://members.xoom.it/it_db_access


 


La risposta lì non 
c'è.




Non rispondetemi con :


------------------------------
Come non c'è???? Dai per scontate le cose, oppure sei cieco? Vai un pò qui e
poi dimmi: 
http://members.xoom.it/_XOOM/it_db_access/tips18.htm
Anche se, devo dire, quella funzione potrebbe essere ottimizzata.
La matrice che contiene le lettere dell'alfabeto, potrebbe essere generata
tramite un ciclo e i codici ASCII, riducendo le righe da 26 a tre.
Anche l'istruzione Selec case, con tutti i vari Case, potrebbe essere
ottimizzata. I numeri possono essere convertiti usando l'istruzione Val. Per
lettere sarebbe sufficiente sottrarre, al corrispondente codice ASCII, il
numero 65 (corrispondente alla 'A').
Questo è valido, ovviamente, per la prima Select. La seconda è più
compelssa, anche se credo che possa essere ridotta, in qualche modo.

 Grazie anticipatamente.
ti serve uncontrollo che sia esatto  o che te lo generi?

 compelssa, anche se credo che possa essere ridotta, in qualche modo.
Sono daccordo, il problema e' trovare il tempo per farlo.
Naturalmente se riesci a farlo, non ho problemi a sostituirla :-))
-- 
Federico
--------------------------------------
Sito Comune di it.comp.appl.access
http://members.xoom.it/it_db_access
mailto:
it_db_...@usa.net
--------------------------------------
Tutte le richieste che mi arrivano
in privato, vengono cestinate.
--------------------------------------
Rimuovi paperino. per e-mail
--------------------------------------

 Federico
Io ci ho provato a farla una routine piů snella e l'ho anche inviata al sito
comune, ma continua ad essere pubblicata quella di prima. A scopo didattico,
mi piacerebbe capire se la mia routine non funziona e perché cosě da poterci
lavorare sopra e renderla piů efficiente. Secondo il mio immodesto parere la
chicca della mia routine sta nel calcolo dlla lettera di controllo che č
effettuata utilizzando i codici ASCI dei caratteri e gli operatori boleani
cosě:
Sub miocontrollo(ok$)
' ok$ contiene la stringa dei 15 caratteri
ReDim d(26)
d(0) = 1: d(1) = 0: d(2) = 5: d(3) = 7
d(4) = 9: d(5) = 13: d(6) = 15: d(7) = 17
d(8) = 19: d(9) = 21: d(10) = 2: d(11) = 4
d(12) = 18: d(13) = 20: d(14) = 11: d(15) = 3
d(16) = 6: d(17) = 8: d(18) = 12: d(19) = 14
d(20) = 16: d(21) = 10: d(22) = 22: d(23) = 25
d(24) = 24: d(25) = 23
' calcolo lettera di controllo
For i = 1 To 15
    If i \ 2 = i / 2 Then pari = True Else pari = False
    ch = Asc(Mid(ok, i, 1))
' ed ecco la mia chicca...
    v = ch + 65 * (ch > 64 And ch < 91) + 48 * (ch > 47 And ch < 58)
    If pari Then tot = tot + v Else tot = tot + d(v)
Next
ok = Chr(tot Mod 26 + 65)
End Sub
che č sicuramente piů breve e (scusa l'immodestia) piů "bella" di quella
pubblicata che riporto di seguito.
Se non si č ancora capito, sto facendo polemica apposta per innescare un
discorso sulla programmazione. A mio modo di vedere il programmatore č un
"artista", non basta risolvere il problema ma occorre risolverlo con
"eleganza"; quindi parliamo anche di modi di programmare.
Un cordiale saluto da Santini
Public Function CheckCodFiscale(CFis As String) As Boolean
    'Autore: Federico Luciani
    'Accetta: CFis = Codice fiscale da verificare
    'Restituisce: true se il Codice fiscale č corretto
    If Len(CFis) <> 16 Then
       CheckCodFiscale = False
       Exit Function
    End If
    Dim i As Integer, p As Integer, d As Integer
    Dim SumDisp As Integer, SumPari As Integer
    Dim SumTot As Integer, Check As String
    Dim Resto(1 To 26) As String
    Resto(1) = "A"
    Resto(2) = "B"
    Resto(3) = "C"
    Resto(4) = "D"
    Resto(5) = "E"
    Resto(6) = "F"
    Resto(7) = "G"
    Resto(8) = "H"
    Resto(9) = "I"
    Resto(10) = "J"
    Resto(11) = "K"
    Resto(12) = "L"
    Resto(13) = "M"
    Resto(14) = "N"
    Resto(15) = "O"
    Resto(16) = "P"
    Resto(17) = "Q"
    Resto(18) = "R"
    Resto(19) = "S"
    Resto(20) = "T"
    Resto(21) = "U"
    Resto(22) = "V"
    Resto(23) = "W"
    Resto(24) = "X"
    Resto(25) = "Y"
    Resto(26) = "Z"
    For i = 2 To 14 Step 2
        Select Case Mid$(CFis, i, 1)
            Case "0": p = 0
            Case "1": p = 1
            Case "2": p = 2
            Case "3": p = 3
            Case "4": p = 4
            Case "5": p = 5
            Case "6": p = 6
            Case "7": p = 7
            Case "8": p = 8
            Case "9": p = 9
            Case "A": p = 0
            Case "B": p = 1
            Case "C": p = 2
            Case "D": p = 3
            Case "E": p = 4
            Case "F": p = 5
            Case "G": p = 6
            Case "H": p = 7
            Case "I": p = 8
            Case "J": p = 9
            Case "K": p = 10
            Case "L": p = 11
            Case "M": p = 12
            Case "N": p = 13
            Case "O": p = 14
            Case "P": p = 15
            Case "Q": p = 16
            Case "R": p = 17
            Case "S": p = 18
            Case "T": p = 19
            Case "U": p = 20
            Case "V": p = 21
            Case "W": p = 22
            Case "X": p = 23
            Case "Y": p = 24
            Case "Z": p = 25
        End Select
        SumPari = SumPari + p
    Next i
    For i = 1 To 15 Step 2
        Select Case Mid$(CFis, i, 1)
            Case "0": d = 1
            Case "1": d = 0
            Case "2": d = 5
            Case "3": d = 7
            Case "4": d = 9
            Case "5": d = 13
            Case "6": d = 15
            Case "7": d = 17
            Case "8": d = 19
            Case "9": d = 21
            Case "A": d = 1
            Case "B": d = 0
            Case "C": d = 5
            Case "D": d = 7
            Case "E": d = 9
            Case "F": d = 13
            Case "G": d = 15
            Case "H": d = 17
            Case "I": d = 19
            Case "J": d = 21
            Case "K": d = 2
            Case "L": d = 4
            Case "M": d = 18
            Case "N": d = 20
            Case "O": d = 11
            Case "P": d = 3
            Case "Q": d = 6
            Case "R": d = 8
            Case "S": d = 12
            Case "T": d = 14
            Case "U": d = 16
            Case "V": d = 10
            Case "W": d = 22
            Case "X": d = 25
            Case "Y": d = 24
            Case "Z": d = 23
        End Select
        SumDisp = SumDisp + d
    Next i
    SumTot = SumPari + SumDisp
    Check = Resto((SumTot Mod 26) + 1)
    If Check = UCase$(Right(CFis, 1)) Then
       CheckCodFiscale = True
    Else
       CheckCodFiscale = False
    End If
End Function

 "eleganza"; quindi parliamo anche di modi di programmare.
Si e' capito benissimo, e naturalmente non posso che darti ragione, ma...
e' anche vero che nella maggior parte dei casi i tempi sono molto stretti e
questo va sicuramente a scapito di una 'bella routine'.


 Sono daccordo.
Sto controllando la routine che hai postato, e non sono piu' daccordo sulla
'bellezza' e la 'pulizia' del codice, naturalmente secondo i miei canoni!
Per quanto riguarda 'la chicca', non ho ancora controllato'


Per quanto riguarda 'la chicca', non ho ancora controllato'
nemmeno io sono d'accordo... č un po' come fanno
molti programmatori C++... per amore di concisione
scrivono programmi criptici e incomprensibili
forse anche a loro stessi...
Non voglio lanciare sassi o fare crociate, ma
sinceramente preferisco un codice chiaro
anche se piů esteso.
Micio

 pubblicata che riporto di seguito.
Ma perchè? C'è già sul sito, è appena stata pubblicata da... non ricordo
chi, e tu devi di nuovo pubblicarla? Questa è tutta roba inutile che mi
tocca scaricare. Non sono arrabbiato e non voglio sembrare maleducato, però,
a mio avviso, certe norme (non voglio chiamarle regole) potrebbero essere
seguite.

 "eleganza"; quindi parliamo anche di modi di programmare.
Mi spiace, non faccio mai di queste polemiche, ma se vuoi discutere di questo
argomento, bene, parliamone.
Non mi reputo un programmatore, ma secondo i _miei criteri_ la tua routine non
e' 'bella' perche':
- non tutte le variabili sono dichiarate
- i nomi delle variabili non identificano ne il tipo di dato ne il contenuto,
questo a scapito della leggibilita' del codice
- presuppone un controllo a monte per la validita' del valore in input
- non esegue il controllo sulla validita' del CF, ma calcola solo il carattere
di controllo
- inoltre avendo usato una sub e dichiarato ByRef (implicitamente) l'input, per
valutare l'output e quindi la validita' del CF hai bisogno di scrivere altro
codice a valle
- per valutare se un numero e' pari ti basta controllare che il resto della
divisione per due sia zero, inoltre la variabile 'pari' e' superflua:
...
    ch = Asc(Mid(ok, i, 1))
    v = ch + 65 * (ch > 64 And ch < 91) + 48 * (ch > 47 And ch < 58)
    If i Mod 2 = 0 Then tot = tot + v Else tot = tot + d(v)
...
risparmiando cosi' una operazione, una istruzione If ed l'assegnazione di una
variabile.
- l'uso di Redim e' errato in quanto la matrice non deve essere ridimensionata,
ma solo dimensionata
Per quanto riguarda la 'chicca', ad una prima valutazione sembra funzionare
correttamente, quindi nulla da obiettare.


 Federico
Bene, fammi sapere: ci tengo e ti ringrazio sin da ora. Mi piace migliorare!
--
Cordiali saluti
Nunzio Santini


Perdonami, ne avrei fatto a meno di ripubblicarla... diciamo che è stato un
eccesso di zelo per evitare a chi leggeva di saltare da un post all'altro.
 Ciao da Nunzio Santini

 ma solo dimensionata
Giusto!
Bene, sarebbe interessante discutere dei particolare per mille altre
occasioni, d'altronde il NG dovrebbe avere anche un valore formativo. Grazie
per la discussione e se hai da aggiungere altro..... ben disponibile
