Numeros a letras en reporte Rdlc

Hace días un cliente me pidió un reporte de ventas en el cual saliera el total con letras. Ya había hecho eso antes, solo que generaba la el texto y lo guardaba en la base de datos.

En esta ocasión quise hacerlo poniendo el código dentro del mismo reporte.

Antes de comenzar, debo decirles que el código para convertir a letras debe estar escrito en Visual Basic.

Lo primero que hacemos es abrir la vista de código de nuestro reporte, esto lo hacemos dando clic en la parte gris, como se muestra en la imagen:


Luego, seleccionamos la pestaña Código:


El código es el siguiente:
    Dim sUnidades() As String =
    {"", "un", "dos", "tres", "cuatro", "cinco",
    "seis", "siete", "ocho", "nueve", "diez",
    "once", "doce", "trece", "catorce",
    "quince", "dieciseis",
    "diecisiete", "dieciocho", "diecinueve", "veinte",
    "veintiún", "veintidos", "veintitres", "veinticuatro",
    "veinticinco", "veintiseis", "veintisiete",
    "veintiocho", "veintinueve"}

    Dim sDecenas() As String =
    {"", "diez", "veinte", "treinta", "cuarenta", "cincuenta",
    "sesenta", "setenta", "ochenta", "noventa"}

    Dim sCentenas() As String =
    {"", "ciento", "doscientos", "trescientos",
    "cuatrocientos",
    "quinientos", "seiscientos", "setecientos",
    "ochocientos", "novecientos"}
    Dim sResultado As String = ""


    Public Function ConvertirCadena(ByVal sNumero As String) As String
        Dim dNumero As Double
        Dim dNumAux As Double = 0
        Dim x As Char
        Dim sAux As String

        sResultado = " "
        Try
            dNumero = Convert.ToDouble(sNumero)

        Catch
            Return ""
        End Try

        If (dNumero > 999999999999) Then
            Return ""
        End If
        If (dNumero > 999999999) Then
            dNumAux = dNumero Mod 1000000000000
            sResultado += Numeros(dNumAux, 1000000000) + " mil "
        End If

        If (dNumero > 999999) Then
            dNumAux = dNumero Mod 1000000000
            sResultado += Numeros(dNumAux, 1000000) + " millones "
        End If

        If (dNumero > 999) Then
            dNumAux = dNumero Mod 1000000
            sResultado += Numeros(dNumAux, 1000) + " mil "
        End If

        dNumAux = dNumero Mod 1000
        sResultado += Numeros(dNumAux, 1)

        ''Enseguida verificamos si contiene punto, 
        ''si es así, los convertimos a texto.
        sAux = dNumero.ToString()

        If (sAux.IndexOf(".") >= 0) Then
            sResultado += ObtenerDecimales(sAux)
        End If
        ''Las siguientes líneas convierten 
        ''el primer caracter a mayúscula.
        sAux = sResultado
        x = Char.ToUpper(sResultado(1))
        sResultado = x.ToString()

        For i As Integer = 2 To sAux.Length - 1 Step 1
            sResultado += sAux(i).ToString()
        Next

        Return sResultado
    End Function


    Public Function ConvertirNumero(ByVal dNumero As Double) As String
        Dim dNumAux As Double = 0
        Dim x As Char
        Dim sAux As String

        sResultado = " "

        If (dNumero > 999999999999) Then
            Return ""
        End If
        If (dNumero > 999999999) Then
            dNumAux = dNumero Mod 1000000000000
            sResultado += Numeros(dNumAux, 1000000000) + " mil "
        End If

        If (dNumero > 999999) Then
            dNumAux = dNumero Mod 1000000000
            sResultado += Numeros(dNumAux, 1000000) + " millones "
        End If

        If (dNumero > 999) Then
            dNumAux = dNumero Mod 1000000
            sResultado += Numeros(dNumAux, 1000) + " mil "
        End If

        dNumAux = dNumero Mod 1000
        sResultado += Numeros(dNumAux, 1)


        ''Enseguida verificamos si contiene punto, 
        ''si es así, los convertimos a texto.
        sAux = dNumero.ToString()
        Dim varDecimales As String = ""
        If (sAux.IndexOf(".") >= 0) Then
            varDecimales = ObtenerDecimales(sAux)

        Else
            varDecimales = ""
        End If
        sResultado += varDecimales
        ''Las siguientes líneas convierten 
        ''el primer caracter a mayúscula.
        sAux = sResultado
        x = Char.ToUpper(sResultado(1))
        sResultado = x.ToString()
        For i As Integer = 2 To sAux.Length - 1 Step 1
            sResultado += sAux(i).ToString()
        Next

        Return sResultado
    End Function


    Private Function Numeros(ByVal dNumAux As Double, _
                             ByVal dFactor As Double) As String
        Dim dCociente As Double = dNumAux / dFactor
        Dim dNumero As Double = 0
        Dim iNumero As Integer = 0
        Dim sNumero As String = ""
        Dim sTexto As String = ""

        If (dCociente >= 100) Then
            dNumero = dCociente / 100
            sNumero = dNumero.ToString()
            iNumero = Integer.Parse(sNumero(0).ToString())
            sTexto += Me.sCentenas(iNumero) + " "
        End If

        dCociente = dCociente Mod 100
        If (dCociente >= 30) Then
            dNumero = dCociente / 10
            sNumero = dNumero.ToString()
            iNumero = Integer.Parse(sNumero(0).ToString())
            If (iNumero > 0) Then
                sTexto += Me.sDecenas(iNumero) + " "
            End If

            dNumero = dCociente Mod 10
            sNumero = dNumero.ToString()
            iNumero = Integer.Parse(sNumero(0).ToString())
            If (iNumero > 0) Then
                sTexto += "y " + Me.sUnidades(iNumero) + " "
            End If

        Else
            dNumero = dCociente
            sNumero = dNumero.ToString()
            If (sNumero.Length > 1) Then
                If (sNumero(1) <> ".") Then
                    iNumero = Integer.Parse(sNumero(0).ToString() +
                        sNumero(1).ToString())
                Else
                    iNumero = Integer.Parse(sNumero(0).ToString())
                End If
            Else
                iNumero = Integer.Parse(sNumero(0).ToString())
                sTexto += Me.sUnidades(iNumero) + " "
            End If
        End If

        Return sTexto
    End Function


    Private Function ObtenerDecimales(ByVal sNumero As String) As String
        Dim sNumPuntos() As String
        Dim sTexto As String = ""
        Dim dNumero As Double = 0
        sNumPuntos = sNumero.Split(".")
        dNumero = Convert.ToDouble(sNumPuntos(1))
        sTexto = "punto " + Numeros(dNumero, 1)
        Return sTexto
    End Function


