Sub Probando()
Dim strCadena As String
strCadena = fALetra(106.5, "") 'Cells(2, 1).Value)
VBA.MsgBox strCadena
End Sub
Public Function fALetra(ByRef dbValor As Double, _
Optional ByRef strMoneda As String = "EURO", _
Optional ByRef strFraccionMoneda As String = "CÉNTIMO", _
Optional ByRef strConcatenador As String = "CON", _
Optional ByRef intDecimales As Integer = 2) As String
Application.Volatile (False)
Dim strSeparadorMiles As String, strSeparadorDecimales As String
Dim strAbsoluto As String, strDecimales As String
Dim lgAbsoluto As Long, dbDecimales As Double
Dim strCadena As String
Dim Cientos As Long, Miles As Long, Millones As Long, MilesMillones As Long
Dim strCadenaBillones As String, strCadenaMilesMillones As String, strCadenaMillones As String, _
strCadenaMiles As String, strCadenaCientos As String, strCadenaDecimales As String
Dim lgMultiplicador As Long
strSeparadorMiles = GetValueCR(15)
strSeparadorDecimales = GetValueCR(14)
If strMoneda = "" Then strMoneda = ""
If VBA.Len(VBA.CStr(dbValor)) = 1 Then 'Caso unidades
lgAbsoluto = VBA.Abs(VBA.Fix(dbValor))
Else
lgAbsoluto = VBA.Abs(VBA.Fix(dbValor))
End If
Cientos = (lgAbsoluto - 1000 * (lgAbsoluto \ 1000))
Miles = (lgAbsoluto - 1000000 * (lgAbsoluto \ 1000000)) \ 1000
Millones = (lgAbsoluto - 1000000000 * (lgAbsoluto \ 1000000000)) \ 1000000
MilesMillones = (lgAbsoluto - Millones * 1000000 - Miles * 1000 - Cientos) \ 1000000000
strCadenaCientos = ConvierteCifra(Cientos)
strCadenaCientos = VBA.IIf(VBA.Right(strCadenaCientos, 2) = "UN" And VBA.UCase(VBA.Right(strMoneda, 1)) = "A", _
strCadenaCientos & "A", strCadenaCientos)
strCadenaCientos = VBA.IIf(VBA.InStr(1, strCadenaCientos, "CIENTOS") > 0 And VBA.UCase(VBA.Right(strMoneda, 1)) = "A", _
VBA.Replace(strCadenaCientos, "CIENTOS", "CIENTAS"), strCadenaCientos)
strCadenaMiles = ConvierteCifra(Miles)
strCadenaMillones = ConvierteCifra(Millones)
strCadenaMilesMillones = ConvierteCifra(MilesMillones)
If VBA.Abs(dbValor) > 999999999999.99 Then
If VBA.Trim(strCadenaBillones) = "UN" Then
strCadena = strCadenaBillones & " BILLóN"
Else
strCadena = strCadenaBillones & " BILLONES"
End If
End If
If VBA.Abs(dbValor) > 999999999.99 Then
strCadena = VBA.IIf(VBA.Trim(strCadenaMilesMillones) = "UN", _
strCadena & " MIL", strCadena & " " & strCadenaMilesMillones & " MIL")
End If
If VBA.Abs(dbValor) > 999999.99 Then
strCadena = VBA.IIf(VBA.Trim(strCadenaMillones) = "UN", _
strCadenaMillones & " MILLÓN", strCadena & " " & strCadenaMillones & " MILLONES")
End If
If VBA.Abs(dbValor) > 999.99 Then
If VBA.Trim(strCadenaMiles) = "UN" Then
strCadena = strCadena & " MIL"
ElseIf VBA.Trim(strCadenaMiles) = "" Then
strCadena = strCadena
Else
strCadena = strCadena & " " & strCadenaMiles & " MIL"
End If
End If
intDecimales = VBA.IIf(intDecimales > 3, 3, intDecimales)
lgMultiplicador = VBA.Val(1 & VBA.String(intDecimales, "0"))
dbDecimales = (VBA.Abs(dbValor) - VBA.Abs(Fix(dbValor))) * lgMultiplicador
If strMoneda <> "" Then
If VBA.Abs(Int(dbValor)) = "0" Then
strCadena = "CERO " & VBA.UCase(strMoneda) & "S"
ElseIf Abs(Int(dbValor)) = "1" Then
strCadena = VBA.IIf(VBA.UCase(VBA.Right(strMoneda, 1)) = "A", "UNA", "UN")
strCadena = strCadena & " " & VBA.UCase(strMoneda)
Else
strCadena = strCadena & " " & strCadenaCientos & " " & VBA.UCase(strMoneda) & "S"
End If
Select Case VBA.Round((dbDecimales), 0)
Case Is = 1 'Una fracción monetaria
strCadena = strCadena & " " & strConcatenador & " " & _
VBA.IIf(VBA.UCase(VBA.Right(strFraccionMoneda, 1)) = "A", "UNA", "UN") & " " & strFraccionMoneda
Case Is > 1 'Hay fracción monetaria
strCadenaDecimales = ConvierteCifra(VBA.Round((dbDecimales), 0))
strCadenaDecimales = VBA.IIf(VBA.Right(strCadenaDecimales, 2) = "UN" And VBA.UCase(VBA.Right(strFraccionMoneda, 1)) = "A", _
strCadenaDecimales & "A", strCadenaDecimales)
strCadenaDecimales = VBA.IIf(VBA.InStr(1, strCadenaDecimales, "CIENTOS") > 0 And VBA.UCase(VBA.Right(strMoneda, 1)) = "A", _
VBA.Replace(strCadenaDecimales, "CIENTOS", "CIENTAS"), strCadenaDecimales)
strCadena = strCadena & " " & strConcatenador & " " & strCadenaDecimales & " " & strFraccionMoneda & "S"
End Select
Else
If Abs(Int(dbValor)) = "0" Then
strCadena = ""
ElseIf Abs(Int(dbValor)) = "1" Then
strCadena = "UNO"
Else
strCadena = strCadena & " " & strCadenaCientos
End If
Select Case VBA.Round((dbDecimales), 0)
Case Is = 1
strCadena = strCadena & " " & strConcatenador & " " & " UNO"
Case Is > 1
strCadenaDecimales = ConvierteCifra(VBA.Round((dbDecimales), 0))
strCadena = strCadena & " " & strConcatenador & " " & strCadenaDecimales
End Select
End If
fALetra = VBA.Trim(strCadena)
If dbValor < 0 Then fALetra = "MENOS " & fALetra
fALetra = VBA.Replace(fALetra, " ", " ")
End Function
Public Function ConvierteCifra(ByVal lgValor As Long) As String
Dim strCentena As String, strDecena As String, strUnidad As String
Dim matrizUnidades As Variant
Dim matrizDecena As Variant
Dim matrizDecenas As Variant
Dim matrizDecenasY As Variant
Dim matrizCentena As Variant
matrizUnidades = Array("", "UN", "DOS", "TRES", "CUATRO", "CINCO", "SEIS", "SIETE", "OCHO", "NUEVE")
matrizDecena = Array("", "ONCE", "DOCE", "TRECE", "CATORCE", "QUINCE", "DIECISEIS", "DIECISIETE", "DIECIOCHO", "DIECINUEVE")
matrizDecenas = Array("", "DIEZ", "VEINTE", "TREINTA", "CUARENTA", "CINCUENTA", "SESENTA", "SETENTA", "OCHENTA", "NOVENTA")
matrizDecenasY = Array("", "", "VEINTI", "TREINTA Y ", "CUARENTA Y ", "CINCUENTA Y ", _
"SESENTA Y ", "SETENTA Y ", "OCHENTA Y ", "NOVENTA Y ")
matrizCentena = Array("", "", "DOSCIENTOS", "TRESCIENTOS", "CUATROCIENTOS", "QUINIENTOS", _
"SEISCIENTOS", "SETECIENTOS", "OCHOCIENTOS", "NOVECIENTOS")
Dim Unidad As Integer, Decena As Integer, Centena As Integer
Centena = lgValor \ 100
Decena = (lgValor - Centena * 100) \ 10
Unidad = (lgValor - Centena * 100 - Decena * 10)
strUnidad = VBA.IIf(Decena <> 1, matrizUnidades(Unidad), matrizDecena(Unidad))
strDecena = VBA.IIf(Decena > 1, matrizDecena(Unidad), strDecena)
strDecena = VBA.IIf(Unidad > 0, matrizDecenasY(Decena), matrizDecenas(Decena))
strCentena = VBA.IIf(Centena = 1, "CIEN", matrizCentena(Centena))
strCentena = VBA.IIf(Centena = 1 And (Decena + Unidad > 0), "CIENTO", matrizCentena(Centena))
ConvierteCifra = strCentena & " " & strDecena & strUnidad
End Function
'En idioma inglés...
Public Function fNumbersToText(ByRef dbValue As Double, _
Optional ByRef strCurrency As String = "EURO", _
Optional ByRef strFractionCurrency As String = "CENTS", _
Optional ByRef strConcatenator As String = "WITH", _
Optional ByRef intDecimals As Integer = 2) As String
Application.Volatile (False)
Dim strSeparatorThousands As String, strSeparatorDecimals As String
Dim strAbsolut As String, strDecimals As String
Dim lgAbsoluto As Long, dbDecimals As Double
Dim strStringText As String
Dim Hundreds As Long, Thousands As Long, Millions As Long, ThousandsMillions As Long
Dim strStringTextBillones As String, strStringTextThousandsMillions As String, strStringTextMillions As String, _
strStringTextThousands As String, strStringTextHundreds As String, strStringTextDecimals As String
Dim lgMultiply As Long
strSeparatorThousands = GetValueCR(15)
strSeparatorDecimals = GetValueCR(14)
If strCurrency = "" Then strCurrency = ""
If VBA.Len(VBA.CStr(dbValue)) = 1 Then 'Unities
lgAbsoluto = VBA.Abs(VBA.Fix(dbValue))
Else
lgAbsoluto = VBA.Abs(VBA.Fix(dbValue))
End If
Hundreds = (lgAbsoluto - 1000 * (lgAbsoluto \ 1000))
Thousands = (lgAbsoluto - 1000000 * (lgAbsoluto \ 1000000)) \ 1000
Millions = (lgAbsoluto - 1000000000 * (lgAbsoluto \ 1000000000)) \ 1000000
ThousandsMillions = (lgAbsoluto - Millions * 1000000 - Thousands * 1000 - Hundreds) \ 1000000000
strStringTextHundreds = fConvertQuantity(Hundreds)
strStringTextThousands = fConvertQuantity(Thousands)
strStringTextMillions = fConvertQuantity(Millions)
strStringTextThousandsMillions = fConvertQuantity(ThousandsMillions)
If VBA.Abs(dbValue) > 999999999999.99 Then
If VBA.Trim(strStringTextBillones) = "UN" Then
strStringText = strStringTextBillones & " BILLION"
Else
strStringText = strStringTextBillones & " BILLIONS"
End If
End If
If VBA.Abs(dbValue) > 999999999.99 Then
strStringText = VBA.IIf(VBA.Trim(strStringTextThousandsMillions) = "ONE", _
strStringText & " THOUSAND", strStringText & " " & strStringTextThousandsMillions & " THOUSANDS")
End If
If VBA.Abs(dbValue) > 999999.99 Then
strStringText = VBA.IIf(VBA.Trim(strStringTextMillions) = "ONE", _
strStringTextMillions & " MILLION", strStringText & " " & strStringTextMillions & " MILLIONS")
End If
If VBA.Abs(dbValue) > 999.99 Then
If VBA.Trim(strStringTextThousands) = "ONE" Then
strStringText = strStringText & " THOUSAND"
ElseIf VBA.Trim(strStringTextThousands) = "" Then
strStringText = strStringText
Else
strStringText = strStringText & " " & strStringTextThousands & " THOUSAND"
End If
End If
intDecimals = VBA.IIf(intDecimals > 3, 3, intDecimals)
lgMultiply = VBA.Val(1 & VBA.String(intDecimals, "0"))
dbDecimals = (VBA.Abs(dbValue) - VBA.Abs(Fix(dbValue))) * lgMultiply
If strCurrency <> "" Then
If VBA.Abs(Int(dbValue)) = "0" Then
strStringText = "ZERO" & " " & VBA.UCase(strCurrency) & "S"
ElseIf Abs(Int(dbValue)) = "1" Then
strStringText = "ONE" & " " & VBA.UCase(strCurrency)
Else
strStringText = strStringText & " " & strStringTextHundreds & " " & VBA.UCase(strCurrency) & "S"
End If
Select Case VBA.Round((dbDecimals), 0)
Case Is = 1 'One monetary fraction
strStringText = strStringText & " " & strConcatenator & " " & "ONE" & " " & strFractionCurrency
Case Is > 1 'There is monetary fraction
strStringTextDecimals = fConvertQuantity(VBA.Round((dbDecimals), 0))
strStringText = strStringText & " " & strConcatenator & " " & strStringTextDecimals & " " & strFractionCurrency & "S"
End Select
Else
If Abs(Int(dbValue)) = "0" Then
strStringText = ""
ElseIf Abs(Int(dbValue)) = "1" Then
strStringText = "ONE"
Else
strStringText = strStringText & " " & strStringTextHundreds
End If
Select Case VBA.Round((dbDecimals), 0)
Case Is = 1
strStringText = strStringText & " " & strConcatenator & " " & " ONE"
Case Is > 1
strStringTextDecimals = fConvertQuantity(VBA.Round((dbDecimals), 0))
strStringText = strStringText & " " & strConcatenator & " " & strStringTextDecimals
End Select
End If
fNumbersToText = VBA.Trim(strStringText)
If dbValue < 0 Then fNumbersToText = "MINUS " & fNumbersToText
fNumbersToText = VBA.Replace(fNumbersToText, " ", " ")
End Function
Public Function fConvertQuantity(ByVal lgValue As Long) As String
Dim strHundreds As String, strTens As String, strUnity As String
Dim matrizUnityes As Variant
Dim matrizTens As Variant
Dim matrizTenss As Variant
Dim matrizTenssY As Variant
Dim matrizHundreds As Variant
matrizUnityes = Array("", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE")
matrizTens = Array("", "ELEVEN", "TWELVE", "THIRTEEN", "FOURTEEN", "FIFTEEN", "SIXTEEN", "SEVENTEEN", "EIGHTEEN", "NINETEEN")
matrizTenss = Array("", "TEN", "TWENTY", "THIRTY", "FOURTY", "FIFTY", "SIXTY", "SEVENTY", "EIGHTY", "NINETY")
matrizTenssY = Array("", "", "TWENTY ", "THIRTY ", "FOURTY ", "FIFTY ", "SIXTY ", "SEVENTY ", "EIGHTY ", "NINETY ")
matrizHundreds = Array("", "ONE HUNDRED", "TWO HUNDREDS", "THREE HUNDREDS", "FOUR HUNDREDS", "FIVE HUNDREDS", _
"SIX HUNDREDS", "SEVEN HUNDREDS", "EIGHT HUNDREDS", "NINE HUNDREDS")
Dim Unity As Integer, Tens As Integer, Hundreds As Integer
Hundreds = lgValue \ 100
Tens = (lgValue - Hundreds * 100) \ 10
Unity = (lgValue - Hundreds * 100 - Tens * 10)
strUnity = VBA.IIf(Tens <> 1, matrizUnityes(Unity), matrizTens(Unity))
strTens = VBA.IIf(Tens > 1, matrizTens(Unity), strTens)
strTens = VBA.IIf(Unity > 0, matrizTenssY(Tens), matrizTenss(Tens))
strHundreds = matrizHundreds(Hundreds)
fConvertQuantity = strHundreds & " " & strTens & strUnity
End Function