Saltar al contenido

FORMULARIO DE LOGIN


Recommended Posts

publicado

Hola a todos,

Tengo el siguiente problema: He creado un formulario para grabar contactos dentro de una hoja de datos llamada "CONTACTOS" y cada vez que introduzco algún dato incorrecto, de manera alguna el formulario vuelve a grabar el mismo registro tantas veces como haya fallado dentro de la hoja de datos.

Muestro por aquí mi formulario...

1.thumb.jpg.6b27d4814a9cc3c9a46e9f0eff5ba196.jpg

Como se puede observar en la imagen adjunta, tiene un casillero inicial para elegir el tipo de contacto ("Proveedor" o "Cliente") y el resto de los datos están dispuestos en modo multipágina. "Denominación" para grabar los datos fiscales, "Domiciliación" para los datos de localización y "Comunicación" para los datos de contacto.

Bueno, eso es lo de menos...

Fíjaros lo que me pasa. Lo explíco con un ejemplo: Supongamos que introduzco una cadena de caracteres en el casillero del "Código Postal", y me salta un mensaje de alerta que me notifica del error cometido, para lo cual vuelvo a introducir de nuevo los datos esta vez sí en formato numérico.

2.thumb.jpg.5d727e8385a38458e9a8766c44ac85f3.jpg

Nos vamos a la página de contactos. Y podemos observar que el mismo registro ha sido grabado dos veces. Esto se debe porque me he equivocado una vez al introducir un código postal con caracteres de texto en vez de con números. Si me hubiera equivocado tres veces, se grababa el mismo dato tres veces, y si fueran mil, pues mil veces...

3.thumb.jpg.06f61e095167ead87f0f844cfc778da9.jpg

Adjunto mi código aquí...

Option Explicit


Private Sub UserForm_Initialize()

   ' Adjuntamos la lista de perfiles...
   With tbContacto
      .AddItem "Proveedor"
      .AddItem "Cliente"
      .AddItem "Otro..."
   End With

   ' Y adjuntamos la lista de países...
   With tbPais
      .AddItem "Alemania"
      .AddItem "España"
      .AddItem "Estados Unidos"
      .AddItem "Francia"
      .AddItem "Gran Bretaña"
      .AddItem "Países Bajos"
   End With

End Sub


Private Sub cbGrabar_Click()

Application.ScreenUpdating = False

   ' Tratamos los errores de la aplicación ofimática...
   On Error GoTo error

   ' Declaramos las variables de ámbito local...
   Dim fila As Long
   Dim deseaContinuar As Byte

