Saltar al contenido

Validar Textbox con horas y minutos


Recommended Posts

publicado

Hola de nuevo. Sigo peleándome con mi proyecto. Lo cierto es que ya lo tengo prácticamente terminado, pero necesito acabar esto que me está volviendo a dar quebraderos de cabeza. He buscado en la red y este problema se plantea bastantes veces y he adaptado de una manera muy básica un código para un Textbox. Veréis en la captura que el formulario tiene muchos Textbox.

image.thumb.png.6dbd5f0dd63e76f338178e38a8794fc1.png

La idea es la siguiente, en los Textbox H.Entrada, H.Salida y Tiempo NO efectivo, recojo los datos de una tabla Excel.

Quedaría así una vez busco un empleado y una fecha.

image.png.1efd50c478371a192227f9f9eae71d65.png

Lo que pretendo es poder modificarlos. o bien borrando el dato (dejándolo en blanco) o modificando la hora. Para esto he hecho el código que pongo más adelante, solo para probar con un Textbox. Además que me parece excesivo de líneas veo que solo funciona casi bien, porque puedo engañar al código y poner letras, siempre y cuando respete el símbolo "." en medio del dato. A ver si podéis echarme una mano, si fuera posible reducir el código porque lo tengo que repetir en 21 Textbox. Además que ya veis que aunque funcione se ve muy poco profesional, o nada.

Private Sub TextBoxE1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If TextBoxE1 = "" Then Exit Sub
If Left(TextBoxE1, 2) > 23 Or Left(TextBoxE1, 2) < 0 Or Right(TextBoxE1, 2) > 59 Or Right(TextBoxE1, 2) < 0 Then
MsgBox "Se ha de introducir horas y minutos y con puntos (hh:mm)"
TextBoxE1 = ""
Exit Sub
End If
If Len(TextBoxE1) <> 5 Or Mid(TextBoxE1, 3, 1) <> ":" Then
MsgBox "Se ha de introducir horas y minutos y con puntos (hh:mm)"
Cancel = True
TextBoxE1 = ""
Exit Sub
End If
TextBoxE1 = Format(TextBoxE1, "hh:mm")
End Sub

Además quería preguntar, si introduzco un valor erróneo el valor que había antes en el checkbox ya me lo he cargado, por eso puesto de cuando no valide el dato deje en blanco el Textbox, pro si se pudiera conservar el dato que había sería lo suyo. Eso no tengo idea si se puede hacer o es imposible.

Gracias.

Moisés.

publicado

Por cierto, se me ha pasado comentarlo anteriormente, pero quizás ese no sea el evento adecuado. Como provengo de Access y allí el modelo de eventos es distinto, una validación de datos se suele realizar antes de actualizar el dato, por lo que quizás el evento más apropiado en este caso podría ser:

Private Sub TextBox1_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)

End Sub

Esto es una sugerencia, si profundizas en el mundo de los formularios te darás cuenta que los eventos a veces son complicados de gestionar sin que entren en conflicto con otras acciones.

Ah, y todo lo que sea iterativo es un buen indicador de que es necesaria una función o procedimiento.

publicado

@overdriveGracias, pero no consigo hacer que funcione. Lo he adaptado un poco a esto y ponga lo que ponga lo da por bueno.

Private Sub TextBoxE2_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
sTexto = TextBoxE2.Value
If sTexto Like "" Then Exit Sub
If sTexto Like "##[:]##" Then
If Left(TextBoxE2, 2) > 23 Or Left(TextBoxE2, 2) < 0 Or Right(TextBoxE2, 2) > 59 Or Right(TextBoxE2, 2) < 0 Then
MsgBox "Se ha de introducir horas y minutos y con puntos (hh:mm)"
End If
End If
End Sub

Yo creo que me estoy poniendo espeso.

publicado

Lo has adaptado demasiado, ya que te has dejado algo clave por el camino, que no se debe usar .value sino .text, ya que si Excel lo identifica como una hora te devolverá un número decimal. En este caso, sería recomendable usar la ventana de locales para ver los valores que la variable tiene durante la ejecución del código.

Por lo que pones entiendo que sería suficiente con:

Private Sub TextBoxE2_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
sTexto = TextBoxE2.text

If len(sTexto)=0 Then Exit Sub

If not sTexto Like "##[:]##" Then
	MsgBox "Se ha de introducir horas y minutos y con puntos (hh:mm)"
End If

End Sub

 

publicado
Hace 28 minutos , overdrive dijo:

Quizás mejor así:


If Len(sTexto) = 0 Then Cancel = True

 

Mejor Exit Sub porque quiero permitir que se borre el contenido del Textbox.

Con este código, casi funciona. Casi, porque se puede poner por ejemplo 25:70 y eso no es una hora válida. Debería permitir entre las 00:00 a las 23:59. 

Gracias, casi lo tenemos.

Moisés.

publicado

En ese caso, puedes hacer lo siguiente:

Sub MascaraEntrada()

    Dim sTexto As String
    sTexto = ActiveSheet.Cells(1, 1).Text
    
    If sTexto Like "##[:]##" And IsDate(sTexto) Then
        Debug.Print "Sí"
    Else
        Debug.Print "No"
    End If
   
End Sub

 

publicado

@overdrivelo he adaptado así, pero sigue igual.

Private Sub TextBoxE2_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
sTexto = TextBoxE2.Text
If Len(sTexto) = 0 Then Exit Sub
If Not sTexto Like "##[:]##" And Not IsDate(sTexto) Then
    MsgBox "Se ha de introducir horas y minutos y con puntos (hh:mm)"
