Numeri Per Lettere FUNZIONE

di il
11 risposte

Numeri Per Lettere FUNZIONE

Buongiorno,
attualmente uso questa funzione IN MODULI per convertire i numeri in lettere:
Option Compare Database
Option Explicit

'///////////////////////////////////////////////////////////////////////////////
'//                                                                           //
'// PROJECT     :                                                             //
'// FILE        : cur2str.bas                                                 //
'// VERSION     : 1.0.0                                                       //
'// CREATED     : 01/09/1998  BY : Roal Zanazzi                               //
'// LAST MODIF. : 18/12/1998  BY : Alessandro Scardova                        //
'// LANGUAGE    : Visual Basic 6.0                                            //
'// ENVIRONMENT : Windows 95/NT 4.0                                           //
'// DESCRIPTION : LongCur2Str() function converts a Currency variant into its //
'//   textual representation (i.e. 1234 -> OneThousandTwoHundredThirtyFour).  //
'//   The resulting text can be in any of the supported languages:            //
'//   Italian, English, French, German.
'//   EuroCheques() Function Allow to make a cheque in Euro Currency.
'//                                                                           //
'// Copyright © 1998 Roal Zanazzi <zrs@iol.it>                                //
'///////////////////////////////////////////////////////////////////////////////

'Adattato per MSAccess97 da Federico Luciani
Const langItalian = 1
Const langEnglish = 2
Const langFrench = 3
Const langGerman = 4

Private Function LongCur2Str(ByVal cValue As Currency, ByRef sCaseValue As String, Optional ByVal Language As Byte) As Long
    Const MAXLEN = 12 'DON'T CHANGE!
    Dim StartValue As String, _
        strValue As String, _
        strResult As String
    Dim n100 As Integer ' x00
    Dim n10 As Integer  ' 0x0
    Dim n1 As Integer   ' 00x
    Dim i As Integer ' Counter in For..Next loop.

    Dim sNumberStrings As Variant

    If IsEmpty(Language) Then Language = langItalian
    
    Select Case Language
        Case langItalian
            sNumberStrings = Array _
            ("zero", "uno", "due", "tre", "quattro", "cinque", "sei", "sette", "otto", "nove", _
            "dieci", "undici", "dodici", "tredici", "quattordici", "quindici", "sedici", "diciassette", "diciotto", "diciannove", _
            "venti", "trenta", "quaranta", "cinquanta", "sessanta", "settanta", "ottanta", "novanta", _
            "cento", "duecento", "trecento", "quattrocento", "cinquecento", "seicento", "settecento", "ottocento", "novecento", _
            "mille", "mila", "unmilione", "milioni", "unmiliardo", "miliardi", "** Valore non calcolabile **")
        Case langEnglish
            sNumberStrings = Array _
            ("Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", _
            "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen", _
            "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety", _
            "Onehundred", "Twohundred", "Threehundred", "Fourhundred", "Fivehundred", "Sixhundred", "Sevenhundred", "Eighthundred", "Ninehundred", _
            "Onethousand", "Thousand", "OneMillion", "Millions", "OneBillion", "Billions", "** Value not calculable **")
        Case langFrench
            sNumberStrings = Array _
            ("Zero", "Un", "Deux", "Trois", "Quatre", "Cinq", "Six", "Sept", "Huit", "Neuf", _
            "Dix", "Onze", "Douze", "Treize", "Quatorze", "Quinze", "Seize", "Dixsept", "Dixhuit", "Dixneuf", _
            "Vingt", "Trente", "Quarante", "Cinquante", "Soixante", "Soixantedix", "Quatrevingts", "Quatrevingtdix", _
            "Cent", "Deuxcents", "Troiscents", "Quatrecents", "Cinqcents", "Sixcents", "Septcents", "Huitcents", "Neufcents", _
            "Mille", "Mille", "UnMillion", "Million", "UnMilliard", "Milliard", "** Valeur pas calculable **")
        Case langGerman
            sNumberStrings = Array _
            ("Null", "Ein", "Zwei", "Drei", "Vier", "Fünf", "Sechs", "Sieben", "Acht", "Neun", _
            "Zehn", "Elf", "Zwölf", "Dreizehn", "Vierzehn", "Fünfzehn", "Sechzehn", "Siebzehn", "Achtzehn", "Neunzehn", _
            "Zwanzig", "Dreißig", "Vierzig", "Fünfzig", "Sechzig", "Siebzig", "Achtzig", "Neunzig", _
            "Hundert", "Zweihundert", "Dreihundert", "Vierhundert", "Fünfhundert", "Sechshundert", "Siebenhundert", "Achthundert", "Neunhundert", _
            "Tausend", "Tausend", "EineMillion", "Millionen", "EineMilliarde", "Milliarden", "** Unberechenbarer Wert **")
    End Select
    
    ' Controlli iniziali
    ' (gestisce fino a 999.999.999.999)
    
    If cValue > 999999999999# Then
        sCaseValue = sNumberStrings(43)
        LongCur2Str = 1 'OwerflowError
        Exit Function
    End If
    
    If cValue = 0 Then
        sCaseValue = sNumberStrings(0)
        LongCur2Str = 0
        Exit Function
    End If

    StartValue = Format(cValue, String(MAXLEN, "0"))
    strResult = ""

    ' Inizio conversione
    For i = 1 To (MAXLEN \ 3)
        strValue = Mid$(StartValue, i * 3 - 2, 3)

        n100 = Val(Mid$(strValue, 1, 1))
        n10 = Val(Mid$(strValue, 2, 1))
        n1 = Val(Mid$(strValue, 3, 1))
        
        ' ----- Centinaia
        If (n100 > 0) Then strResult = strResult & sNumberStrings(n100 + 27)
        ' ----- Decine e Unita'
        ' Tratta in modo differente i numeri [1..9], [10..19], [20..99].
        If (n10 = 0) Then '[1..9]
            If (n1 > 0) Then strResult = strResult & sNumberStrings(n1)
        ElseIf (n10 = 1) Then '[10..19]
            strResult = strResult & sNumberStrings(10 + n1)
        Else 'If (n10 > 1) Then '[20..99]
            If ((Language = langGerman) And (n1 <> 0)) Then
                ' TEDESCO: un numero compreso tra 21 e 99 non terminante con
                ' 0, si scrive prima il numero che indica le unità, poi "und" ("e" in
                ' tedesco) e poi il numero che indica le decine, tutto attaccato
                strResult = strResult & sNumberStrings(n1) & "Und" & sNumberStrings(n10 + 18)
            Else
                strResult = strResult & sNumberStrings(n10 + 18)
                ' ITALIANO: correzione per decine con unita' = 1 o 8;
                ' troncamento dell'ultima vocale delle decine: VentiUno -> VentUno
                If (Language = langItalian) Then
                    If ((n1 = 1) Or (n1 = 8)) Then strResult = Left(strResult, Len(strResult) - 1)
                End If
                ' ----- Unita' (solo se le decine<>10)
                If ((n1 > 0) And (n10 <> 1)) Then strResult = strResult & sNumberStrings(n1)
            End If
        End If
        ' Ultimi aggiustamenti
        ' Aggiunge Miliardi, Milioni e Mila (oppure 1Miliardo, 1Milione, Mille).
        If (i < 4) Then
            If (strValue = "001") Then ' 1000
                strResult = Left(strResult, Len(strResult) - Len(sNumberStrings(1)))
                strResult = strResult & sNumberStrings(44 - (i * 2) - 1)
            ElseIf (strValue <> "000") Then ' x000
                strResult = strResult & sNumberStrings(44 - (i * 2))
            End If
        End If
    Next

    ' TEDESCO: se l'ultima cifra e' 1, si scrive Eins, non Ein.
    If (Language = langGerman) Then
        If (Right(strResult, 3) = sNumberStrings(1)) Then strResult = strResult & "s"
    End If

    sCaseValue = strResult
    LongCur2Str = 0