inicio:
   ' Comprobamos que el cuadro combinado del código postal no está vacío...
   If (tbContacto = "Cliente" And tbCodigoPostal.Value = "") Or _
      (tbContacto = "Cliente" And IsNumeric(tbCodigoPostal.Value) = False) Then

      FormularioDeContactos.Hide
      MsgBox Prompt:="Upps, parece que hubo un error... Por favor, debe introducir un código postal " & _
                           "para ubicar al cliente.", _
             Buttons:=vbExclamation, _
             Title:="                                     CODIGO POSTAL INCORRECTO"
      FormularioDeContactos.Show
      GoTo inicio

   ' Comprobamos que el cuadro combinado de la provincia no está vacía...
   ElseIf tbProvincia.Value = "" Then

      FormularioDeContactos.Hide
      MsgBox Prompt:="Upps, parece que hubo un error... Por favor, debe introducir una provincia " & _
                           "para ubicar al " & _
                           IIf(tbContacto.Value = "Proveedor", "proveedor.", "cliente."), _
             Buttons:=vbExclamation, _
             Title:="                                          PROVINCIA INCORRECTA"
      FormularioDeContactos.Show
      GoTo inicio

   ' Comprobamos que el cuadro combinado del país no está vacío...
   ElseIf tbPais.Value = "" Then

      FormularioDeContactos.Hide
      MsgBox Prompt:="Upps, parece que hubo un error... Por favor, debe introducir un país " & _
                           "para ubicar al " & _
                           IIf(tbContacto.Value = "Proveedor", "proveedor.", "cliente."), _
             Buttons:=vbExclamation, _
             Title:="                                                 PAIS INCORRECTO"
      FormularioDeContactos.Show
      GoTo inicio

   End If

   ' Grabamos toda la información actual dentro de la hoja de contactos...
   fila = Sheets("CONTACTOS").Range("A1048576").End(xlUp).Row + 1

   With Sheets("CONTACTOS")
      .Cells(fila, 1) = tbContacto.Value           ' Tipo de contacto
      .Cells(fila, 2) = tbCodigo.Value             ' Código (PK)
      .Cells(fila, 3) = tbDniCif.Value             ' DNI / CIF
      .Cells(fila, 4) = tbNombre.Value             ' Nombre y apellidos / Nombre comercial
      .Cells(fila, 5) = tbNombreFiscal.Value       ' Nombre fiscal
      .Cells(fila, 6) = tbDireccionPostal.Value    ' Dirección postal
      .Cells(fila, 7) = tbCodigoPostal.Value       ' Código postal
      .Cells(fila, 8) = tbPoblacion.Value          ' Población
      .Cells(fila, 9) = tbProvincia.Value          ' Provincia
      .Cells(fila, 10) = tbPais.Value              ' País
      .Cells(fila, 11) = tbWeb.Value               ' Sitio web
      .Cells(fila, 12) = tbWeb2.Value              ' Otros sitios web
      .Cells(fila, 13) = tbEmail.Value             ' Correo electrónico
      .Cells(fila, 14) = tbTelefonoFijo.Value      ' Teléfono fijo
      .Cells(fila, 15) = tbTelefonoMovil.Value     ' Teléfono móvil
      .Cells(fila, 16) = tbFax.Value               ' Fax
   End With

   ' Ocultamos el formulario de contactos...
   FormularioDeContactos.Hide

   ' Mostramos un mensaje de alerta para notificar al usuario de que el registro se ha grabado correctamente...
   deseaContinuar = MsgBox(Prompt:="El contacto ha sido grabado correctamente." & vbCr & _
                                   "¿Desea continuar grabando datos?", _
                           Buttons:=vbYesNo + vbInformation, _
                           Title:="                                  AVISO IMPORTANTE")

   ' Si la respuesta es afirmativa...
   If deseaContinuar = vbYes Then

      ' Mostramos el formulario de contactos...
      FormularioDeContactos.Show

   ' Pero si la respuesta es negativa...
   Else

      ' Activamos la hoja correspondiente...
      Sheets("CONTACTOS").Activate

      ' Salimos del procedimiento...
      GoTo salir

   End If

salir:
   ' Y salimos del procedimiento...
   Exit Sub

error:
   ' Mostramos por pantalla el tipo de error y la descripción del mismo...
   MsgBox Prompt:="Upps, parece que hubo un error... Por favor, póngase directamente " & _
                  "en contacto con su programador informático." & vbCr & vbCr & _
                  "El error producido es: [" & Err.Number & "] - " & Err.Description, _
          Buttons:=vbCritical, _
          Title:="                                               AVISO IMPORTANTE"

   ' Sacamos el error fuera de la pila de errores...
   Resume salir

End Sub


Private Sub cbSalir_Click()

   ' Cerramos el formulario de contactos...
   Unload FormularioDeContactos

End Sub


Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)

   ' Habilitamos única y exclusivamente el control a través de los botones del formulario...
   If CloseMode = vbFormControlMenu Then
      MsgBox Prompt:="Por favor, utilice los botones 'Grabar' y 'Salir' para navegar por el formulario " & _
                     "de contactos.", _
             Buttons:=vbExclamation, _
             Title:="                                              AVISO IMPORTANTE"
      Cancel = True
   End If

End Sub

Normalmente, esto lo solucionaba con la propiedad variable.Cancel o variable.Default con valor igual a "True". Es decir, algo como esto...

...
	If (tbContacto = "Cliente" And tbCodigoPostal.Value = "") Or _
       (tbContacto = "Cliente" And IsNumeric(tbCodigoPostal.Value) = False) Then

      FormularioDeContactos.Hide
      MsgBox Prompt:="Upps, parece que hubo un error... Por favor, debe introducir un código postal " & _
                           "para ubicar al cliente.", _
             Buttons:=vbExclamation, _
             Title:="                                     CODIGO POSTAL INCORRECTO"
      FormularioDeContactos.Show

	  tbCodigoPostal.Default = True		' Reestablecemos la variable en el valor inicial por defecto...

      GoTo inicio
