Botón para dar de baja registros sin eliminarlos
Es una pregunta para Jacinto Trillo
Hola Jacinto
Querría usar un botón para dar de baja registros, sin eliminarlos, mediante los valores si/no del campo “EXISTENTE” en el Formulario Libros.
Si se da de baja el registro debe aparecer en color rojo y si está activo se deja en blanco.
Me gustaría hacerlo esto con VBA sin usar el formato condicional, te lo comento porque siempre que puedo prefiero evitar las herramientas de access porque pueden variar de una versión a otra, en cambio el código en su mayor parte me vale para cualquier versión y lo veo más flexible para modificar cosas, si no es problema...
Había pensado llamar a una función del tipo:
Public Function RegistrosBaja (Frm as form, cancel as integer) as boolean
For each Ctrl in Frm.Controls
if Typeof Ctrl is textbox or Typeof Ctrl is ComboBox then
IF ... Then
Ctrl.BackColor =vbRed
En la claúsula IF...
Me gustaría indicar que no se ponen en rojo todos los controles tipo textbox o combobox sino solo aquellos controles que tengan como origen del control el campo de la tabla.
Ésta sería la clave que solo se coloren en rojo los controles, que sean los campos de la tabla.
Podría hacer lo de poner prefijos o sufijos a los nombres de los controles para diferenciarlos... Pero tal vez hay alguna forma de indicar que...
Se quiere realizar una acción x en controles de tipo textbox o combobox pero solo en aquéllos que tengan como origen del control el campo de la tabla, origen del formualrio. Claro... Esto pasado a VBA que es precisamente lo que no sé hacer.
1 Respuesta
Rafa: Lo que comentas, y que yo sepa no se puede hacer en Formularios continuos con VBA. Ya que el color de fondo te lo aplicaría a todas las filas.
Si se puede hacer en Access 2013 o 2016 lo ignoro. En lo que te refieres del Formato condicional, no estaba en las primeras versiones de Access, y por lo util que es no creo que Microsoft lo quite, pero todo podría ser.
He visto metodologías de varios especialistas que recurren a elementos auxiliares para distinguir Filas de los Formularios continuos y entre ellas está un ejemplo que Neckkito tiene en su Web :
http://siliconproject.com.ar/neckkito/index.php/ejemplos-explicados/todos/93-ejemplos-explicados/ejemplos-de-formularios/250-formulario-continuo-multicolor
Es lo más aproximado a lo que creo que buscas. Saludos >> Jacinto
Hola Jacinto
No lo quiero aplicar en el Form "FiltroGeneral" de la Bd sino en el FormLibros.
Este formulario no es tipo "formularios continuos" sino "único Formulario". Me imagino que podremos aplicar un código y luego anularlo cada vez que activemos un nuevo registro. Como te digo es para el formLibros que es "único formulario".
... Y al margen del color está lo del tema de que se aplique a solo aquellos controles que tengan como origen del control el campo de la tabla a la que está vinculada el form.
Había pensado poner en la claúsula If algo como:
If Ctrl.Controlsource = "Select * From LIBROS" Then
Para referirme que la acción de colorear se aplique solo a los controles que tienen como origen el campo de la tabla pero no me funciona.
Quedaría algo como...
Public Function RegistrosBaja (Frm as form, cancel as integer) as boolean
For each Ctrl in Frm.Controls
if Typeof Ctrl is textbox or Typeof Ctrl is ComboBox then
IF ... Then
Ctrl.BackColor =vbRed
Un saludo y ya me comentas
Rafa: Esto cambia las cosas. Había interpretado que era en el Formulario del Filtro general que es continuo. Miro de nuevo el tema y te comento. Saludos >> Jacinto
Rafa: La función que a continuación te cito es para que esté en un Módulo Estándar, y así poder llamarla desde cualquier Formulario con un CheckBox que en éste código cito como >> ChkDeSondeo, y cuyo origen puede ser un Campo Si/No de la Tabla.
Public Function ColorControlesSegunCheck(Frm As Form, EstadoCheck As Boolean) As Boolean
'Primero sondeo el valor EstadoCheck
If EstadoCheck = True Then
ColorControlesSegunCheck = True
Else
ColorControlesSegunCheck = False
End If
'Recorremos los Controles para colorearlos según el Valor de la Función
For Each Ctrl In Frm.Controls
'Voy directo al TipoTextBox y ComboBox
If TypeOf Ctrl Is TextBox Or TypeOf Ctrl Is ComboBox Then
If ColorControlesSegunCheck = True Then
Ctrl.BackColor = RGB(255, 255, 255)
Else
Ctrl.BackColor = RGB(255, 0, 0)
End If
End If
Next Ctrl
End Function
Para llamar a ésta Función desde un Formulario, se el de Libros u otro no continuo.
En el Evento Form_Current pones >>
Call ColorControlesSegunCheck(Me, Me.ChkDeSondeo)
También la he preparado para que puedes aprovecharla en otras acciones, sean de formato u otra cosa, haciendo igualmente en ese evento o en otro>>
If ColorControlesSegunCheck(Me, Me.ChkDeSondeo) = True Then
'Unas Acciones
Else
'Otras Acciones
End If
Lo pruebas y me comentas. Saludos >> Jacinto
Hola Jacinto
La función va muy bien y cumple su objetivo de colorear en rojo el registro dado de baja... pero el problema es que pone en rojo todos los textbox, todos...
If TypeOf Ctrl Is TextBox Or TypeOf Ctrl Is ComboBox Then
----------------------------------------------------------------------------------------------------------------------------------------
El objetivo principal que te comentaba en la pregunta es que necesitaba que solo pusiera en rojo los textbox o combos, que tienen como origen el campo de la tabla LIBROS y dejara sin colorear el resto de textbox o combos, que hay en un formulario "FormLibros" y que no tienen su origen en un campo de la tabla.
Por eso te decía si valía de pista para resolverlo, lo de la propiedad controlsource y añadir esta línea o similar a la función:
If Ctrl.Controlsource = "Select * From LIBROS" Then ...
Lo que quiero decir es que si el origen del control (controlsource) es un campo de la tabla libros ("Select * From LIBROS" Then ...) entonces... pero esta parte del "select..." creo que no me vale.
----------------------------------------------------------------------------------------------------------
Sería para añadirla a esta parte de la función que me comentas.
...
If TypeOf Ctrl Is TextBox Or TypeOf Ctrl Is ComboBox Then
If ColorControlesSegunCheck = True Then
If Ctrl.Controlsource = "Select * From LIBROS" Then
Ctrl.BackColor = RGB(255, 255, 255)
Lo que quiero es que no ponga en rojo todos los textbox o combobox como hasta ahora sino solo los objetos, los controles que tienen como origen un campo de la tabla Libros con la que está vinculado el FormLibros.
Un saludo y gracias
Rafa: Ciertamente si que has mencionado varias veces lo de ... solo los objetos, los controles que tienen como origen un campo de la tabla Libros..., y he creido que era una confusión, porque "Todos los Controles" del Formulario de Libros según la BD que yo tengo tienen como Origen la Tabla Libros.
Si es que eso no es así me comentas. Saludos >> Jacinto
Disculpa Rafa: He cometido un error, porque algún control que no pertenece a la Tabla Libros, que son los señaladores de Registros y alguno independiente.
Si te referías a esoa me comentas y vemos como evitar que se coloeen. Saludos >> Jacinto
Hola Jacinto
Ahora hay varios textbox en el FormLibros (de la BD en pruebas que me actualizaste, en el archivo "ZBiblioRafael_03") que no tienen su origen de control en los campos de la tabla como:
TxtNumRegistros (en el encabezado del formulario)
TxtNulos y TxtNoNulos (en el detalle del formulario)
Rec y NRec (en el pie del formulario)
Estos controles son también textbox y no tienen su origen en el campo de la tabla Libros... pero también se ponen en rojo ya que ahora mismo la función se aplica a todos los textbox o combos cuando necesitaría que solo se aplicase a los que el "controlsource" sea un campo.
En todo caso aunque ahora mismo no estuvieran estos textbox en el form, en el futuro seguro que añadiría algun textbox o combo o lista sin origen del control... al formulario y se me presentaría el mismo problema...
Sería solo creo cambiar esta línea pero no me sale
If Ctrl.Controlsource = "Select * From LIBROS" Then
Un saludo y perdona la reiteración... es que no entiendo qué pongo mal en esta línea para que no haga lo que necesito.
Vaya... Se han cruzado las respuestas je je
Lo único... que más que excluir de la acción (poner en rojo) los textbox o controles que no tienen su origen en un campo... con un "if not txt. then" lo que preferiría es añadir a la función que solo colorease en rojo los que tienen como origen del control un campo de la tabla LIBROS.
Un saludio y gracias por la ayuda
Rafa: Lo tengo claro ahora y como te comentaba ha sido un error de atención, pero es lógico por las goteras de la edad. Esta noche ya es un poco tarde. Lo miro y te contesto mañana.
Saludos >> Jacinto
Rafa: Para distinguir de color los Controles "Independientes", tienes dos maneras.
Por código VBA, pones debajo del último Next Ctrl >>
'Para colorear de otro Color los Controles Indepencentes. En éste caso Naranja
For Each Ctrl In Frm.Controls
'Voy directo al TipoTextBox y ComboBox
If TypeOf Ctrl Is TextBox Or TypeOf Ctrl Is ComboBox Then
If Ctrl.ControlSource = "" Then
'Ctrl.BackStyle = 1
Ctrl.BackColor = RGB(255, 255, 0)
End If
End If
Next Ctrl
Te pongo la línea de Ctrl. BackStyle comentada, porque si quieres utilizar el Método directo de no colorear, dejas esa línea comentada y en los que quieras, pones la Propiedad del Fondo en Transparente y no te colorea.
Y también puedes optar por no poner ese Código y en los Controles que no quieras colorear, simplemente le pones la Propiedad del fondo y el VBA no te actuará. Haz pruebas con algunos Controles de los que tengan origen de Datos.
Esto es válido para éste y todos los casos y te lo comento por si usas el Código en otro Formulario que tenga controles con fondo Transparente, no te actuará y pensarás que tienes un error.
Espero que con ésto quede resuelto el tema. Saludos >> Jacinto
Hola Jacinto
Creo que me entendiste al revés. En realidad no buscaba colorear automáticamente con código, los controles independientes con...
If Ctrl.ControlSource = "" Then
1º sino justo al contrario, colorear los controles que tienen como origen del control los campos de la tabla. Habría que cambiar solo la línea anterior en esta función:
Public Function ColorControlesSegunCheck(Frm As Form, EstadoCheck As Boolean) As Boolean
'Primero sondeo el valor EstadoCheck
If EstadoCheck = true Then
ColorControlesSegunCheck = True
Else
ColorControlesSegunCheck = False
End If
'Recorremos los Controles para colorearlos según el Valor de la Función
For Each Ctrl In Frm.Controls
'Voy directo al TipoTextBox y ComboBox
If TypeOf Ctrl Is TextBox Or TypeOf Ctrl Is ComboBox Then
If ColorControlesSegunCheck = false Then
If Ctrl.ControlSource = "" Then (hay que poner los controles cuyo origen son campos)
Ctrl.BackColor = RGB(255, 255, 255)
End If
End If
end if
Next Ctrl
End Function
En el Evento Form_Current pones >>
Call ColorControlesSegunCheck(Me, Me.ChkDeSondeo)
2º El otro problema que se me presenta en la función que me indicas una vez resuelto lo de If Ctrl.ControlSource = "" Then...
es que al usarla en el evento Form_current, al dar de baja el registro con el checkbox y colorear los controles cuyo origen del control es un campo de la tabla... cuando activo otro registro ya aparece coloreado esté o no de baja, habría que aplicar una función para poner todos los controles sin color cada vez que activo el registro y luego aplicar de nuevo la función que me propones.
Algo como...
- Call ControlesSinColor (Tendríamos primero al activar cada registro poner de nuevo todos los controles sin color y luego aplicar la función que me comentas)
- Call ColorControlesSegunCheck (me, me.ChkDeSondeo)
Podrías indicarme cómo haríamos esta otra función de "ControlesSinColor" para dejar todos los controles sin color...
Un saludo y ya me dices
Rafa:
Después de hacer algunos ensayos, el método que he encontrado más simple, es la idea original de Identificar los Controles para cualquier acción.
Mis saludos
Jacinto
Hola Jacinto
Encontré esta solución y funciona:
For each Ctrl in Frm.Controls
If typeof Ctrl is textbox or Typeof Ctrl is combobox then
If ColorControlesSeguncheck = true then
Ctrl.backcolor = vbwhite
end if
If ColorControlesSegunCheck = false then
if Len(Ctrl.ControlSource) > 0 then (así nos referimos a controles con origen en campo)
Ctrl.BackColor = vbred
end if
end if
end if
Next
End function.................................Como ves he cambiado lo de antes por esto:if Len(Ctrl.ControlSource) > 0 thenpara referirme solo a aquéllos controles cuyo origen es un campo de la tabla y solo ésos son los que pondré de rojo al dar de baja.
Lo único comentarte dos cosas:¿Qué es mejor poner?...Ctrl.BackColor = vbred O Ctrl.BackColor = RGB (255,255,255)y los segundo ¿cómo quedaría el código que te he puesto con varias if, usando el Select Case?Con esto podemos cerrar la respuesta... Un saludo y gracias
Rafa: Lamento desilusionarte, pero esa solución de:
if Len(Ctrl.ControlSource) > 0 then para referirme solo a aquéllos controles cuyo origen es un campo de la tabla y solo ésos son los que pondré de rojo al dar de baja.
Con eso te estás refiriendo a lo que te estás refiriendo y no a otra cosa.
A mi modo de ver, eso te detecta los Controles que tienen "Origen de Control", sea de una Tabla, de una Consulta o "Directamente Formulados"
Esa solución la descarté porque estoy convencido que es como te comento, pero puedo andar equivocado.
Añade un control y le pones cualquier Formula. Ejemplo = Fecha()
Cuando tenga un momento lo probaré.
Mis saludos. >> Jacinto
- Compartir respuesta