Oggi ho dovuto scrivere un modulo per la compilazione e la stampa automatica di assegni, nulla di che, uno di quei compiti poco stimolanti che si svolgono col cervello in standby e lo sguardo perso nel nulla. E poi odio avere a che fare con le stampanti, forse perchè tutte le stampanti che ho avuto mi hanno puntualmente abbandonato il giorno prima della consegna di qualche tesina. Ad essere sincero però, devo ammettere che cinque minuti di piacere me li sono ritagliati, ed è stato quando ho dovuto scrivere una funzione che mi permettesse di esprimere l'importo dell'assegno in lettere. Un momento di piacere che definirei dal sapore nostalgico! Non so perchè, ma mentre scrivevo la funzione mi sono venuti in mente i primi anni dell'università, quando studiavo Pascal e implementavo il BubbleSort piuttosto che la Torre di Hanoi o robe del genere. A volte il cervello fa collegamenti strani, forse dovrei smettere di bere caffè..
Public Class bcc_NumeriInLettere
Private mTabella1() As String = {"uno", _
"due", _
"tre", _
"quattro", _
"cinque", _
"sei", _
"sette", _
"otto", _
"nove", _
"dieci", _
"undici", _
"dodici", _
"tredici", _
"quattordici", _
"quindici", _
"sedici", _
"diciassette", _
"diciotto", _
"diciannove"}
Private mTabella2() As String = {"venti", _
"trenta", _
"quaranta", _
"cinquanta", _
"sessanta", _
"settanta", _
"ottanta", _
"novanta"}
Private Function m_FiniscePerVocale(ByVal tmp As String) As Boolean
Return tmp.EndsWith("a") Or _
tmp.EndsWith("e") Or _
tmp.EndsWith("i") Or _
tmp.EndsWith("o") Or _
tmp.EndsWith("u")
End Function
Private Function m_IniziaPerVocale(ByVal tmp As String) As Boolean
Return tmp.StartsWith("a") Or _
tmp.StartsWith("e") Or _
tmp.StartsWith("i") Or _
tmp.StartsWith("o") Or _
tmp.StartsWith("u")
End Function
Private Function m_da1a999(ByVal strval As String) As String
Dim l As Int16 = strval.Length
Dim i, j, k As Int16
Dim tmp, dec, uni As String
Dim c As String
tmp = ""
j = 0
For i = l To 1 Step -1
c = strval.Chars(j)
j = j + 1
If c <> "0" Then
Select Case i
Case 3
If c = "1" Then
tmp &= "cento"
Else
k = CInt(c) - 1
tmp &= mTabella1(k) & "cento"
End If
Case 2
' controlla se è un numero conosciuto
k = CInt(c & strval.Chars(j))
If k < color="blue">Then
tmp &= mTabella1(k - 1)
ElseIf (k Mod 10) = 0 Then
' venti, trenta, quaranta...
tmp &= mTabella2((k / 10) - 2)
Else
' ventuno, ventidue, ventitre..
k -= k Mod 10
k = (k / 10) - 2
dec = mTabella2(k)
k = CInt(strval.Chars(j).ToString) - 1
uni = mTabella1(k)
If m_FiniscePerVocale(dec) And m_IniziaPerVocale(uni) Then
' per esempio ventuno, ventotto
' tronchiamo venti a vent e concateniamo uno, otto..
dec = dec.SubString(0, dec.Length - 1)
End If
tmp &= dec & uni
End If
Return tmp
Case 1
' basta tradurre l'unita
k = CInt(c) - 1
tmp &= mTabella1(k)
End Select
End If
Next
Return tmp
End Function
Public Function NumeriInLettere(ByVal strval As String) As String
Dim part1 As String
Dim part2 As String
Dim tmp As String
Dim rv As String
Dimlen As Int16
Dim i As Int16
part1 = strval
part2 = ""
tmp = ""
rv = ""
i = strval.IndexOf(",")
If i <> -1 Then
part1 = strval.SubString(0, i)
part2 = strval.SubString(i + 1)
End If
While True
len = part1.Length
If len > 12 Then
' ci fermiamo solo ai miliardi..
Return "numero troppo grande"
ElseIf (12 >= len) And (len > 9) Then
' miliardi
i = len - 9
tmp = part1.SubString(0, i)
part1 = part1.SubString(i)
tmp = m_da1a999(tmp)
rv = IIf(tmp = "uno", "unmiliardo", tmp & "miliardi")
ElseIf (9 >= len) And (len > 6) Then
' milioni
i = len - 6
tmp = part1.SubString(0, i)
part1 = part1.SubString(i)
tmp = m_da1a999(tmp)
rv &= IIf(tmp = "uno", "unmilione", tmp & "milioni")
ElseIf (6 >= len) And (len > 3) Then
i = len - 3
tmp = part1.SubString(0, i)
part1 = part1.SubString(i)
tmp = m_da1a999(tmp)
rv &= IIf(tmp = "uno", "mille", tmp & "mila")
Else
tmp = m_da1a999(part1)
rv &= tmp & "/" & IIf(part2 <> "", part2, "00")
Return rv
End If
End While
End Function
End Class
1 commento:
imparato molto
Posta un commento