...

Por aquí continúa el código anterior...

Pero en esta ocasión, no me funciona.

Creo haberme explicado bien. Si necesitáis más detalles, dejadme un comentario.

Necesito que alguien me arroje algo de lucidez sobre este tema, porque el formulario funciona correctamente tal y como habéis visto. El problema es que cuando alguien comete un error al grabar los datos, es como si el mismo registro se grabara tantas veces como errores cometiera al grabar el registro.

 

Muchísimas gracias por vuestro tiempo.

publicado

Hola

Te recomiendo usar el evento "change" del textbox, de tal manera que solo acepte valor numérico; investiga un poco sobre lo que te comento, aquí mismo en el foro, puedes buscar

Otra cosa por favor sube un archivo con el problema y el formulario, pues por lo menos yo, no estoy dispuesto siempre a ver todo el testamento e imágenes que has agregado al tema

 

Saludos!

publicado
Hace 10 horas, Gerson Pineda dijo:

Otra cosa por favor sube un archivo con el problema y el formulario, pues por lo menos yo, no estoy dispuesto siempre a ver todo el testamento e imágenes que has agregado al tema

Normalmente lo hago así para que la gente que lea el mensaje a través del foro, pueda ver el código sin necesidad de descargarse ningún fichero que pueda estar contagiado por algún virus, pues ya bastante tenemos con lo que tenemos... Jeje.

 

De todos modos y si así lo prefieres, te adjunto aquí el fichero:

Libro1.xlsm

 

SUPUESTO: Prueba a introducir una cadena de caracteres o dejar vacío el cuadro de texto del "Código Postal", y ya verás como el mismo registro se graba dos veces dentro de la hoja "CONTACTOS".

Si erráramos tres veces, pues se grabaría tres veces, y así sucesivamente...

 

Normalmente, ya digo que esto lo solucionaba con la propiedad .Cancel o .Default = True.

Pero en esta ocasión no funciona...

 

Gracias por tu tiempo.

publicado

Ese comportamiento lo provocas tu con la sentencia GoTo inicio, que se ejecuta tantas veces como errores encuentra al meterte en un bucle.

Sustituye GoTo inicio por Exit Sub y problema resuelto.

En otro orden de cosas, Microsoft se molestó en poner una cruz en la parte superior derecha para cerrar los formularios, no se porqué esa manía de deshabilitar ese botón y no me digas que es por seguridad, ya que es más fácil pulsar el botón Salir por error, que pulsar sobre la cruz.

 

publicado

Hola!

A mi gusto lo tienes mal planteado, te lo explico:

Si vas a utilizar multipage es preferible que los botones estén asignados por cada page, si no entonces debes asegurar que por cada page activo, el único botón "Grabar" audite los controles si están vacíos o según la restricción que dispongas, de lo contrario puedes usar los eventos del control, de manera que escriban en ellos lo que tu requieras

 

Saludos 

publicado
Hace 7 horas, Antoni dijo:

Sustituye GoTo inicio por Exit Sub y problema resuelto.

Solucionado! A veces me rompo la cabeza en encontrar la solución más complicada, y resulta ser la más fácil.

Muchas gracias, @Antoni. Funciona perfectamente, tal y como dices.

 

Hace 2 horas, Gerson Pineda dijo:

Si vas a utilizar multipage es preferible que los botones estén asignados por cada page, si no entonces debes asegurar que por cada page activo, el único botón "Grabar" audite los controles si están vacíos o según la restricción que dispongas, de lo contrario puedes usar los eventos del control, de manera que escriban en ellos lo que tu requieras

@Gerson Pineda, supongo que te refieres a aplicar un evento Private Sub textbox_Change(), sobre cada uno de los cuadros de texto. Efectivamente al tratarse de una multipágina es necesario que el evento Change reconozca que cada página correspondiente este activa.

Es una buena idea, pero no sé cómo hacerlo...

 

publicado
Hace 4 horas, paikerr dijo:

Efectivamente al tratarse de una multipágina es necesario que el evento Change reconozca que cada página correspondiente este activa.