End If
End Sub

 

publicado

@Pirtrafilla La lógica en condicionales no es similar a la lingüística, la expresión que has puesto sería: Not True And Not True, que es análogo a: True or True. Y eso no funcionará, por eso si quieres negar una condición compuesta por AND, puedes usar los paréntersis para agrupar e indicarle que debe evaluarse antes. En conclusión, usa:

Sub MascaraEntrada()

    Dim sTexto As String
    sTexto = ActiveSheet.Cells(1, 1).Text
    
    If Not (sTexto Like "##[:]##" And IsDate(sTexto)) Then
        Debug.Print "No"
    Else
        Debug.Print "Sí"
    End If
    

End Sub

 

publicado

@overdrive ¿Te refieres a este código?

Private Sub TextBoxE2_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
sTexto = TextBoxE2.Text
If Len(sTexto) = 0 Then Exit Sub
If Not (sTexto Like "##[:]##" And IsDate(sTexto)) Then
    MsgBox "Se ha de introducir horas y minutos y con puntos (hh:mm)"
End If
End Sub

 

publicado
Hace 1 minuto , overdrive dijo:

@Pirtrafilla No puedo comprobar si te funciona porque no tengo el archivo que estás fabricando pero entiendo que la lógica es correcta. Pruébalo y comentas.

Funciona. Ahora tengo buscar la manera de hacer esto los 21 Textbox que les ocurre lo mismo.

Gracias.

Moisés.

publicado

@Pirtrafilla No puedo probarlo pero mira si esto te vale:

Sub ValidarHora(sHora As String)

    If Len(sHora) = 0 Then End
    
    If Not (sHora Like "##[:]##" And IsDate(sHora)) Then
        MsgBox "Se ha de introducir horas y minutos y con puntos (hh:mm)"
    End If
End Sub
Private Sub TextBoxE2_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
    
    ValidarHora TextBoxE2.Text
End Sub

 

publicado

@overdriveHe cambiado End por Exit Sub, sino se cierra el programa.

Ahora si que se un código limpio, corto y usable. Muchas gracias.

Que diferencia con el que había comenzado yo en la pregunta.

Sub ValidarHora(sHora As String)
    If Len(sHora) = 0 Then Exit Sub
    If Not (sHora Like "##[:]##" And IsDate(sHora)) Then
        MsgBox "Se ha de introducir horas y minutos y con puntos (hh:mm)"
    End If
End Sub
Private Sub TextBoxE2_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
    ValidarHora TextBoxE2.Text
End Sub

Moisés.

publicado

@overdriveUna cosa más...

Funciona bien, si lo pongo mal me avisa, pero deja el dato en el Textbox y salta al siguiente tabulado.

¿Cómo podría hacer para que el Textbox se limpie si el formato no es el correcto.?

Como salimos del Textbox y la validación la hace una función, no se como limpiar el Textbox y no dejarlo con el dato mal.

Gracias.

publicado

@overdriveLo he arreglado así, pero no se si lo he dejado muy largo el código cuando antes había quedado tan corto.

Sub ValidarHora(sHora As String)
    If Len(sHora) = 0 Then Exit Sub
    If Not (sHora Like "##[:]##" And IsDate(sHora)) Then
        MsgBox "Se ha de introducir horas y minutos y con puntos (hh:mm)"
    End If
End Sub
Private Sub TextBoxE2_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
ValidarHora TextBoxE2.Text: If Not IsDate(TextBoxE2) Then TextBoxE2 = ""
End Sub

 

publicado

Para eso está el argumento Cancel, si lo establece a False, dejará el cursor en el cuadro de texto. Aquí te dejo mi propuesta:

Function EsHoraValida(sHora As String) As Boolean
    EsHoraValida = False

    If Len(sHora) = 0 Then Exit Function
    
    If Not (sHora Like "##[:]##" And IsDate(sHora)) Then
        MsgBox "Se ha de introducir horas y minutos y con puntos (hh:mm)"
        
        Exit Function
    End If
    
    EsHoraValida = True
End Function

Private Sub TextBoxE2_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)   
    If EsHoraValida(TextBoxE2.Text) = False Then TextBoxE2 = vbNullString: Cancel = True
End Sub

 

publicado
Hace 59 minutos , overdrive dijo:

Para eso está el argumento Cancel, si lo establece a False, dejará el cursor en el cuadro de texto. Aquí te dejo mi propuesta:


Function EsHoraValida(sHora As String) As Boolean
    EsHoraValida = False

    If Len(sHora) = 0 Then Exit Function
    
    If Not (sHora Like "##[:]##" And IsDate(sHora)) Then
        MsgBox "Se ha de introducir horas y minutos y con puntos (hh:mm)"
        
        Exit Function
    End If
    
    EsHoraValida = True
End Function

Private Sub TextBoxE2_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)   
    If EsHoraValida(TextBoxE2.Text) = False Then TextBoxE2 = vbNullString: Cancel = True
End Sub

 

@overdrivePerfecto. Ya lo he copiado y adaptado a los 21 botones y es lo que necesitaba.

Muchas gracias!!!!

Moisés.

 

Archivado

Este tema está ahora archivado y está cerrado a más respuestas.

×
×
  • Crear nuevo...

Información importante

Echa un vistazo a nuestra política de cookies para ayudarte a tener una mejor experiencia de navegación. Puedes ajustar aquí la configuración. Pulsa el botón Aceptar, si estás de acuerdo.