Alternar colores en dbgrid
Hola, ya sé que esto es de lo más común, pero no consigo hacer que funcione, así que pregunto a los expertos.
A diferencia de lo habitual, que cambia de color por cada registro, en este caso es por uno de los campos. Aunque en la imagen aparece ordenado, lo normal es que no esté ordenado por ese campo (asiento), sino por el campo fecha. He usado una variable para guardar el contenido del último asiento, si el nuevo es distinto... se cambia de color. No sé si ya estoy encabezonado con esto, pero no consigo que salga bien. ¿Alguna idea? |
Hola Casimiro.
¿ Queres que los registros recién ingresados tengan otro color ? Edito: ( lo que vió Casimiro :o) Probá este código:
Saludos. |
Pero de ese manera va a alternar el color por cada registro y necesito que sea por cada vez que cambia de 'asiento'
|
jajaja... has editado tu respuesta y ahora he contestado a algo inexistente :)
|
Si me dí cuenta de mi confusión, pero no fuí tan rápido para modificar ... :)
Ya la agrego para que el hilo sea coherente... :) |
Es una simple consulta sql, nada más, y quiero que cambie de color cada vez que cambie el valor del campo asiento.
|
algo asi te puede servir?
lo uso para mostrar los articulos dados de baja. |
Gracias por tu aporte, Aleca.
En este caso no sirve, ten en cuenta que el color debe de cambiar cuando cambie el valor de un campo (asiento) y debe seguir con ese color hasta que cambie el valor ese campo. O sea, no es controlar únicamente el valor de un campo, sino también que no sea distinto (o sí lo sea) del registro anterior. Teniendo en cuenta que puede estar moviendo el cursor arriba o abajo, claro. |
A ver Casimiro..., proba con este código:
Tendrás que hacer algunos cambios y seguro lo puedas mejorar, pero en mis pruebas funcionó... Un saludo. |
Y no te vale así ? asientos pares un color, impares otro. En principio, si están ordenados por asiento, y teniendo en cuenta que no puede haber saltos ... Es igual que el código de ecfisa pero en lugar de usar Recno usas el valor del campo asiento. Un saludo |
Cita:
Cita:
|
A ver ahora
|
Gracias a ambos, las ideas ambos (ecfisa y Aleca) funcionan 'más o menos' bien.
Tienen el inconveniente que a veces se intercambian los colores, normalmente cuando se intercalan asientos de 1 sólo registro o cuando el número de asientos es un número impar. Más o menos es el problema que tenía yo con las pruebas que estaba haciendo, que no terminaba de "cuadrar". Bueno, sigo haciendo pruebas... |
Hola,
Pues a como lo entiendo para hacer lo que buscas deberías leer el campo en cuestión, y compararlo con el anterior leído. En caso de ser diferente, se altera el color y se pinta con ese. En otro caso sigue pintando por el defecto. Inicialmente se lee el primer registro y se decide el color inicial y se guarda en una variable auxiliar el valor del campo de este registro. Se pinta el primer registro con el color inicial. En lo sucesivo se va comparando el valor del campo con el de la variable auxiliar y en caso de ser diferente se guarda en variable auxiliar este valor, se altera el color. Para lograr la alteración entre dos colores yo tendría algo como esto: type ColorDoble = array[boolean] of TColor; De ese modo tendría los dos colores, por ejemplo:
Y de modo que cuando se cumpla:
Provocar un cambio en el color elegido por pintar, Algo como:
La idea no es ofrecer el código exacto. No tengo Delphi a mano, pero al menos orientar un poco las cosas. Saludos, |
Sí, la idea es esa, Delphius, aunque no termina de quedar bien.
Pienso que el problema puede venir por lo siguiente, pongo un ejemplo: empezamos pintando en blanco primer registro (asiento, suelen ser varios registros por asientos) nuevo registro... pintamos en negro nuevo registro... pintamos en blanco Se acabó... se posiciona al principio del dbgrid... y en memoria tenemos el último color, el blanco. Si ahora movemos el cursor... pintará de negro. O sea, estamos en el primer registro que era blanco y ahora lo pinta de negro, se están intercambiando los colores. Esto no ocurre cuando el número de asientos es par, acabamos en negro y se posiciona al principio, si movemos el cursor... pintará de blanco, que es el inicial, por lo tanto saldrá bien. El mismo problema sucede (no sé por qué) cuando hay asientos con un sólo registro, no será nunca habitual porque en contabiildad será siempre como mínimo 2 registros (apuntes) por asiento. En fin, puede que todo sea ya que estoy cansado de esto y mejor lo dejo para mañana con las ideas más claras :) Aunque seguiré un rato más :D |
¿Te refieres a que eso se descuadra cuando nos desplazamos por los registros, alterando el cursor?
¿No consideraste trabajar con otras dbgrids más especializadas? Quizá en una de esas hay alguna que te facilite la cosa. Yo también estoy en cero amigo. Saludos, |
Sí, los hay, pero cuando me encargaron este proyecto, lo primero que pregunté fue: ¿qué importe tiene presupuestado este proyecto?, y mis jefes se miraron las caras y contestaron: "cero", "nada".
Así que todo lo hago "a mano", lo más algunos componentes libres que los adapto a mis requerimientos. Luego me meten prisa diciendo que estoy tardando demasiado. |
La otra posibilidad que se ocurre es disponer de alguna estructura que almacene la distribución de colores basándose en la posición de los registros.
Por ejemplo: 1 - Blanco 3 - Rojo 10 - Blanco 11 - Rojo ... De ese modo diríamos que los dos primeros registros van de blanco, desde el 3ro al 9no va de rojo, el 10mo blanco... y así podríamos armar una lista almacenando un "ítem" cada vez que se detecte un cambio. Lo que se haría es que al lanzar la consulta, llevar un procedimiento que se encargue de analizar el conjunto de datos y genera esta estructura. Ya con esta estructura de datos se podría pintar los registros sin problemas. Se evaluaría en base al RecNo y de allí determinar el color que le corresponde. No se si se me entiende. Cada vez que se desplazace sobre el DBGrid o se repintase se examinaría esta estructura y se pintaría con el color correspondiente ya que tenemos toda la referencia. Saludos, |
Sí, te entiendo, aunque tener que llegar a estos extremos para hacer algo así es como se dice normalmente: matar moscas a cañonazos :)
En fin, ya sí me voy a dormir, que son casi las 6am y mañana (dentro de un rato) veré cómo lo hago. Gracias!!! |
No acabo de entender del todo el problema.
Entiendo perfectamente que puedas ordenar por fecha, pero no entiendo que sea sólo por ese campo. Bien dices que lo normal es que un asiento tenga dos apuntes mínimos, partida y contrapartida. Por lo tanto, bajo mi punto de vista, deberemos ordenar por fecha y asiento, ya que si no ( insisto que es una opinión mía ), la información no tiene sentido ( o lo pierde). Por lo tanto, si ordenas por FECHA y ASIENTO, las soluciones más simples que se han manejado creo que serían válidas. Corrigeme si me equivoco, ya que me interesa saber tu opinión. Saludos |
Casimiro, si me permites mi opinión, por que no usasun sistema de control por asientos, asignando al último digito del asiento, en el grid en el envento OnDrawColumCell... (no recuerdo el nombre exacto), como digo según sea este último digito, se rellene la fila de un color, lo cual te permite 10 colores diferentes del grid, ya sería mucha casualidad, dos asientos con la misma terminación para que sea el mismo color, y a unque esto ocurriese, podrias usar una variable local de 0 a 9, y cada vez que cambiaz de valor el asiento, cambias este valor y asignas color a la fila.
Espero se entienda mi idea. |
Cita:
El ATHLETIC a octavos de final en la copa !! :D:D:D:D:D:D:D:D:D:D |
Creo que el problema viene que, cuando pintamos la primera columna y preguntamos si el dato cambia, cambiamos el color (correcto); pero no podemos cambiar la variable que controla dicho cambio, porque entonces, el resto de las columnas volverían a cambiar.
He probado con esto y me ha funcionado:
Prueba a ver si te vale Un saludo |
le estuve dando un poco de vuelta al asunto y se armas un campo calculado que lleve el color en que se va a pintar (0-blanco, 1-Verde) y pintas de acuerdo al valor de ese campo.
ahora me lo mantiene estable. Saludos :) |
Cita:
|
Cita:
Saludos |
Cita:
Saludos PD: Cuando Casi vea el revuelo que ha formado igual le da un patatús. |
jajaja... bueeenooo... ¡¡¡ vaya jaleo !!! :D
Muchísimas gracias a todos :) Y sí, me piden que esté ordenado por fecha y luego por asiento/apunte, pero como cada asiento son varios apuntes... No sé, el tema no parece muy complicado, al contrario, pero sin embargo se está complicando. El asunto es que cada asiento son varios registros (apuntes) y cuando hay un número impar de asientos (y en otros casos que no he detectado el motivo) al terminar de pintar el último se queda con el color igual al primer registro, entonces al posicionarse en el primero e intentar mover el cursor a otro... lo pinta del color que no le corresponde. Se hace el select y pinta el dbgrid: asiento 1 apunte 1 azul asiento 1 apunte 2 azul asiento 1 apunte 3 azul asiento 2 apunte 1 rojo asiento 2 apunte 2 rojo asiento 3 apunte 1 azul asiento 3 apunte 2 azul <-- en memoria queda último color usado: azul Entonces se posiciona en el primer registro, y si muevo el cursor al siguiente, por ejemplo, al estar en azul... lo pinta e rojo. Alterna los colores. Cuando el número de asientos es par entonces no hay problema asiento 1 apunte 1 azul asiento 1 apunte 2 azul asiento 1 apunte 3 azul asiento 2 apunte 1 rojo asiento 2 apunte 2 rojo asiento 3 apunte 1 azul asiento 3 apunte 2 azul asiento 4 apunte 1 rojo asiento 4 apunte 2 rojo <-- en memoria queda último color usado: rojo Al posicionarse en el primero y movernos, cambia rojo por azul, que es el color correcto. En fin, que voy a hacerlo de otra forma, ya habéis dado pistas sobre eso, un campo calculado que vaya anotando cada vez que cambia de asiento y listo, luego se pinta del color según ese campo, (true/false ó 0/1). O cargarlo en un clientdataset o tabla en memoria y hacer lo mismo. Y de nuevo muchísimas gracias a todos :) Si se os ocurre una forma "normal" y que funcione... avisáis :) |
Pues no se, a mi me funciona lo que he probado. Creía que bastaría con adaptarlo un poco a tu programa y ya está
En fin, mi gozo en un pozo Saludos |
Cita:
|
Hola.
Dudo de su aplicabilidad... pero brinda un 'arco iris' de posibilidades... :)
Saludos. |
Creo que la solución sería:
Nota: Según la ayuda de Delphi 6: Cita:
|
Cita:
|
Al final he hecho lo siguiente:
El único problema es que la última parte donde asigno al campo sombra un valor, la pasa por alto y siempre es 0. He probado con AutoCalcFields en False y en True, con el mismo resultado. Puede ser porque estoy probando con unos componentes que descienden de FreeIB. Si alguien lo puede probar con otros componentes DataSets que informe si le funciona. |
Casimiro te pongo unas imágenes de lo que te comentaba anteriormente
Ten en cuenta que usado colores a lo loco, deberías usar, un color y derivar luego de este cambiado sólo uno de los valores de la rgb para que fueran tonalidades mas consecutivas. La parte del código que creo te puede interesar es esta
Como puedes comprobar use mi BD de pruebas y el Campo por el que hago la comprobación es LOTE, en tu caso sería ASIENTO |
Bueno siento ser pesado, pero con unos pequeños cambios os muestro lo que digo.
Código Cambiado
|
mmm... comparto la opinión de casimiro, las soluciones presentadas son como cañonazos.
Por mi parte creo que este problema necesita nada más que una especie de switch, o alternador. Una simple variable booleana que controle el color utilizado.
BoolSwitch y UltimoValor son variables privadas del formulario. Creo que con este código se pudiera solucionar el problema. Sino pues creo que de él se puede partir. Saludos, Chris |
Estoy siguiendo este hilo con interés. En algún momento voy a verme en la tesitura de implantar algo similar. Y creo que el principal problema no es "pintar" las filas cuando se "cargan" los datos. Eso, con los sistemas de switch que se van comentando es fácil. Yo creo que el principal problema es la navegación, el hacer click en cualquier sitio. Creo que si en el registro de la tabla no hay una información que nos indique si hay que pintar esa celda de un color o de otro, los valores del "switch" no van a ser válidos. Mi opinión en que "debe haber una información en el registro que indique de color hay que pintar esa celda".
Saludos, |
Cita:
Así que creo que la única opción es la del campo que indique el color o algo así. Pero todavía se aceptan más propuestas... habrá premio al que obtenga el resultado correcto :) |
Pues yo no veo otra salida amigo. Ya sea que se lleve una estructura fuera o en el mismo dbgrid con un campo calculado y el uso de técnicas "flags booleanas" es necesario contar con un artilugio para llevar ese conteo y poder determinar con que color pintar cada registro.
Saludos, |
La franja horaria es GMT +2. Ahora son las 15:39:49. |
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi