none
validar rut chileno en aplicación problema RRS feed

  • Pregunta

  • buenas tardes 

    señores programadores estoy haciendo una aplicacion pequeña para verficar el rut de un alumno pero tengo problemas al tratar de validarla

    rut es chileno

    en que parte pongo este codigo de la validacion del rut al ponerlo en txtrutchangue salta altiro

    como puedo puedo poner que salga el digito verifcador en caja txtverificador.txt

    vb.net 

    sql server 

    Private Sub TxtRut_TextChanged(sender As Object, e As EventArgs) Handles TxtRut.TextChanged
    
            If Not IsDBNull(TxtRut.Text) _
                AndAlso
                Not String.IsNullOrEmpty(TxtRut.Text) Then
                Dim Txt = TxtRut.Text
                Dim Reg As New Regex("^\d{1,2}\d{3}\d{3}[-][0-9kK]{1}$") '("/^([0-9])+\-([kK0-9])+$/")
                Dim m As Match = Reg.Match(Txt)
                If m.Success Then
    
                Else
                    MsgBox("Debe ingresar un rut válido")
                    TxtRut.Focus()
    
                End If
            End If
    
        End Sub
    viernes, 17 de marzo de 2017 19:59

Respuestas

  • djnilo,

    Un código de control o de verificación permite validar el ingreso de un dato, es un mecanismo utilizado para verificar la integridad de un valor, por ejemplo, un número de documento, un número de cuenta, etc. En ese contexto, creo que haces mal dejando que sea la aplicación quien calcule y escriba el dígito verificador, pienso que el usuario debe ingresar el número de RUT bajo la forma 'XXXXXXXX-Y' y la aplicación se debe limitar a validar si el valor ingresado es válido comparando el dígito verificador -ingresado por el usuario como parte del número- versus el calculado.

    - Función que determina si el número de RUT ingresado bajo la forma XXXXXXXX-Y es válido:

    Private Function RUTNumberValid(RUT As String) As Boolean
    
    	Dim DigitosSerie() As Integer = {2, 3, 4, 5, 6, 7, 2, 3}
    
    	'Obtener la suma de productos (carácter en orden invertido x dígito de serie)
    	Dim SumaProductos = RUT.Substring(0, 8).Reverse.Select(Function(c, i) New With
    			{.Val = (Val(c) * DigitosSerie(i)), .Index = i}).Sum(Function(c) c.Val)
    
    	'Obtener la diferencia de 11 sobre el residuo
    	Dim Result = 11 - (SumaProductos Mod 11)
    
    	Return If(Result = 11, "0", If(Result = 10, "K", Result.ToString)) = RUT.Substring(9, 1)
    
    End Function

    - Escribir las reglas de validación que se ejecutarán al momento en que se produce el evento Validating (usualmente cuando el control deja de ser el activo)

    Private Sub txtRUT_Validating(sender As Object, ...
    
    	Dim txt = CType(sender, TextBox)
    
    	If Not String.IsNullOrEmpty(txtRUT.Text) Then
    		ErrorProvider1.SetError(txt, String.Empty)
    
    		If Regex.Match(txtRUT.Text, "^(\d{8}-)(\d{1}$)").Success Then
    			If Not RUTNumberValid(txtRUT.Text) Then '¿Es válido el número de RUT?
    				e.Cancel = True
    				ErrorProvider1.SetError(txt, "El número de RUT no es válido")
    			End If
    		Else
    			e.Cancel = True
    			ErrorProvider1.SetError(txt, "El formato de número de RUT no es válido")
    		End If
    	End If
    
    End Sub


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Propuesto como respuesta Joyce_ACModerator martes, 21 de marzo de 2017 18:02
    • Marcado como respuesta djnilo miércoles, 22 de marzo de 2017 1:18
    martes, 21 de marzo de 2017 15:13
  • pero sigo rabiado que deberia aparecer el digito verifiacador en la caja txtdigitoverificadortxt

    Lo siento, pero lo que intentas hacer no tiene sentido siendo que el dígito verificador -reitero- tiene como objetivo validar el número ingresado, si permites que la aplicación calcule el dígito verificador el usuario podrá ingresar cualquier número de 8 dígitos sin problema alguno.

    Dicho lo anterior, y para lo que pueda servir:

    - Procedimiento Function que retorna el dígito verificador

    Private Function ObtenerDigitoVerificador(RUT As String) As String
    
    	Dim DigitosSerie() As Integer = {2, 3, 4, 5, 6, 7, 2, 3}
    
    	'Obtener la suma de productos (carácter en orden invertido x dígito de serie)
    	Dim SumaProductos = RUT.Substring(0, 8).Reverse.Select(Function(c, i) New With
    			{.Val = (Val(c) * DigitosSerie(i)), .Index = i}).Sum(Function(c) c.Val)
    
    	'Obtener la diferencia de 11 sobre el residuo
    	Dim Result = 11 - (SumaProductos Mod 11)
    
    	Return If(Result = 11, "0", If(Result = 10, "K", Result.ToString))
    
    End Function

    - Validar el formato de ingreso del número de RUT (sólo 8 dígitos)

    Private Sub txtRUT_Validating(sender As Object, ...
    
    	Dim txt = CType(sender, TextBox)
    
    	If Not String.IsNullOrEmpty(txtRUT.Text) Then
    		ErrorProvider1.SetError(txt, String.Empty)
    
    		If Not Regex.Match(txtRUT.Text, "^\d{8}$").Success Then
    			e.Cancel = True
    			ErrorProvider1.SetError(txt, "El número de RUT debe tener 8 dígitos")
    		End If
    	End If
    
    End Sub

    - Escribir dígito verificador. Considera configurar la propiedad Enabled a False para el objeto 'txtDigitoVerificador' siendo que el valor de la propiedad Text es calculado, no tiene sentido mostrarlo como disponible.

    Private Sub txtRUT_TextChanged(sender As Object, ...
    
    	txtDigitoVerificador.Text = String.Empty
    
    	If txtRUT.TextLength = 8 Then
    		txtDigitoVerificador.Text = ObtenerDigitoVerificador(txtRUT.Text)
    
    		SelectNextControl(ActiveControl, True, True, True, True)
    	End If
    
    End Sub


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Marcado como respuesta djnilo jueves, 27 de abril de 2017 15:11
    miércoles, 22 de marzo de 2017 3:23

Todas las respuestas

  • Hola djnilo,

    Lo que pasa es que el evento TextChanged del TextBox se ejecuta cada ves que se cambia el valor de la propiedad Text. Por lo que al ingresar valor por valor este se repetirá 'n' veces. 

    Si escribes "102030" en el TextBox el evento se ejecutará por cada cambio : (en total 6 veces).

    1
    10
    102
    1020
    10203
    102030

    Puedes ejecutarlo de varias maneras, usando el evento Leave (se ejecuta cuando el control deja de ser el control activo del formulario, valga la redundancia), Validating (se ejecuta cuando el control se está validando) o ejecutarlo mediante una tecla clave como el 'Enter'.

    Usando el evento Validating.

    - Es necesario usar el ErrorProvider.

    Private Sub TxtRut_Validating(sender As Object, e ......
    
        Dim txt = CType(sender, TextBox)
    
        If Not String.IsNullOrEmpty(txt.Text) Then
    
            If Not Regex.Match(txt.Text,
                            "^\d{1,2}\d{3}\d{3}[-][0-9kK]{1}$").Success Then
                e.Cancel = True
                ErrorProvider1.SetError(txt, "Debe ingresar un rut válido")
            End If
    
        End If
    End Sub

    Evento Control.Validating

    O usando la tecla ENTER.

    Private Sub TxtRut_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TxtRut.KeyPress
        'Presiona la tecla Enter, validamos
        If e.KeyChar = Convert.ToChar(Keys.Enter) Then
            'Operaciones
        End If
    End Sub

    Saludos.


    JC NaupaCrispín
    Lima - Perú

    La magia no existe, la programación SI

    viernes, 17 de marzo de 2017 20:33
  • Hola djnilo,

    Lo que pasa es que el evento TextChanged del TextBox se ejecuta cada ves que se cambia el valor de la propiedad Text. Por lo que al ingresar valor por valor este se repetirá 'n' veces. 

    Si escribes "102030" en el TextBox el evento se ejecutará por cada cambio : (en total 6 veces).

    1
    10
    102
    1020
    10203
    102030

    Puedes ejecutarlo de varias maneras, usando el evento Leave (se ejecuta cuando el control deja de ser el control activo del formulario, valga la redundancia), Validating (se ejecuta cuando el control se está validando) o ejecutarlo mediante una tecla clave como el 'Enter'.

    Usando el evento Validating.

    - Es necesario usar el ErrorProvider.

    Private Sub TxtRut_Validating(sender As Object, e ......
    
        Dim txt = CType(sender, TextBox)
    
        If Not String.IsNullOrEmpty(txt.Text) Then
    
            If Not Regex.Match(txt.Text,
                            "^\d{1,2}\d{3}\d{3}[-][0-9kK]{1}$").Success Then
                e.Cancel = True
                ErrorProvider1.SetError(txt, "Debe ingresar un rut válido")
            End If
    
        End If
    End Sub

    Evento Control.Validating

    O usando la tecla ENTER.

    Private Sub TxtRut_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TxtRut.KeyPress
        'Presiona la tecla Enter, validamos
        If e.KeyChar = Convert.ToChar(Keys.Enter) Then
            'Operaciones
        End If
    End Sub

    Saludos.


    JC NaupaCrispín
    Lima - Perú

    La magia no existe, la programación SI

    muchas gracias por responder y clase tambien

    pero manda un error en esta linea

    ¿ como podria poner para que me aparecas el digito verificado en la caja texto digito

     Private Sub TxtRut_Validated(sender As Object, e As EventArgs) Handles TxtRut.Validated
            Dim txt = CType(sender, TextBox)
    
            If Not String.IsNullOrEmpty(TxtRut.Text) Then
    
                If Not Regex.Match(TxtRut.Text,
                                "^\d{1,2}\d{3}\d{3}[-][0-9kK]{1}$").Success Then
                    e.Cancel = True ' me dice que el cancel no es miembro Eventargs
                    ErrorProvider1.SetError(txt, "Debe ingresar un rut válido")
                End If
    
            End If
        End Sub

    sábado, 18 de marzo de 2017 22:35
  • Hola djnilo,

    Tienes que usar el evento Validating no Validated, ya que este último se ejecuta cuando el control ya se validó.

    Saludos.


    JC NaupaCrispín
    Lima - Perú

    La magia no existe, la programación SI

    domingo, 19 de marzo de 2017 0:35
  • Hola djnilo,

    Tienes que usar el evento Validating no Validated, ya que este último se ejecuta cuando el control ya se validó.

    Saludos.


    JC NaupaCrispín
    Lima - Perú

    La magia no existe, la programación SI

    muchas gracias JC Naupacrispin pero no sirve al parece este codigo que puse 

    para validar el rut se queda asi

    el rut es 15055230-3 el tres el digito verificador

    lunes, 20 de marzo de 2017 16:45
  • Hola djnilo,

    [-] ... en que parte pongo este codigo de la validacion del rut al ponerlo en txtrutchangue salta altiro

    La verdad solo me limité a responder porque tenías el problema de la validación, ya que este se ejecutaba en cada cambio de la propiedad .Text de tu control TextBox.

    Ahora lo que es incorrecto es el patrón que estás utilizando para validar el RUT. La verdad desconozco como es la estructura real de un RUT pero según lo indicado :

    15055230-3
    
    8númerosguión1número

    Por lo que sería :

        Private Sub TxtRut_Validating(sender As ....
            Dim txt = CType(sender, TextBox)
    
            If Not String.IsNullOrEmpty(TxtRut.Text) Then
    
                If Not Regex.Match(TxtRut.Text,
                                "^(\d{8}-)(\d{1}$)").Success Then
                    e.Cancel = True
                    ErrorProvider1.SetError(txt, "Debe ingresar un rut válido")
                End If
    
            End If
        End Sub

    Y en el evento Validated limpiamos el error mostrado porque ya se valido correctamente.

    Private Sub TxtRut_Validated(sender As Object, e As EventArgs) Handles TxtRut.Validated
        ErrorProvider1.SetError(CType(sender, TextBox), String.Empty)
    End Sub

    Resultado :

    En caso el RUT tenga diversas estructuras, si podrías mostrar un ejemplo de los posibles resultados que este debe tener sería de gran ayuda.

    Saludos.


    JC NaupaCrispín
    Lima - Perú

    La magia no existe, la programación SI

    lunes, 20 de marzo de 2017 17:24
  • Hola djnilo,

    [-] ... en que parte pongo este codigo de la validacion del rut al ponerlo en txtrutchangue salta altiro

    La verdad solo me limité a responder porque tenías el problema de la validación, ya que este se ejecutaba en cada cambio de la propiedad .Text de tu control TextBox.

    Ahora lo que es incorrecto es el patrón que estás utilizando para validar el RUT. La verdad desconozco como es la estructura real de un RUT pero según lo indicado :

    15055230-3
    
    8númerosguión1número

    Por lo que sería :

        Private Sub TxtRut_Validating(sender As ....
            Dim txt = CType(sender, TextBox)
    
            If Not String.IsNullOrEmpty(TxtRut.Text) Then
    
                If Not Regex.Match(TxtRut.Text,
                                "^(\d{8}-)(\d{1}$)").Success Then
                    e.Cancel = True
                    ErrorProvider1.SetError(txt, "Debe ingresar un rut válido")
                End If
    
            End If
        End Sub

    Y en el evento Validated limpiamos el error mostrado porque ya se valido correctamente.

    Private Sub TxtRut_Validated(sender As Object, e As EventArgs) Handles TxtRut.Validated
        ErrorProvider1.SetError(CType(sender, TextBox), String.Empty)
    End Sub

    Resultado :

    En caso el RUT tenga diversas estructuras, si podrías mostrar un ejemplo de los posibles resultados que este debe tener sería de gran ayuda.

    Saludos.


    JC NaupaCrispín
    Lima - Perú

    La magia no existe, la programación SI

    muchas gracias por tu paciencia JC NaupaCrispin

    voy seguir buscando un algoritmo para  validar el rut chileno este no sirve no valida gracias por tu paciencia

    lunes, 20 de marzo de 2017 18:11
  • djnilo,

    Una expresión regular te servirá únicamente para realizar búsquedas basadas en patrones (en tu caso restringir que el número ingresado contenga 8 dígitos, un guión medio y un último dígito verificador), pero si deseas conocer si un número de identificación tributaria es válido no te basta una expresión regular, debes implementar un algoritmo para obtener el dígito verificador y -en base al resultado- corroborar si el número ingresado es válido, revisa los siguientes enlaces:

    ALGORITMO DIGITO VERIFICADOR DE RUT CHILENO

    Rol Único Tributario

    Algoritmo para Validar RUT


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    lunes, 20 de marzo de 2017 18:35
  • djnilo,

    Una expresión regular te servirá únicamente para realizar búsquedas basadas en patrones (en tu caso restringir que el número ingresado contenga 8 dígitos, un guión medio y un último dígito verificador), pero si deseas conocer si un número de identificación tributaria es válido no te basta una expresión regular, debes implementar un algoritmo para obtener el dígito verificador y -en base al resultado- corroborar si el número ingresado es válido, revisa los siguientes enlaces:

    ALGORITMO DIGITO VERIFICADOR DE RUT CHILENO

    Rol Único Tributario

    Algoritmo para Validar RUT


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.

    muchas gracias Williams Morales  por tu tiempo pero ya lo habia visto eso del rut

    lo qu necesito que el digito validarlo lo ponga en la otra caja de texto ejmplo txtdigitoverificador.txt

    por ejemplo rut 15055230-3 aparesca en la caja txtrut = 15055230 txtdigitoverificador.txt = 3

    habria que sacarle el guio para que funciona de esa forma

    algoritmo ocupado

     Public Function ValidaRut(ByVal ElNumero As String) As String
            Dim Resultado As String = ""
            Dim Multiplicador As Integer = 2
            Dim iNum As Integer = 0
            Dim Suma As Integer = 0
    
            For i As Integer = 8 To 1 Step -1
                iNum = Mid(ElNumero, i, 1)
                Suma += iNum * Multiplicador
                Multiplicador += 1
                If Multiplicador = 8 Then Multiplicador = 2
            Next
            Resultado = CStr(11 - (Suma Mod 11))
            If Resultado = "10" Then Resultado = "K"
            If Resultado = "11" Then Resultado = "0"
            Return ElNumero & "-" & Resultado
    
            'Return Resultado
    
        End Function

    para llamarlo

     Private Sub TxtRut_TextChanged(sender As Object, e As EventArgs) Handles TxtRut.TextChanged
    
            If TxtRut.TextLength = 8 Then
                TxtRut.Text = ValidaRut(TxtRut.Text)
                My.Computer.Keyboard.SendKeys("{tab}", True)
            End If
            If TxtRut.TextLength = 8 Then TxtRut.Text = ValidaRut(TxtRut.Text)
    
            
    
        End Sub
    

    martes, 21 de marzo de 2017 12:56
  • djnilo,

    Un código de control o de verificación permite validar el ingreso de un dato, es un mecanismo utilizado para verificar la integridad de un valor, por ejemplo, un número de documento, un número de cuenta, etc. En ese contexto, creo que haces mal dejando que sea la aplicación quien calcule y escriba el dígito verificador, pienso que el usuario debe ingresar el número de RUT bajo la forma 'XXXXXXXX-Y' y la aplicación se debe limitar a validar si el valor ingresado es válido comparando el dígito verificador -ingresado por el usuario como parte del número- versus el calculado.

    - Función que determina si el número de RUT ingresado bajo la forma XXXXXXXX-Y es válido:

    Private Function RUTNumberValid(RUT As String) As Boolean
    
    	Dim DigitosSerie() As Integer = {2, 3, 4, 5, 6, 7, 2, 3}
    
    	'Obtener la suma de productos (carácter en orden invertido x dígito de serie)
    	Dim SumaProductos = RUT.Substring(0, 8).Reverse.Select(Function(c, i) New With
    			{.Val = (Val(c) * DigitosSerie(i)), .Index = i}).Sum(Function(c) c.Val)
    
    	'Obtener la diferencia de 11 sobre el residuo
    	Dim Result = 11 - (SumaProductos Mod 11)
    
    	Return If(Result = 11, "0", If(Result = 10, "K", Result.ToString)) = RUT.Substring(9, 1)
    
    End Function

    - Escribir las reglas de validación que se ejecutarán al momento en que se produce el evento Validating (usualmente cuando el control deja de ser el activo)

    Private Sub txtRUT_Validating(sender As Object, ...
    
    	Dim txt = CType(sender, TextBox)
    
    	If Not String.IsNullOrEmpty(txtRUT.Text) Then
    		ErrorProvider1.SetError(txt, String.Empty)
    
    		If Regex.Match(txtRUT.Text, "^(\d{8}-)(\d{1}$)").Success Then
    			If Not RUTNumberValid(txtRUT.Text) Then '¿Es válido el número de RUT?
    				e.Cancel = True
    				ErrorProvider1.SetError(txt, "El número de RUT no es válido")
    			End If
    		Else
    			e.Cancel = True
    			ErrorProvider1.SetError(txt, "El formato de número de RUT no es válido")
    		End If
    	End If
    
    End Sub


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Propuesto como respuesta Joyce_ACModerator martes, 21 de marzo de 2017 18:02
    • Marcado como respuesta djnilo miércoles, 22 de marzo de 2017 1:18
    martes, 21 de marzo de 2017 15:13
  • muchas gracias por tu colaboración y paciencia williams Morales había mucho codigo de mas el que tenia yo

    el tuyo esta mas simpificado tu codigo pero sigo rabiado que deberia aparecer el digito verifiacador en la caja txtdigitoverificadortxt

    miércoles, 22 de marzo de 2017 1:18
  • pero sigo rabiado que deberia aparecer el digito verifiacador en la caja txtdigitoverificadortxt

    Lo siento, pero lo que intentas hacer no tiene sentido siendo que el dígito verificador -reitero- tiene como objetivo validar el número ingresado, si permites que la aplicación calcule el dígito verificador el usuario podrá ingresar cualquier número de 8 dígitos sin problema alguno.

    Dicho lo anterior, y para lo que pueda servir:

    - Procedimiento Function que retorna el dígito verificador

    Private Function ObtenerDigitoVerificador(RUT As String) As String
    
    	Dim DigitosSerie() As Integer = {2, 3, 4, 5, 6, 7, 2, 3}
    
    	'Obtener la suma de productos (carácter en orden invertido x dígito de serie)
    	Dim SumaProductos = RUT.Substring(0, 8).Reverse.Select(Function(c, i) New With
    			{.Val = (Val(c) * DigitosSerie(i)), .Index = i}).Sum(Function(c) c.Val)
    
    	'Obtener la diferencia de 11 sobre el residuo
    	Dim Result = 11 - (SumaProductos Mod 11)
    
    	Return If(Result = 11, "0", If(Result = 10, "K", Result.ToString))
    
    End Function

    - Validar el formato de ingreso del número de RUT (sólo 8 dígitos)

    Private Sub txtRUT_Validating(sender As Object, ...
    
    	Dim txt = CType(sender, TextBox)
    
    	If Not String.IsNullOrEmpty(txtRUT.Text) Then
    		ErrorProvider1.SetError(txt, String.Empty)
    
    		If Not Regex.Match(txtRUT.Text, "^\d{8}$").Success Then
    			e.Cancel = True
    			ErrorProvider1.SetError(txt, "El número de RUT debe tener 8 dígitos")
    		End If
    	End If
    
    End Sub

    - Escribir dígito verificador. Considera configurar la propiedad Enabled a False para el objeto 'txtDigitoVerificador' siendo que el valor de la propiedad Text es calculado, no tiene sentido mostrarlo como disponible.

    Private Sub txtRUT_TextChanged(sender As Object, ...
    
    	txtDigitoVerificador.Text = String.Empty
    
    	If txtRUT.TextLength = 8 Then
    		txtDigitoVerificador.Text = ObtenerDigitoVerificador(txtRUT.Text)
    
    		SelectNextControl(ActiveControl, True, True, True, True)
    	End If
    
    End Sub


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Marcado como respuesta djnilo jueves, 27 de abril de 2017 15:11
    miércoles, 22 de marzo de 2017 3:23