End Function

Public Function EuroCheque(ByVal vValue As Variant, ByRef sNumberValue As String, ByRef sCaseValue As String, Optional ByVal Language As Byte) As Long
    On Error GoTo EuroChequeError
    Dim sTempCaseValue As String
    
    'Controlli su vValue
    If IsNull(vValue) Then GoTo EuroChequeError
    If vValue = vbNullString Then GoTo EuroChequeError
    If Not IsNumeric(vValue) Then GoTo EuroChequeError
    If LongCur2Str(CCur(Int(vValue)), sTempCaseValue, Language) Then GoTo EuroChequeError
    sCaseValue = StrConv(sTempCaseValue & "/" & Right$(Format$(vValue, ".00"), 2), vbProperCase)
    
    sNumberValue = Format$(vValue, "#,##0.00")
    Exit Function
    
EuroChequeError:
    sNumberValue = "Error"
    sCaseValue = "Error"
    EuroCheque = 1
End Function

Public Function Converti(Valore As Variant)
    Dim Risu As String
    ' Si deve separare la parte intera da quella decimale ed usiamo le funzioni matematiche
    Dim p_intera As Integer
    Dim p_decimale As Integer
    ' prelievo della parte intera
    p_intera = Fix(Valore)
    ' prelievo delle due cifre decimali con approssimazione.
    p_decimale = Fix(((Valore - p_intera) * 100) + 0.5)
    ' Composizione del risultato
    LongCur2Str p_intera, Risu, langItalian
    ' Parte dei decimali
    If p_decimale > 0 Then
        Converti = Risu & "/" & Format(CStr(p_decimale), "00")
    Else
        Converti = Risu & "/00"
    End If
    