Luego, vayamos al lugar en donde ubicaremos los valores:


Escribimos algo así:


Así se ve, maso menos:



Nota: La vista previa corresponde al diseño de mi cliente, en portugués.

Listo!!!

13 comentarios:

  1. me han salvado la vida, gracias...

    ResponderEliminar
    Respuestas
    1. Hola, me podrías ayudar soy nuevo. He probado y no me acepta el code.NumeroLetra

      Eliminar
    2. Hola necesito saber por que el código me marca error en code.NumeroLetra :/ necesito ayuda, mi proyecto se entrega mañana

      Eliminar
  2. Hola necesito saber por que el código me marca error en code.NumeroLetra :/ necesito ayuda, mi proyecto se entrega mañana.....Por favor!

    ResponderEliminar
  3. No sean tan vagos, si se analiza un poco el código, es fácil darse cuenta del error, es un simple llamado a la función, no la manda llamar con el nombre correcto.

    ResponderEliminar
  4. Por favor tendras el codigo para c# te lo agradecere mucho por favor lo necesito urgente gracias

    ResponderEliminar
  5. Y porsiacso no sabras tu por favor para que me puedas ayudar te lo agradecere mucho

    ResponderEliminar
  6. ESTE CODIGO NO ES AUDITORIA MIA, NO RECUERDO QUIEN LO PROGRAMO PERO ME HA RESULTADO MUY UTIL JUNTO CON LA INFORMACION DE ESTE POST.
    LES COMPARTO EL CODIGO
    https://drive.google.com/open?id=1bwGK6iBSkTGFDHKJlv4dQKCEzT82HeAK

    ResponderEliminar
  7. Solo en las expresiones me tira error cual sera la correcta
    Me puedes ayudar

    ResponderEliminar
  8. Solo en la expresion me tira error en visual studio 2017
    Me puedes ayudar te agradezco bastante

    ResponderEliminar