Es una buena idea, pero no sé cómo hacerlo...

En efecto, y es posible, trata de estudiar a fondo el MultiPage, a mi ese control me ha encantado, lo he utilizado en proyectos para clientes, es bastante cómodo y ventajoso, porque te ahorra esa cantidad de formularios individuales y luego tienes que esconderlos o volverlo a llamar... en fin 

 

Saludos

Archivado

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

  • 109 ¿Te parecen útiles los tips de las funciones? (ver tema completo)

    1. 1. ¿Te parecen útiles los tips de las funciones?


      • No
      • Ni me he fijado en ellos

  • Ayúdanos a mejorar la comunidad

    • Donaciones recibidas este mes: 0.00 EUR
      Objetivo: 130.00 EUR
  • Archivos

  • Estadísticas de descargas

    • Archivos
      189
    • Comentarios
      99
    • Revisiones
      29

  • Crear macros Excel

  • Mensajes

    • Hola Buenas Noches, Me podrán ayudar a resolver un problema con una planilla que tengo, les comento brevemente. Tengo un archivo que cuenta con 2 hojas, la primera se llama "Movimientos" que básicamente muestra los productos con quiebres que se presentan y la hoja "Producción" que como su nombre lo dice son las producciones de cada producto según fecha de creación. Lo que necesito es lo siguiente: Cada vez que agregue una producción en la hoja "producción", debo ingresar el código creado su cantidad y lote respetivamente, además de la fecha en que se realiza la producción, en caso que sea mayor a las 12:00 se considera PM sino AM. Lo complejo es acá en la otra hoja llamada Movimientos: Esta hoja contiene una columna que se llama "Saldo", que básicamente es la diferencia de lo producido vs el quiebre en esa fecha. Una columna llamada "Cumple", que significa que ese pedido lleva si o no el producto con quiebre. Y una columna "Se preparo", que es si el pedido se preparo o no. Lo complicado viene acá es que si la fecha de la producción que ingrese en la hoja "Produccion", se hace después de la fecha de la hoja movimientos no me debe contar esa producción para efecto de la columna Saldos, si la fecha es igual o menor si se considera y ese saldo que queda disponible se puede ocupar para futuros ingresos de pedidos. Otra conducción es que las producciones siempre se deben asignar al pedido más antiguo de ese código salvo que la fecha de entrega ya haya pasado. La columna "Cumple" es básicamente para poder generar un KPI donde me indique cuales producciones se cumplieron con el plazo y cuales No. Espero me puedan ayudar ya que tengo la siguiente formula pero no sirve ya que me toma las unidades totales y no cumple con la restricción del horario. =SUMAR.SI(Produccion!A:A; $A2; Produccion!C:C) - SUMAR.SI.CONJUNTO($E$2:$E2; $A$2:$A2; A2)) Muchas gracias. Ejemplo..xlsx
    • Hola a ambos, Prueba con: =BYROW(G5:G6;LAMBDA(x;UNIRCADENAS(" - ";1;FILTRAR(E5:E10;B5:B10=x)))) Saludos,
    • Si tienes office 365 puedes usar algo como FILTER ó TEXTJOIN y si no tienes, entonces se puede jugar con las formulas, pero no te recomiendo mucho si son muchos datos, de todas maneras te dejo una fórmula y en vba, ya tu decides cual ocupar, vale Saludos BUSCAR.xlsm
    • Buenos días mis estimados Familia ayudaexcel,  Favor quisiera solicitar su gentil soporte con lo siguiente: Necesito una formula que al buscar encuentre el valor inicial de busqueda y dea todo los resultados encontrado en una celda como ejemplo. si este producto tienes 4 cantidades esta al hacer una formula de busqueda me dea el resultado de las 4 en una celda, dejo el adjunto a espera de su gran soporte.   BUSCAR.xlsx
    • Saludos Sr @Israel Cassales espero este bien quise verificar bien su solución y que las modificaciones que hice funcionarán adecuadamente y al respecto debo decir que su aporte es excelente ya que no solo me ayudo a resolver lo que necesitada sino que también me ayudo a solventar dos cosas más por lo cual estoy muy agradecido 
  • Visualizado recientemente

    • No hay usuarios registrado para ver esta página.
×
×
  • 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.