End Function

Non capisco come mai superata la cifra di 32.800,00 euro mi da errore RUNTIME 6 OverFLOW nella riga:
p_intera = Fix(Valore)
Se invece cerco di convertire la cifra di 32.750,00 me la converte senza problemi.

Avete suggerimenti?

11 Risposte

  • Re: Numeri Per Lettere FUNZIONE

    alessandro.vitale ha scritto:


    ...
    Private Function LongCur2Str(ByVal cValue As Currency, ByRef sCaseValue As String, Optional ByVal Language As Byte) As Long
    Sono pigro più che mai, come usi la funzione? a cosa serve il parametro sCaseValue?
  • Re: Numeri Per Lettere FUNZIONE

    La funzione la uso in un report per convertirmi le cifre in lettere.
    ScaseValue la uso per identificare il numero(stringa)
  • Re: Numeri Per Lettere FUNZIONE

    alessandro.vitale ha scritto:


    La funzione la uso in un report per convertirmi le cifre in lettere.
    Ok, ma concretamente cosa scrivi?

    alessandro.vitale ha scritto:


    ScaseValue la uso per identificare il numero(stringa)
    So quello che sapevo prima. Cosa va a finirci in sCaseValue?
  • Re: Numeri Per Lettere FUNZIONE

    Ok Concretamente scrivo es: 1.250,05 € mi scrive milleduecentocinquanta/05
    Cosa ci va a finire non saprei...non l'ho creata io questa funzione l'ho presa da internet e non la comprendo in toto.
  • Re: Numeri Per Lettere FUNZIONE

    alessandro.vitale ha scritto:


    Ok Concretamente scrivo es: 1.250,05 € mi scrive milleduecentocinquanta/05
    Considerato che nelle 2 o 3 prove che ho fatto nel frattempo a me non ha dato alcun problema per cifre ben oltre i 32.750 (che ricorda tanto range da -32,768 a 32,767 supportato dal tipo Integer, ma che non è quello, evidentemente), da qualche parte avrai pur chiamato quella funzione: nell'origine di un controllo, in un evento. Ecco, cosa hai scritto in quella chiamata?
    Perché, ripeto, con i miei tentativi non ho avuto alcun problema. Li ho fatti dalla finestra immediata con una funzione creata da me che chiamava EuroCheque, per potergli passare i parametri che voleva e vederli stampati con debug.print ma non vedo motivi perché vada ko.
  • Re: Numeri Per Lettere FUNZIONE

    La funzione Converti la richiamo (in origine controllo) in un report che mi converte la voce costo1 da numeri a lettere.
    Per la precisione ho scritto in origine controllo =Converti([costo1])
  • Re: Numeri Per Lettere FUNZIONE

    La risposta è banale... un rupe integer supporta al massimo 32768 quindi devi convertire la variabile in Long.

    Federico Luciani è stato uno dei fondatori del SitoComume... anni 90... bei tempi.
  • Re: Numeri Per Lettere FUNZIONE

    @Alex ha scritto:


    La risposta è banale... un rupe integer supporta al massimo 32768 quindi devi convertire la variabile in Long.

    Federico Luciani è stato uno dei fondatori del SitoComume... anni 90... bei tempi.
    Come si fa? da quello che ho capito devo usare CLng ma non saprei dove e cosa metterci dentro
  • Re: Numeri Per Lettere FUNZIONE

    Non sparare a caso.... se ti dico che la variabile deve essere cambiata in LONG non ti sto dicendo che devi convertire in long un valore da assegnare alla variabile che è dichiarata INTEGER...

    Questa è come viene dichiarata... nella finzione Convertì. [Code] Dim p_intera As Integer La devi dichiarare Long.
  • Re: Numeri Per Lettere FUNZIONE

    Ho fatto così. Prima che tu rispondessi (e ti ringrazio) ho fatto trova e sostituisci tutte le parola INTEGER con LONG quindi mi ha messo long anche in
    Dim n100 As Integer ' x00
        Dim n10 As Integer  ' 0x0
        Dim n1 As Integer   ' 00x
        Dim i As Integer ' Counter in For..Next loop.
    e in
     Dim p_intera As Integer
        Dim p_decimale As Integer
    
    Va bene oppure devo modificare solo quanto tu mi hai detto e cioè la sola stringa
    Dim p_intera As Integer
    ?
  • Re: Numeri Per Lettere FUNZIONE

    Vedi che continui a fare le cose a caso senza minimamente ragionare...
    Perché hai fatto la sostituzione di tutto...?
    Serve sostituire solo quello che serve... avevi detto.che il problema era la variabile specifica...
    Non si può affrontare codice Copiaincollando senza avere minimamente idea di cosa faccia.

    Vedi tu...
Devi accedere o registrarti per scrivere nel forum
11 risposte