lunes, 25 de enero de 2010

Formatear con separadores de miles una cadena

Hola, ultimamente, he visto esta pregunta tanto en foros de EEUU como de HispanoAmerica, por ello me decido a colgar este pequeño ejemplo en C#, tambien lo disponible en VB por si alguien lo necesita:


Para que funcione correctamente ha de invocarse a la funcion desde el evento KeyUP




CODIGO C#


 public string Puntos(string strValor, int intNumDecimales)
{

    string strAux = null;
    string strComas = null;
    string strPuntos = null;
    int intX = 0;
    bool bolMenos = false;

    strComas = "";
    if (strValor.Length == 0) return "";
    strValor = strValor.Replace(Application.CurrentCulture.NumberFormat.NumberGroupSeparator, "");
    if (strValor.Contains(Application.CurrentCulture.NumberFormat.NumberDecimalSeparator)) {
        strAux = strValor.Substring(0, strValor.LastIndexOf(Application.CurrentCulture.NumberFormat.NumberDecimalSeparator));
        strComas = strValor.Substring(strValor.LastIndexOf(Application.CurrentCulture.NumberFormat.NumberDecimalSeparator) + 1);
    }
    else {
        strAux = strValor;
    }

    if (strAux.Substring(0, 1) == Application.CurrentCulture.NumberFormat.NegativeSign) {
        bolMenos = true;
        strAux = strAux.Substring(1);
    }

    strPuntos = strAux;
    strAux = "";
    while (strPuntos.Length > 3) {
        strAux = Application.CurrentCulture.NumberFormat.NumberGroupSeparator + strPuntos.Substring(strPuntos.Length - 3, 3) + strAux;
        strPuntos = strPuntos.Substring(0, strPuntos.Length - 3);
    }
    if (intNumDecimales > 0) {
        if (strValor.Contains(Application.CurrentCulture.NumberFormat.PercentDecimalSeparator)) {
            strComas = Application.CurrentCulture.NumberFormat.PercentDecimalSeparator + strValor.Substring(strValor.LastIndexOf(Application.CurrentCulture.NumberFormat.PercentDecimalSeparator) + 1);
            if (strComas.Length > intNumDecimales) {
                strComas = strComas.Substring(0, intNumDecimales + 1);
            }
         
        }
    }
    strAux = strPuntos + strAux + strComas;
   

    return strAux;
}




        private void textBox1_KeyUp(object sender, KeyEventArgs e)
        {
            textBox1.Text = Puntos(textBox1.Text, 0);
            textBox1.Select(textBox1.TextLength, 0);
        }


CODIGO VB:

    Public Function Puntos(ByVal strValor As String, ByVal intNumDecimales As Integer) As String

        Dim strAux As String = ""
        Dim strComas As String = ""
        Dim strPuntos As String = ""
        Dim intX As Integer = 0
        Dim bolMenos As Boolean = False

        If strValor.Length = 0 Then
            Return ""
        End If
        strValor = strValor.Replace(Application.CurrentCulture.NumberFormat.NumberGroupSeparator, "")
        If strValor.Contains(Application.CurrentCulture.NumberFormat.NumberDecimalSeparator) Then
            strAux = strValor.Substring(0, strValor.LastIndexOf(Application.CurrentCulture.NumberFormat.NumberDecimalSeparator))
            strComas = strValor.Substring(strValor.LastIndexOf(Application.CurrentCulture.NumberFormat.NumberDecimalSeparator) + 1)
        Else
            strAux = strValor
        End If

        If strAux.Substring(0, 1) = Application.CurrentCulture.NumberFormat.NegativeSign Then
            bolMenos = True
            strAux = strAux.Substring(1)
        End If

        strPuntos = strAux
        strAux = ""
        While strPuntos.Length > 3
            strAux = Application.CurrentCulture.NumberFormat.NumberGroupSeparator + strPuntos.Substring(strPuntos.Length - 3, 3) + strAux
            strPuntos = strPuntos.Substring(0, strPuntos.Length - 3)
        End While
        If intNumDecimales > 0 Then
            If strValor.Contains(Application.CurrentCulture.NumberFormat.PercentDecimalSeparator) Then
                strComas = Application.CurrentCulture.NumberFormat.PercentDecimalSeparator + strValor.Substring(strValor.LastIndexOf(Application.CurrentCulture.NumberFormat.PercentDecimalSeparator) + 1)
                If strComas.Length > intNumDecimales Then
                    strComas = strComas.Substring(0, intNumDecimales + 1)

                End If
            End If
        End If
        strAux = strPuntos + strAux + strComas


        Return strAux
    End Function


    Private Sub TextBox1_KeyUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyUp
        TextBox1.Text = Puntos(TextBox1.Text, 2)
        TextBox1.Select(TextBox1.TextLength, 0)
    End Sub

Para evitar, que metan en la caja de texto mas de un caracter decimal:

c#

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (textBox1.Text.Contains(Application.CurrentCulture.NumberFormat.NumberDecimalSeparator) && (e.KeyChar == Application.CurrentCulture.NumberFormat.NumberDecimalSeparator))
                e.Handled = true;
            else
                e.Handled = false;
        }


VB


 Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
        If TextBox1.Text.Contains(Application.CurrentCulture.NumberFormat.PercentDecimalSeparator) And (e.KeyChar = Application.CurrentCulture.NumberFormat.PercentDecimalSeparator) Then
            e.Handled = True
        Else
            e.Handled = False
        End If
    End Sub




5 comentarios:

  1. Yo la tenía hecha en Basics prehistóricos (incluso de antes de la existencia de la PC), en Pascal y en VB6.

    La versión en VB2008 estaría bien que la publicaras, aunque no parece difícil de "traducir" ;)

    Gracias.

    ResponderEliminar
  2. Vale mañana en un ratito la preparo en principio la tengo en vb lo que pasa es que en los foros me la pidieron en c# y la traduje en un rato!

    ResponderEliminar
  3. Jeje, no hay el menor apuro ;)

    ResponderEliminar
  4. Habeis oido hablar de los RegEXP????

    ResponderEliminar
  5. Te acuerdas cuando no existian las REGEXP? Como lo hacias?

    ResponderEliminar