Discussion:
Personalizar la entrada de datos en un TextBox (Máscara de Entrada)
(demasiado antiguo para responder)
Insumos
2007-06-26 21:45:14 UTC
Permalink
Hola Gente del Foro:

Espero todos esten bien! Mi consulta de hoy es: Hay alguna manera de
personalizar la forma en que los usuarios ingresen datos en un TextBox?
Lo que busco exactamente es lo siguiente: en un Userform yo tengo un TextBox
en el cuál hay que ingresar un dato manualmente que es una fecha. De la
manera como está ahora los usuarios, si por ejemplo deben ingresar 22/06/07,
deben ingresar cada uno de los caracteres (incluyendo las barras "/"). La
cuestión es que esto puede dar lugar a errores, como que los usuarios tipeen
2206/07 (salteando una barra, por ejemplo) o 22/06 (olvidando ingresar el
año), o 22/06/077 (ingresando un 7 de más), etc, etc. Lo que yo necesitaria
es algo así como una "máscara de entrada" (del tipo que hay en access) de
modo que los usuarios tengan en el TextBox predefinido el formato _ _ / _ _
/ _ _ del cual no puedan apartarse. De esta manera obligaría a los usuarios
a ingresar los datos de una manera standarizada, en la cual no hayan ni
olvidos ni agregados en el dato, y evito todos los trastornos que puedan
generar en las operaciones los errores de ingreso.
Espero haberme explicado correctamente.
Saludos y desde ya muchas gracias!!

Mariano

--
CONTADURIA
Héctor Miguel
2007-06-26 23:19:06 UTC
Permalink
hola. Mariano !
... alguna manera de personalizar la forma en que los usuarios ingresen datos en un TextBox?
... en un Userform... un TextBox... ingresar un dato... fecha...
... algo asi como una "mascara de entrada" (del tipo que hay en access) [...]
toma en cuenta que un control textbox [por su misma caracteristica] 'acepta' datos de todo tipo...
suponiendo que diferentes usuarios pudieran tener diferentes *costumbres* en el orden de fechas...
y considerando que NO es 'el fuerte' de excel... andar 'enmascarando' las entradas del usuario...

op1: inserta a tu formulario un control DTPicker o un control Calendar

op2: utilza TRES controles textbox para usarlos segun el orden de fechas que vayas a controlas [dd/mm/aa <-> mm/dd/aa]

si cualquier duda... comentas ?
saludos,
hector.

p.d. el control DTPicker requiere que esta instalado y registrado...
-> el componente [+/- C:\Windows\System[32]\mscomct2.ocx]...
el control calendar requiere que este instalado y registrado...
-> el componente [C:\Archivos de programa\Microsoft Office x.0\Officexx\MSCal.ocx]
Ivan
2007-06-27 00:55:37 UTC
Permalink
hola chicos,

