'__________________________________________________
'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
'Da_lettere_a_numeri è una funzione anche UDF che
'effettua la conversione di un numero scritto in
'lettere nel relativo numero scritto in cifre.
'
'L'argomento sNumero è la stringa che deve essere
'convertita per es. passando "duemilanove" la
'funzione restituisce 2009.
'
'Utilizza la function Da_uno_a_mille che converte
'stringhe che vanno da "uno" a "mille" nei relativi
'numeri in cifre (accetta 108 nelle due forme
'centotto centootto)
'
'E' possibile convertire qualunque stringa che
'utilizza fino ai miliardi di miliardi, sarebbe
'facile conprendere bilioni, trilioni etc.
'
'Su che valori ho testato la funzione:
'- tutti i valori da 0 a 100.000 step 1
'- valori da 100.000 fino a 999.999.999 con
' step random da 1 a 10.000
'- valori superiori 999.999.999 solo alcune
' prove manuali (non ho trovato infatti funzioni
' che restituiscano il testo con numeri così
' grandi - p.s. magari ne scriverò una
'
'Viene eseguito un controllo ortografico, la
'funzione restituisce "#VALORE!" qualora un numero
'venga scritto con errori di digitazione.
'es.1 Millle -> "#VALORE!"
'es.2 CentoMille -> 1100
'Il codice utilizza le RegExp e un oggetto
'Dictionary ma non necessita di riferimenti alle
'librerie di VBScript e Scripting
'
'Il codice è commentato per spiegarne il
'funzionamento
'__________________________________________________
'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯/
' INIZIO DEL CODICE /
' DA INCOLLARE IN UN MODULO STANDARD /
'______________________________________________/
'
Option Explicit
'
Function Da_lettere_a_numeri( _
ByVal sNumero As String)
'______________________________________________
'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
'Di Roberto Mensa nick r
'______________________________________________
'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Dim RE As Object
Dim v, l As Long
'
'setto l'espressione regolare
'
Set RE = CreateObject("VBScript.RegExp")
'
'converto il numero in caratteri minuscoli
'
sNumero = LCase(sNumero)
'
'se sNumero è zero esco
'
If sNumero = "zero" Then
Da_lettere_a_numeri = 0
Exit Function
End If
'
'Imposto la ricerca su tutte le occorrenze
'
RE.Global = True
'--> inizio la sostituzione di mila, milioni,
' di milioni, miliardi, di miliardi
'
'imposto il pattern di ricerca
'
RE.Pattern = "mila"
'
'verifico se c'è almeno una occorrenza
'a occorrenza trovata effettuo la
'sostituzione
'
If RE.test(sNumero) Then _
sNumero = RE.Replace(sNumero, "*1000")
RE.Pattern = "milioni| di milioni"
If RE.test(sNumero) Then _
sNumero = RE.Replace(sNumero, _
"*1000000")
RE.Pattern = "miliardi| di miliardi"
If RE.test(sNumero) Then _
sNumero = RE.Replace(sNumero, _
"*1000000000")
'___fine della sostituzione <--
'
'tutte le parole rimaste vengono passate alla
'funzione Da_uno_a_mille, le parole saranno
'delimitate da numeri ecco la stringa di
'esempio a questo livello della funzione:
'sNumero = "duemilanove" -> "due*1000nove"
'se questa restituisce 0 (zero) siamo in
'presenza di un errore e la funzione
'restituisce #VALORE!
'
RE.Pattern = _
"mille|unmilione|unmiliardo|[a-z]+"
If RE.test(sNumero) Then
For Each v In RE.Execute(sNumero)
l = Da_uno_a_mille(CStr(v))
If l = 0 Then
Da_lettere_a_numeri = "#VALORE!"
Exit Function
Else
sNumero = _
VBA.Replace(sNumero, v, _
"+" & l, , 1)
End If
Next
Else
Da_lettere_a_numeri = "#VALORE!"
Exit Function
End If
'
'utilizza la funzione di excel evaluate per
'ottenere il risultato della stringa che avrà
'un formato per esempio:
'sNumero = "duemilanove" -> "2*1000+9"
'
Da_lettere_a_numeri = _
Excel.Application.Evaluate(sNumero)
End Function
Function Da_uno_a_mille( _
ByVal sNumero As String) As Long
'______________________________________________
'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
'Di Roberto Mensa nick r
'______________________________________________
'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Dim RE As Object
Dim Dic As Object
Dim s(1 To 8) As String
Dim sArr() As String
Dim i As Long, l(3) As Long
'
'setto l'espressione regolare e l'oggetto dic
'
Set Dic = CreateObject("Scripting.Dictionary")
Set RE = CreateObject("VBScript.RegExp")
'
'imposto le stringhe di pattern che verranno
'anche utilizare per il caricamento del
'dizionario
'
s(1) = "due|tre|quattro|cinque|sei|sette|" & _
"otto|nove"
s(2) = "undici|dodici|tredici|quattordici" & _
"|quindici|sedici|diciassette|dici" & _
"otto|diciannove"
s(3) = "venti|trenta|quaranta|cinquanta|s" & _
"essanta|settanta|ottanta|novanta"
s(4) = "ventuno|trentuno|quarantuno|cinqu" & _
"antuno|sessantuno|settantuno|otta" & _
"ntuno|novantuno"
s(5) = "ventotto|trentotto|quarantotto|ci" & _
"nquantotto|sessantotto|settantott" & _
"o|ottantotto|novantotto|centotto"
s(6) = "uno|dieci|cento|mille"
s(7) = "unmilione"
s(8) = "unmiliardo"
'
'--> inizio il caricamento delle voci con
' i relativi valori
'
Dic.Add s(7), 1000000
Dic.Add s(8), 1000000000
sArr = Split(s(1), "|")
For i = 0 To UBound(sArr)
Dic.Add sArr(i), i + 2
Next
sArr = Split(s(2), "|")
For i = 0 To UBound(sArr)
Dic.Add sArr(i), i + 11
Next
sArr = Split(s(3), "|")
For i = 0 To UBound(sArr)
Dic.Add sArr(i), (i + 2) * 10
Next
sArr = Split(s(4), "|")
For i = 0 To UBound(sArr)
Dic.Add sArr(i), (i + 2) * 10 + 1
Next
sArr = Split(s(5), "|")
For i = 0 To UBound(sArr)
Dic.Add sArr(i), (i + 2) * 10 + 8
Next
sArr = Split(s(6), "|")
For i = 0 To UBound(sArr)
Dic.Add sArr(i), 10 ^ i
Next
'
' Il dizionario è stato caricato <---
'
'Imposto la ricerca su tutte le occorrenze
'
RE.Global = True
'
'Quello che segue effettua anche un controllo
'sulla ortografia della stringa passata, in quanto
'scompone sNumero e verifica che ogni parola sia
'presente nel dizionario
'
'Prima controllo le stringhe composte da parola
'singola es. due, tredici, ventuno, trentotto
'
RE.Pattern = "^(" & _
s(1) & "|" & _
s(2) & "|" & _
s(3) & "|" & _
s(4) & "|" & _
s(5) & "|" & _
s(6) & "|" & _
s(7) & "|" & _
s(8) & ")$"
If RE.test(sNumero) Then
Da_uno_a_mille = Dic.Item(sNumero)
Exit Function
End If
'
'Poi controllo le stringhe composte da una o due
'parole es. quaranta, quarantatre fino a 99
'
RE.Pattern = "^(" & _
s(2) & "|" & _
s(3) & "|" & _
s(4) & "|" & _
s(5) & "|" & _
s(6) & "|" & _
s(7) & "|" & _
s(8) & ")(" & _
s(1) & _
")?$"
'
'se la ricerca che viene fatta sull'intera stringa
'ha esito positivo sostituisco le parole recuperandole
'dal dizionario
'
If RE.test(sNumero) Then
Da_uno_a_mille = _
CLng(Dic.Item(RE.Replace(sNumero, "$1"))) + _
CLng(Dic.Item(RE.Replace(sNumero, "$2")))
Exit Function
End If
'
'Terzo controllo su stringhe composte da una due
'o tre parole che cominciano con cento es. centodue,
'centoquarantadue, centoquaranta da 100 a 199
'
RE.Pattern = "^(cento)(" & _
s(2) & "|" & _
s(3) & "|" & _
s(4) & "|" & _
s(5) & "|" & _
s(6) & "|" & _
s(7) & "|" & _
s(8) & ")?(" & _
s(1) & _
")?$"
If RE.test(sNumero) Then
Da_uno_a_mille = _
CLng(Dic.Item(RE.Replace(sNumero, "$1"))) + _
CLng(Dic.Item(RE.Replace(sNumero, "$2"))) + _
CLng(Dic.Item(RE.Replace(sNumero, "$3")))
Exit Function
End If
'
'Ultimo controllo su stringhe composte da una due tre
'o quattro parole che cominciano con un numero da 2 a 9
'seguito da cento e opzionalmente da altre parole
'es. duecentodue duecentoquarantadue, duecentoquaranta
'da 200 a 999
'
RE.Pattern = "^(" & _
s(1) & ")(cento)(" & _
s(2) & "|" & _
s(3) & "|" & _
s(4) & "|" & _
s(5) & "|" & _
s(6) & "|" & _
s(7) & "|" & _
s(8) & ")?(" & _
s(1) & _
")?$"
If RE.test(sNumero) Then
Da_uno_a_mille = _
CLng(Dic.Item(RE.Replace(sNumero, "$1"))) * _
CLng(Dic.Item(RE.Replace(sNumero, "$2"))) + _
CLng(Dic.Item(RE.Replace(sNumero, "$3"))) + _
CLng(Dic.Item(RE.Replace(sNumero, "$4")))
Exit Function
End If
End Function
'
'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
' FINE DEL CODICE
'________________________________________________
'
'implementata per accettare anche bilioni, trilioni
'etc...
'_________________________________________________
'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
' INIZIO DEL CODICE
' DA INCOLLARE IN UN MODULO STANDARD
'______________________________________________
'
'
Function Da_lettere_a_numeri_G20( _
ByVal sNumero As String)
'______________________________________________
'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
'Di Roberto Mensa nick r
'______________________________________________
'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Dim RE As Object
Dim v, l
'
'setto l'espressione regolare
'
Set RE = CreateObject("VBScript.RegExp")
'
'converto il numero in caratteri minuscoli
'
sNumero = LCase(sNumero)
'
'se sNumero è zero esco
'
If sNumero = "zero" Then
Da_lettere_a_numeri_G20 = 0
Exit Function
End If
'
'Imposto la ricerca su tutte le occorrenze
'
RE.Global = True
'--> inizio la sostituzione di mila, milioni,
' di milioni, miliardi, di miliardi
'
'imposto il pattern di ricerca
'
RE.Pattern = "mila"
'
'verifico se c'è almeno una occorrenza
'a occorrenza trovata effettuo la
'sostituzione
'
If RE.test(sNumero) Then _
sNumero = RE.Replace(sNumero, "*1000")
RE.Pattern = "milioni| di milioni"
If RE.test(sNumero) Then _
sNumero = RE.Replace(sNumero, _
"*1000000")
RE.Pattern = "miliardi| di miliardi"
If RE.test(sNumero) Then _
sNumero = RE.Replace(sNumero, _
"*1000000000")
RE.Pattern = "bilioni| di bilioni"
If RE.test(sNumero) Then _
sNumero = RE.Replace(sNumero, _
"*1000000000000")
RE.Pattern = "biliardi| di biliardi"
If RE.test(sNumero) Then _
sNumero = RE.Replace(sNumero, _
"*1000000000000000")
RE.Pattern = "trilioni| di trilioni"
If RE.test(sNumero) Then _
sNumero = RE.Replace(sNumero, _
"*1000000000000000000")
RE.Pattern = "triliardi| di triliardi"
If RE.test(sNumero) Then _
sNumero = RE.Replace(sNumero, _
"*1000000000000000000000")
'___fine della sostituzione <--
'
'tutte le parole rimaste vengono passate alla
'funzione Da_uno_a_mille_G20, le parole saranno
'delimitate da numeri ecco la stringa di
'esempio a questo livello della funzione:
'sNumero = "duemilanove" -> "due*1000nove"
'se questa restituisce 0 (zero) siamo in
'presenza di un errore e la funzione
'restituisce #VALORE!
'
RE.Pattern = _
"mille|unmilione|unmiliardo|unbilione|" & _
"unbiliardo|untrilione|untriliardo|[a-z]+"
If RE.test(sNumero) Then
For Each v In RE.Execute(sNumero)
l = Da_uno_a_mille_G20(CStr(v))
If l = 0 Then
Da_lettere_a_numeri_G20 = "#VALORE!"
Exit Function
Else
sNumero = _
VBA.Replace(sNumero, v, _
"+" & l, , 1)
End If
Next
Else
Da_lettere_a_numeri_G20 = "#VALORE!"
Exit Function
End If
'
'utilizza la funzione di excel evaluate per
'ottenere il risultato della stringa che avrà
'un formato per esempio:
'sNumero = "duemilanove" -> "2*1000+9"
'
Da_lettere_a_numeri_G20 = _
Excel.Application.Evaluate(sNumero)
End Function
Function Da_uno_a_mille_G20( _
ByVal sNumero As String) As Double
'______________________________________________
'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
'Di Roberto Mensa nick r
'______________________________________________
'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Dim RE As Object
Dim Dic As Object
Dim s(1 To 8) As String
Dim sArr() As String
Dim i As Long, l(3) As Long
'
'setto l'espressione regolare e l'oggetto dic
'
Set Dic = CreateObject("Scripting.Dictionary")
Set RE = CreateObject("VBScript.RegExp")
'
'imposto le stringhe di pattern che verranno
'anche utilizare per il caricamento del
'dizionario
'
s(1) = "due|tre|quattro|cinque|sei|sette|" & _
"otto|nove"
s(2) = "undici|dodici|tredici|quattordici" & _
"|quindici|sedici|diciassette|dici" & _
"otto|diciannove"
s(3) = "venti|trenta|quaranta|cinquanta|s" & _
"essanta|settanta|ottanta|novanta"
s(4) = "ventuno|trentuno|quarantuno|cinqu" & _
"antuno|sessantuno|settantuno|otta" & _
"ntuno|novantuno"
s(5) = "ventotto|trentotto|quarantotto|ci" & _
"nquantotto|sessantotto|settantott" & _
"o|ottantotto|novantotto|centotto"
s(6) = "uno|dieci|cento|mille"
s(7) = "unmilione|unbilione|untrilione"
s(8) = "unmiliardo|unbiliardo|untriliardo"
'
'--> inizio il caricamento delle voci con
' i relativi valori
'
sArr = Split(s(7), "|")
For i = 0 To UBound(sArr)
Dic.Add sArr(i), 1000000 * 1000000 ^ i
Next
sArr = Split(s(8), "|")
For i = 0 To UBound(sArr)
Dic.Add sArr(i), 1000000000 * 1000000 ^ i
Next
sArr = Split(s(1), "|")
For i = 0 To UBound(sArr)
Dic.Add sArr(i), i + 2
Next
sArr = Split(s(2), "|")
For i = 0 To UBound(sArr)
Dic.Add sArr(i), i + 11
Next
sArr = Split(s(3), "|")
For i = 0 To UBound(sArr)
Dic.Add sArr(i), (i + 2) * 10
Next
sArr = Split(s(4), "|")
For i = 0 To UBound(sArr)
Dic.Add sArr(i), (i + 2) * 10 + 1
Next
sArr = Split(s(5), "|")
For i = 0 To UBound(sArr)
Dic.Add sArr(i), (i + 2) * 10 + 8
Next
sArr = Split(s(6), "|")
For i = 0 To UBound(sArr)
Dic.Add sArr(i), 10 ^ i
Next
'
' Il dizionario è stato caricato <---
'
'Imposto la ricerca su tutte le occorrenze
'
RE.Global = True
'
'Quello che segue effettua anche un controllo
'sulla ortografia della stringa passata, in quanto
'scompone sNumero e verifica che ogni parola sia
'presente nel dizionario
'
'Prima controllo le stringhe composte da parola
'singola es. due, tredici, ventuno, trentotto
'
RE.Pattern = "^(" & _
s(1) & "|" & _
s(2) & "|" & _
s(3) & "|" & _
s(4) & "|" & _
s(5) & "|" & _
s(6) & "|" & _
s(7) & "|" & _
s(8) & ")$"
If RE.test(sNumero) Then
Da_uno_a_mille_G20 = Dic.Item(sNumero)
Exit Function
End If
'
'Poi controllo le stringhe composte da una o due
'parole es. quaranta, quarantatre fino a 99
'
RE.Pattern = "^(" & _
s(2) & "|" & _
s(3) & "|" & _
s(4) & "|" & _
s(5) & "|" & _
s(6) & "|" & _
s(7) & "|" & _
s(8) & ")(" & _
s(1) & _
")?$"
'
'se la ricerca che viene fatta sull'intera stringa
'ha esito positivo sostituisco le parole recuperandole
'dal dizionario
'
If RE.test(sNumero) Then
Da_uno_a_mille_G20 = _
CLng(Dic.Item(RE.Replace(sNumero, "$1"))) + _
CLng(Dic.Item(RE.Replace(sNumero, "$2")))
Exit Function
End If
'
'Terzo controllo su stringhe composte da una due
'o tre parole che cominciano con cento es. centodue,
'centoquarantadue, centoquaranta da 100 a 199
'
RE.Pattern = "^(cento)(" & _
s(2) & "|" & _
s(3) & "|" & _
s(4) & "|" & _
s(5) & "|" & _
s(6) & "|" & _
s(7) & "|" & _
s(8) & ")?(" & _
s(1) & _
")?$"
If RE.test(sNumero) Then
Da_uno_a_mille_G20 = _
CLng(Dic.Item(RE.Replace(sNumero, "$1"))) + _
CLng(Dic.Item(RE.Replace(sNumero, "$2"))) + _
CLng(Dic.Item(RE.Replace(sNumero, "$3")))
Exit Function
End If
'
'Ultimo controllo su stringhe composte da una due tre
'o quattro parole che cominciano con un numero da 2 a 9
'seguito da cento e opzionalmente da altre parole
'es. duecentodue duecentoquarantadue, duecentoquaranta
'da 200 a 999
'
RE.Pattern = "^(" & _
s(1) & ")(cento)(" & _
s(2) & "|" & _
s(3) & "|" & _
s(4) & "|" & _
s(5) & "|" & _
s(6) & "|" & _
s(7) & "|" & _
s(8) & ")?(" & _
s(1) & _
")?$"
If RE.test(sNumero) Then
Da_uno_a_mille_G20 = _
CLng(Dic.Item(RE.Replace(sNumero, "$1"))) * _
CLng(Dic.Item(RE.Replace(sNumero, "$2"))) + _
CLng(Dic.Item(RE.Replace(sNumero, "$3"))) + _
CLng(Dic.Item(RE.Replace(sNumero, "$4")))
Exit Function
End If
End Function
'
'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
' FINE DEL CODICE
'________________________________________________
' |