disculpad que me meta, pero estaba liadillo preparando esta respuesta y hasta que no la he tenido acabada (+/-) no he
visto la de hector, que posiblemente lo dice (casi)todo sobre el `marron' que puede llegar a suponer la conjuncion
fechas/controles vba (al menos en lo que a mi experiencia se refiere)

pero, bueno ya que esta hecho, y aprovechando que hector podria comentarnos posibles inconvenientes en el uso ( que
seguro existen, sobre todo con determinadas teclas) de estos codigos, y ademas puede darle alguna idea a Mariano, aqui
la mando

Nota: aunque normalmente, por lo que he visto, la validacion numerica suele hacerse en keypress o quizas en keydown,
aqui he hecho una especie de conglomerado que al menos y sin demasiadas pruebas parece funcionar relativamente bien


' modulo del formulario:
'
Dim Borrar As Boolean
'
'en el mismo modulo del form (la funcion, si prefieres tenerla disponible para otros formularios de la aplicacion puedes
ponerla en uno normal como public)

Function Mascara_Fecha(ByRef TextB As MSForms.TextBox, _
ByRef b_Borrar As Boolean)
Dim n As Byte, nl As Byte, lt As String
With TextB
If .Text = "" Then b_Borrar = False: Exit Function
nl = Len(.Text): lt = Mid(.Text, nl, 1)
Select Case nl
Case Is = 1
If Not IsNumeric(lt) Or Val(lt) > 3 Then .Text = ""
Case Is = 2
If Not IsNumeric(lt) Or Val(.Text) > 31 Or _
Val(.Text) < 1 Then
.Text = Left(.Text, nl - 1)
Else
.Text = .Text & "/"
End If
Case Is = 3
If b_Borrar Then .Text = Left(.Text, 1)
Case Is = 4
If Not IsNumeric(lt) Or _
Val(lt) > 1 Then .Text = Left(.Text, nl - 1)
Case Is = 5
If Not IsNumeric(lt) Or _
Val(Mid(.Text, nl - 1, 1) & lt) > 12 Or _
Val(Mid(.Text, nl - 1, 1) & lt) < 1 Then
.Text = Left(.Text, nl - 1)
Else
.Text = .Text & "/"
End If
Case Is = 6
If b_Borrar Then .Text = Left(.Text, 4)
Case Is > 8
.Text = Left(.Text, 8)
Case Else
End Select
End With
b_Borrar = False
End Function

' ejemplo de uso (es importante el codigo de KeyDown)

Private Sub TextBox1_Change()
Mascara_Fecha TextBox1, Borrar
End Sub

' para permitir el borrado con la tecla retroceso sin interferencias (seguramente convendria controlar alguna tecla
mas)
'
Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, _
ByVal Shift As Integer)
If KeyCode = vbKeyBack Then Borrar = True
End Sub

bueno, como dice Hector creo que hay otras soluciones mucho mejores, pero para practicar no esta mal

un saludo
Ivan
Ivan
2007-06-27 02:13:08 UTC
Permalink
hola de nuevo (para variar)

siguiendo con el 'entretenimiento' y ya de paso aprovechando para consultarle una 'curiosidad' a Hector Miguel, esta
otra incluiria una validacion para los bisiestos (por cierto se me olvido comentar que esta hecha para el formato y
configuracion regional 'dd/mm/aa'). La consulta la pongo al final

Function Mascara_Fecha(ByRef TextB As MSForms.TextBox, _
ByRef b_Borrar As Boolean)
Dim n As Byte, nl As Byte, lt As String, max As Byte
With TextB
If .Text = "" Then b_Borrar = False: Exit Function
nl = Len(.Text): lt = Mid(.Text, nl, 1)
Select Case nl
Case Is = 1
If Not IsNumeric(lt) Or Val(lt) > 3 Then .Text = ""
Case Is = 2, Is = 5
If nl = 2 Then max = 31 Else max = 12
If Not IsNumeric(lt) Or _
Val(Mid(.Text, nl - 1, 1) & lt) > max Or _
Val(Mid(.Text, nl - 1, 1) & lt) < 1 Then
.Text = Left(.Text, nl - 1)
Else
If nl = 5 And Not IsDate(.Text & "/00") Then _
.Text = Left(.Text, nl - 1) Else _
.Text = .Text & "/"
End If
Case Is = 3, Is = 6
If b_Borrar Then .Text = Left(.Text, nl - 2)
Case Is = 4
If Not IsNumeric(lt) Or _
Val(lt) > 1 Then .Text = Left(.Text, nl - 1)
Case Is = 8
If Left(.Text, 2) = "29" And Mid(.Text, 4, 2) = "02" And _
Val(Right(.Text, 2)) Mod 4 > 0 Then .Text = Left(.Text, nl - 1)
Case Is > 8
.Text = Left(.Text, 8)
Case Else
End Select
End With
b_Borrar = False
End Function

bueno, aunque se que el tema de las fechas da para rato, y ya (me) has dado unas cuantas explicaciones por el foro, aqui
va la consulta:

en la validacion del Case Is = 8 creia que esto me valdria para validar los bisiestos

If Not IsDate(.Text) Then .Text = Left(.Text, nl - 1)

y sin embargo, solo parece funcionar hasta el 99, a partir del '00' admite cualquier numero . Probando en la ventana
inmediato he visto que por ej. devuelve esto

?cdate("29/02/01")
01/02/2029

quiere esto decir que si existe una posibilidad de 'escape' para evitar el error cdate busca tira de otra configuracion
aunque no sea la regional ni la del propi vba, y no genera error?? eso es lo que me da la impresion, pero me parece
curioso

bueno, sobre todo es eso, una curiosidad mas, pero ya sabes ...

un saludo y hasta pronto
Ivan
Ivan
2007-06-27 02:28:53 UTC
Permalink
y se me habia escapado otra mas,

habria que cambiar elfinal del select case, pues para el 7 y el 8 no habia restringido la entrada a numeros. Habria que
cambiar desde el Case is=8 (incluido hasta el final del select por esto=

Case Is = 8
If Not IsNumeric(lt) Or (Left(.Text, 2) = "29" And Mid(.Text, 4, 2) = "02" And _
Val(Right(.Text, 2)) Mod 4 > 0) Then _
.Text = Left(.Text, 7)
Case Is > 8
.Text = Left(.Text, 8)
Case Else
If Not IsNumeric(lt) Then .Text = Left(.Text, nl - 1)
End Select

creo que asi ya quedaan cubiertas casi todas las posibilidades, a falta de problemas con teclado y a saber ....

un saludo
Ivan
Héctor Miguel
2007-06-27 03:40:01 UTC
Permalink
hola, Ivan !

1) comentarte que la *enmascarada* que le has dado a los textboxes me parece *genial*
[y como ya lo comentas] el unico inconveniente es que queda circunscrita para un orden de fechas dd/mm/aa

2) con relacion al comportamiento que describes de la funcion CDate(...) [y hasta donde se]...

a) sirve para convertir/verificar/validar datos-fecha *basada* en la configuracion regional del sistema

b) me atrae la atencion el ejemplo que expones de la ventana de inmediato: ?cdate("29/02/01") -> 01/02/2029
-> da la impresion de que en TU configuracion regional, el formato de fecha *corta* incluye 4 digitos para el a#o -?-

c) cuando CDate encuentra *conflictos*... que puede resolver... los resuelve *como Dios le de a entender* :))
lo que incluye invertir el orden de fecha *corta* mm/dd/aa <-> dd/mm/aa <-> aa/mm/dd
si NO los puede resolver... [simplemente] devuelve un error 13 "el tipo no coincide" [con alguna fecha *valida* para CDate] :-(

d) por ejemplo, en 'mi' caso, con una configuracion de fecha *corta* con el orden d/m/aa esto es lo que obtengo [inmediato]
? cdate("29/02/01") -> 2/1/29 <= OJO: cambio de: dd/mm/aa a: -> m/d/aa
? format(cdate("29/02/01"),"mm/dd/yyyy") -> 01/02/2029
? cdate("02/29/01") -> error 13 [no existe la fecha feb/29/2001]

2) fechas en excel y vba ???... [como ya lo expones, *da para rato*]...
como que hay que pensar en lo que *conlleve* las menores complicaciones posibles :))
es conveniente visitar la siguiente exposicion de manejos de fechas [de Stephen Bullen]:
-> http://www.bmsltd.ie/ExcelProgRef/Ch22/default.htm
[nota: aunque ya le debes conocer... es probable que le sirva tambien a OP] :))

saludos,
hector.

__ la consulta original __
Post by Ivan
bueno, aunque se que el tema de las fechas da para rato, y ya (me) has dado unas cuantas explicaciones por el foro
en la validacion del Case Is = 8 creia que esto me valdria para validar los bisiestos
If Not IsDate(.Text) Then .Text = Left(.Text, nl - 1)
y sin embargo, solo parece funcionar hasta el 99, a partir del '00' admite cualquier numero.
Probando en la ventana inmediato he visto que por ej. devuelve esto
?cdate("29/02/01")
01/02/2029
quiere esto decir que si existe una posibilidad de 'escape' para evitar el error
cdate busca tira de otra configuracion aunque no sea la regional ni la del propi vba, y no genera error?
eso es lo que me da la impresion, pero me parece curioso
Ivan
2007-06-27 15:54:02 UTC
Permalink
hola Hector,

muchas gracias de nuevo, tanto por tu ayuda como por este comentario
=>
Post by Héctor Miguel
que la *enmascarada* que le has dado a los textboxes me parece *genial*
aunque ten por seguro que si (realmente) tiene algo de genial la mayor
parte de la culpa es tuya (y no es falsa modestia). Aun asi no deja de
'ayudar' viniendo de tu parte.
Post by Héctor Miguel
b) me atrae la atencion el ejemplo que expones de la ventana de inmediato: ?cdate("29/02/01") -> 01/02/2029
tienes razon. Estoy harto de verlo y ni siquiera se me habia ocurrido
fijarme
Post by Héctor Miguel
c) cuando CDate encuentra *conflictos*... que puede resolver... los resuelve *como Dios le de a entender* :))
eso me parecia, con lo que, si no se quieren correr riesgos lo mas
seguro debe ser la opcion del DTPicker que mencionas
Post by Héctor Miguel
2) fechas en excel y vba ???... [como ya lo expones, *da para rato*]...
tan es asi que supongo que, aun revisando el enlace, por estos lares,
'volveremos' a molestarte mas de una vez con el tema
Post by Héctor Miguel
[nota: aunque ya le debes conocer... es probable que le sirva tambien a OP] :))
estoy convencido de que 'OP' tambien le sacara partido, tanto al
enlace como al hilo. Ya nos comentara


bueno, lo dicho, muchas gracias de nuevo y hasta pronto
Ivan
Feliciano
2007-06-27 18:38:20 UTC
Permalink
Hola a Mariano, Hector, Juan y a todos los demas:
Me parece que me habeis aludido con eso de OP [¿otros posteadores?] :)))
He seguido el hilo y, como experiencia personal (continuamente estoy
manejando fechas en distintos programas), creo que lo mejor es optar por
"op1: inserta a tu formulario ..... un control Calendar", que indica Hector.
Y con todo habra mas de uno que al seleccionar la fecha no se fije (por
ejemplo en el año) y ponga 27/06/2008 en vez de 27/06/2007 (o viceversa).


Saludos,

Feliciano.
--------------------------------------------------------------------------------
Post by Ivan
hola Hector,
muchas gracias de nuevo, tanto por tu ayuda como por este comentario
=>
Post by Héctor Miguel
que la *enmascarada* que le has dado a los textboxes me parece *genial*
aunque ten por seguro que si (realmente) tiene algo de genial la mayor
parte de la culpa es tuya (y no es falsa modestia). Aun asi no deja de
'ayudar' viniendo de tu parte.
Post by Héctor Miguel
b) me atrae la atencion el ejemplo que expones de la ventana de
inmediato: ?cdate("29/02/01") -> 01/02/2029
tienes razon. Estoy harto de verlo y ni siquiera se me habia ocurrido
fijarme
Post by Héctor Miguel
c) cuando CDate encuentra *conflictos*... que puede resolver... los
resuelve *como Dios le de a entender* :))
eso me parecia, con lo que, si no se quieren correr riesgos lo mas
seguro debe ser la opcion del DTPicker que mencionas
Post by Héctor Miguel
2) fechas en excel y vba ???... [como ya lo expones, *da para rato*]...
tan es asi que supongo que, aun revisando el enlace, por estos lares,
'volveremos' a molestarte mas de una vez con el tema
Post by Héctor Miguel
[nota: aunque ya le debes conocer... es probable que le sirva tambien a OP] :))
estoy convencido de que 'OP' tambien le sacara partido, tanto al
enlace como al hilo. Ya nos comentara
bueno, lo dicho, muchas gracias de nuevo y hasta pronto
Ivan
Ivan
2007-06-27 20:21:30 UTC
Permalink
Post by Feliciano
Me parece que me habeis aludido con eso de OP [¿otros posteadores?] :)))
He seguido el hilo y, como experiencia personal (continuamente estoy
manejando fechas en distintos programas), creo que lo mejor es optar por
"op1: inserta a tu formulario ..... un control Calendar", que indica Hector.
Y con todo habra mas de uno que al seleccionar la fecha no se fije (por
ejemplo en el año) y ponga 27/06/2008 en vez de 27/06/2007 (o viceversa).
Saludos,
Feliciano.
hola Feliciano,

como parece que no lo recuerdas, te pego un trozo de la conversacion
en la que yo me entere de lo que era OP (para que eches un ojo)

---------------------------------------------------------------------
----------------------------------------------------------------------
Hola Hector

: > [ahora que lo mencionas]... debo asumir que OP [probablemente]
esta
Post by Feliciano
utilizando macros o algun otro 'mecanismo' -?-
[definitivamente] OP necesita ofrecer detalles mas...
'significativos' > :D

Disculpa mi ignorancia. ¿Que es OP?. ¿Operacion de Pegado?.

Saludos,
Feliciano.
---------------------------------------------------------------------------­-----

hola, Feliciano !
Post by Feliciano
... Que es OP?. Operacion de Pegado?.
es un termino adoptado en las comunidades entre usuarios desde UseNet
significa: Original Post(er) [la consulta original o quien hizo la
consulta original/inicial] :))

saludos,
hector.
------------------------------------------------------------------------------------

Hola Hector :
Muchas gracias por la información.

Saludos,
Feliciano.

----------------------------------------------------------------------------------
------------------------------------------------------------------------------------


en cualquier caso estoy de acuerdo en que posiblemente lo mejor sea
usar controles especificos para las fechas

un saludo
Ivan
Feliciano
2007-06-28 19:27:42 UTC
Permalink
Hola Ivan:
Gracias por el recordatorio.
Espero que la proxima vez que vea OP recuerde lo que significa.

Saludos,

Feliciano.
--------------------------------------------------------------------------------
Post by Feliciano
Me parece que me habeis aludido con eso de OP [¿otros posteadores?] :)))
He seguido el hilo y, como experiencia personal (continuamente estoy
manejando fechas en distintos programas), creo que lo mejor es optar por
"op1: inserta a tu formulario ..... un control Calendar", que indica Hector.
Y con todo habra mas de uno que al seleccionar la fecha no se fije (por
ejemplo en el año) y ponga 27/06/2008 en vez de 27/06/2007 (o viceversa).
Saludos,
Feliciano.
hola Feliciano,

como parece que no lo recuerdas, te pego un trozo de la conversacion
en la que yo me entere de lo que era OP (para que eches un ojo)

---------------------------------------------------------------------
----------------------------------------------------------------------
Hola Hector

: > [ahora que lo mencionas]... debo asumir que OP [probablemente]
esta
Post by Feliciano
utilizando macros o algun otro 'mecanismo' -?-
[definitivamente] OP necesita ofrecer detalles mas...
'significativos' > :D

Disculpa mi ignorancia. ¿Que es OP?. ¿Operacion de Pegado?.

Saludos,
Feliciano.
---------------------------------------------------------------------------­-----

hola, Feliciano !
Post by Feliciano
... Que es OP?. Operacion de Pegado?.
es un termino adoptado en las comunidades entre usuarios desde UseNet
significa: Original Post(er) [la consulta original o quien hizo la
consulta original/inicial] :))

saludos,
hector.
------------------------------------------------------------------------------------

Hola Hector :
Muchas gracias por la información.

Saludos,
Feliciano.

----------------------------------------------------------------------------------
------------------------------------------------------------------------------------


en cualquier caso estoy de acuerdo en que posiblemente lo mejor sea
usar controles especificos para las fechas

un saludo
Ivan
Insumos
2007-06-29 17:42:03 UTC
Permalink
Hola Hector, Ivan y Feliciano:

Muchas gracias por todas las respuestas! La verdad que me sorprendió ver
todo el "hilo"que se generó por mi pregunta! Pero justamente esto es lo
positivo del foro.
En fin, les cuento como me fue con sus propuestas.
De las 2 opciones que me menciona Hector Miguel, la primera (DTPicker o un
control Calendar) no tengo idea como es ni como incorporarlo. Tampoco parece
que tenga el archivo ese que menciona instalado en todas las maquinas, lo
cual puede ser un problema para los usuarios.
La segunda opción (usar 3 Textbox) la experimenté con éxito, ya que esta más
al alcanze de mis conocimientos.
Después probé varias veces el enmascarador de Ivan, pero lamentablemente
presione la tecla que presione siempre me tira el mismo error "El tipo de
argumento de ByRef no coincide". Intente ver si podía ver cual podía ser el
error en el código y descubri que había olvidado poner la línea "Dim Borrar
As Boolean". Ahora anda perfectamente (hasta donde lo he probado). Es
genial!!
También hoy aprendí el siginificado del termino OP!
Bueno, les estoy infinitamente agradecido por todo.
Muchas gracias y saludos!!

Mariano
Post by Héctor Miguel
hola. Mariano !
... alguna manera de personalizar la forma en que los usuarios ingresen
datos en un TextBox?
Post by Héctor Miguel
... en un Userform... un TextBox... ingresar un dato... fecha...
... algo asi como una "mascara de entrada" (del tipo que hay en access) [...]
toma en cuenta que un control textbox [por su misma caracteristica]
'acepta' datos de todo tipo...
Post by Héctor Miguel
suponiendo que diferentes usuarios pudieran tener diferentes *costumbres*
en el orden de fechas...
Post by Héctor Miguel
y considerando que NO es 'el fuerte' de excel... andar 'enmascarando' las
entradas del usuario...
Post by Héctor Miguel
op1: inserta a tu formulario un control DTPicker o un control Calendar
op2: utilza TRES controles textbox para usarlos segun el orden de fechas
que vayas a controlas [dd/mm/aa <-> mm/dd/aa]
Post by Héctor Miguel
si cualquier duda... comentas ?
saludos,
hector.
p.d. el control DTPicker requiere que esta instalado y registrado...
-> el componente [+/- C:\Windows\System[32]\mscomct2.ocx]...
el control calendar requiere que este instalado y registrado...
-> el componente [C:\Archivos de programa\Microsoft Office x.0\Officexx\MSCal.ocx]
Loading...