Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Alternar colores en dbgrid (https://www.clubdelphi.com/foros/showthread.php?t=71698)

Casimiro Notevi 06-01-2011 22:51:55

Buenísima la idea, lo he probado y funciona perfectamente :) .... ... ... peeerooooo... ... ... no me sirve :(
No puedo usar un procedimiento almacenado porque en pantalla el usuario selecciona una serie de opciones de filtro y el select sql se crea dinámicamente :(
No se me ocurre cómo pasar ese select a un procedimiento, salvo crear el procedure dinámicamente, lanzarlo y borrarlo después. Hacer un "create or alter procedure"... ... ... puede ser

Código Delphi [-]
procedure TFapuntes.CargarDiario(iParametro: integer);
var
  cSql : string;
begin
{ TODO 3 -oampc -cControlar : Hace falta controlar los tipos de usuarios, por si tiene permisos para verlos o no. }
  DMapuntes.QRdiario.Close;
  cSql := 'select * from tbapuntes where codigoempresa= :codigoempresa and ejercicio= :ejercicio ';
  case iParametro of
    0,1,2,3,4: cSql := cSql + ' and codigoestadoapunte=2 ';  // 1.definitivo  2.borrador
    5: cSql := cSql + ' and codigoestadoapunte=1 ';  // 1.definitivo  2.borrador
  end;
  case iParametro of
    0,2,3: cSql := cSql+' and fechaasiento  between :fechadesde and :fechahasta ';
    1: cSql := cSql+' and fechacreacion= :fechacreacion and horacreacion>= :horacreacion ';
  end;
  case iParametro of
    4: cSql := cSql + ' and (codigousuariocreacion='+IntToStr(fmain._iCodigoUsuario_)+
                       ' or codigousuariomodificacion='+IntToStr(fmain._iCodigoUsuario_)+')';
  end;
  cSql := cSql + ' order by codigoempresa, ejercicio, numeroasiento, lineaasiento';
  //
  DMapuntes.QRdiario.SelectSQL.Text := cSql;
  //
  DMapuntes.QRdiario.Params[0].AsInteger := Fmain._iCodigoEmpresa_;
  DMapuntes.QRdiario.Params[1].AsInteger := Fmain._iCodigoEjercicio_;
  //
  case iParametro of
    0:begin  // cd_config
        DMapuntes.QRdiario.Params[2].AsDate := edDfecD.Date;
        DMapuntes.QRdiario.Params[3].AsDate := edDfecH.Date;
      end;
    1:begin  // cd_sesion
        DMapuntes.QRdiario.Params[2].AsDate := Trunc(fmain._dFechaInicioSesion_);
        DMapuntes.QRdiario.Params[3].AsTime := Frac (fmain._dFechaInicioSesion_);
      end;
    2:begin  // cd_hoy
        DMapuntes.QRdiario.Params[2].AsDate := getFechaServidor;
        DMapuntes.QRdiario.Params[3].AsDate := getFechaServidor;
      end;
    3:begin  // cd_ftrabajo
        DMapuntes.QRdiario.Params[2].AsDate := fmain._dFechaTrabajo_;
        DMapuntes.QRdiario.Params[3].AsDate := fmain._dFechaTrabajo_;
      end;
  end;
  //
  DMapuntes.QRdiario.Open;
  //
  grDiario.SetFocus;
end;

roman 06-01-2011 22:55:20

Dicho a bote pronto, ¿no puedes hacer un procedimiento almacenado al que le pases como parámetros los filtros que escoge el usuario?

// Saludos

Delphius 06-01-2011 22:59:44

Cita:

Empezado por roman (Mensaje 386857)
Dicho a bote pronto, ¿no puedes hacer un procedimiento almacenado al que le pases como parámetros los filtros que escoge el usuario?

// Saludos

Pues yo creería que si. No veo porqué no trasladar los parámetros y filtros de entrada al SP y después hacer simplemente algo como

Código SQL [-]
select * from MiProcedimientoAlmacenado(Param1, Param2 ....)

Para tener el conjunto de datos.

Saludos,

Casimiro Notevi 06-01-2011 23:13:32

Sí, en teoría, sí. El caso es que tengo ya la cabeza como un bombo dándole vueltas a esto desde hace varios días, voy a comer algo y desenchufo un rato, a ver si después lo veo más claro.
Gracias!!!!!!

Chris 06-01-2011 23:30:45

Mejorando código....

Código Delphi [-]
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
const
    background_colors: array[0..1] of TColor = (clBtnFace, clWhite);
begin
if Dataset.FieldByName('asiento').Value <> UltimoValor then
    BoolSwitch := (not BoolSwitch);

TDBGrid(Sender).Canvas.Brush.Color := background_colors[BoolSwitch];

// el grupo ya fue pintado?
if Pos(Format('-%s-', [Dataset.FieldByName('asiento').Value]), GrupoImpar) > 0 then
    TDBGrid(Sender).Canvas.Brush.Color := background_colors[0];
   
TDBGrid(Sender).DefaultDrawColumnCell( ... );
UltimoValor := Dataset.FieldByName('asiento').Value;

// guarlar una lista de los grupos impares
if (not BoolSwitch) and (Pos(Format('-%s-', [Dataset.FieldByName('asiento').Value]), GrupoImpar) = 0) then
    GrupoImpar := (GrupoImpar + Format('-%s-', [Dataset.FieldByName('asiento').Value]);
...
end;

Es un gasto de memoria, es cierto. Pero la solución en el código es una simplificación de la solución primera propuesta por delphius.

Aún no funciona? Dinos que esto ya lo tomamos como reto

EDITO: Aclaro que GrupoImpar es una variable global privada

fjcg02 06-01-2011 23:42:43

Hola de nuevo.

No quiero ser pesado, pero ya lo comenté en un post anterior. Se hace un procedimiento almacenado y se llama al mismo poniendo la where que se quiera, ya que puede ser invocado como una tabla o query. esta where puede ser montada 'al vuelo'.

Código SQL [-]
SET TERM ^ ;

CREATE OR ALTER PROCEDURE PRUEBA 
returns (
    idpresupuesto integer,
    color integer)
as
declare variable widpresupuesto integer;
begin
  /* Procedure Text */
  widpresupuesto = -1000;
  for
  SELECT IDPRESUPUESTO FROM b_lineapresupuesto order by idpresupuesto
  into :idpresupuesto
  do
  begin
    if (widpresupuesto = idpresupuesto) then
    begin
      if (color = 1) then COLOR = 1;
      else color = 0;
    end
    else
    begin
      if (color = 1) then COLOR = 0;
      else color = 1;
    end
    widpresupuesto=idpresupuesto;
    suspend;
  end
end^

SET TERM ; ^
Llamadas
Código SQL [-]
SELECT * from prueba WHERE IDPRESUPUESTO > 40

ó 

SELECT * from prueba WHERE IDPRESUPUESTO >= 40 AND IDPRESUPUESTO <= 200

Espero que sea de utilidad.

Saludos
Aupa Casi, no desfallezcas ahora !!

Chris 06-01-2011 23:48:39

Cita:

Empezado por Delphius (Mensaje 386859)
Pues yo creería que si. No veo porqué no trasladar los parámetros y filtros de entrada al SP y después hacer simplemente algo como

Código SQL [-]
select * from MiProcedimientoAlmacenado(Param1, Param2 ....)

Para tener el conjunto de datos.

Saludos,

De hecho en Firebird un procedimiento almacenado puede ser usado como un select cualquiera, eligiendo los campos y las condiciones que deben complirse para devolver cierto grupo de registros. Incluso se le puede establecer un orden. El único inconveniente es que es un poco más lento que cualquier otro select hecho directamente sobre una tabla.

Código SQL [-]
select from campo1, campo2, campo3 from procedimiento_almacenado where campo1=condificion_usuario order by campo_n

Saludos,
Chris

fjcg02 06-01-2011 23:50:21

Huelo que estamos llegando a tocarlo con la punta de los dedos...

Casi lo tenemos ...

Delphius 06-01-2011 23:53:06

Cita:

Empezado por Casimiro Notevi (Mensaje 386862)
Sí, en teoría, sí. El caso es que tengo ya la cabeza como un bombo dándole vueltas a esto desde hace varios días, voy a comer algo y desenchufo un rato, a ver si después lo veo más claro.
Gracias!!!!!!

Tu tranqui.

Prueba y evalúa las opciones. Si tienes problemas nos avisas y le caemos a madrazos a tu jefe y/o cliente por ese requerimiento :D

Si te funciona, ya sabes... me envías un jamón (la pata entera, por supuesto) por correo ;) :D :p

Saludos,

Aleca 06-01-2011 23:58:34

Cita:

Empezado por fjcg02 (Mensaje 386869)
Huelo que estamos llegando a tocarlo con la punta de los dedos...

Casi lo tenemos ...

si es así en horabuena, se esta siendo rogar...:D

fjcg02 07-01-2011 00:20:14

Repasando el hilo completo, Delphius ya daba el 80 % de la solución cuando en su post adjuntaba el código del procedimiento almacenado.

Sólo faltaba tal y como apuntaba Chris, saber que un procedimiento almacenado se puede llamar igual que cualquier tabla o vista, añadiéndole las condiciones que se necesiten al WHERE.

Un saludo

Delphius 07-01-2011 00:34:05

Debo decir que no hubiera sido posible la escritura del SP sin la ayuda de román cuando presentó esa consulta.

Por ello estoy dispuesto a compartir la mitad del jamón con el maestro román. :) :D ;)

Saludos,

Chris 07-01-2011 00:43:13

Cita:

Empezado por fjcg02 (Mensaje 386872)
Repasando el hilo completo, Delphius ya daba el 80 % de la solución cuando en su post adjuntaba el código del procedimiento almacenado.

Sólo faltaba tal y como apuntaba Chris, saber que un procedimiento almacenado se puede llamar igual que cualquier tabla o vista, añadiéndole las condiciones que se necesiten al WHERE.

Un saludo

Puede ser que ya se haya encontrado una solución, pero no es la optima realmente. No es muy buena idea que la base de datos funcione de muleta de un programador que no pudo solucionar un problema de la GUI. Agregar un campo más lo único que hará es aumentar la cantidad de datos que deben intercambiarce y para rematar, usando un procedimiento almacendado, la consulta se vuelve más lenta. Con estos dos problemas, todos tus usuarios juntos podrían perder mucho más tiempo del que no quisiste tomarte en moldear una mejor idea.

Obviamente, es decisión de Casimiro en este caso tomar un camino para su solución, pero yo sigo pensando en que es mucho mejor seguir trabajando del lado del código de la GUI en luegar de utilizar la base de datos como solución.

Delphius 07-01-2011 01:03:37

Cita:

Empezado por Chris (Mensaje 386875)
Puede ser que ya se haya encontrado una solución, pero no es la optima realmente. No es muy buena idea que la base de datos funcione de muleta de un programador que no pudo solucionar un problema de la GUI. Agregar un campo más lo único que hará es aumentar la cantidad de datos que deben intercambiarce y para rematar, usando un procedimiento almacendado, la consulta se vuelve más lenta. Con estos dos problemas, todos tus usuarios juntos podrían perder mucho más tiempo del que no quisiste tomarte en moldear una mejor idea.

Obviamente, es decisión de Casimiro en este caso tomar un camino para su solución, pero yo sigo pensando en que es mucho mejor seguir trabajando del lado del código de la GUI en luegar de utilizar la base de datos como solución.

Nunca se ha dicho que sea la más óptima, que sea la mejor, o que fuese la única alternativa.
Es sólo una posibilidad más que se baraja y debo decir que en buena parte tiene su simpleza.

Quizá un SP no se tan rápido que una consulta. Quizá se pierda un poco de velocidad y perfomance cuando se tengan varios registros y sean muchos clientes quienes estén atacando el servidor pero la posibilidad de que esté el SP ayuda a que buena parte del código sea más simple.

Si el motor tiene la capacidad y los datos necesarios para ayudar a facilitar algunas operaciones del lado del cliente es más que una buena posibilidad de evaluarlo. ¿No es acaso una de las reglas que un desarrollador debe siempre considerar?

Si el servidor puede asumir esa tarea y puede darnos los datos pre-masticados que la haga.... para todo lo demás existe mastercard... este... digo el sistema cliente. :D

No se trata de una chapuza como lo quieres vender, ni que el programador es ineficiente o incompetente por no haber logrado algo por otra vía. Si tanto te preocupa encontrar una solución que no esté vinculada con la base de datos y sea por código yo ya había indicado una vía, que me tomo la molestia de corregir:

Disponer de una estructura, una lista, a modo del campo ficticio "Colorear" y llenar esta lista con los 1 o 0 (o el color, o lo que quieran) para que luego al momento de pintar el DBGrid pueda recuperarse este dato y saber de que color pintarlo.
El punto es que NECESARIAMENTE se debe contar con toda la información de todos los registros para saber de que color pintar. No puede verse y atacar el problema considerando el registro de forma individual, ya que su color está relacionado con su predecesor y es necesario mantener en memoria, de alguna forma, el color asignado para que a efectos de un desplazamiento podamos volver al estado original.

Saludos,

Casimiro Notevi 07-01-2011 01:13:33

Cita:

Empezado por Chris (Mensaje 386864)
[..]
if Dataset.FieldByName('asiento').Value <> UltimoValor then
BoolSwitch := (not BoolSwitch);



C
reo que se está llegando a la conclusión de que esa parte es la que no funciona en este sistema, no se puede comparar con el valor del "último valor" porque puede ser cualquier registro, por ejemplo cuando ha llegado al último registro y ahora se posiciona en el primero, los colores pueden ser iguales, o no, depende de si el número de "asientos" es par o impar.
O sea, pintarlo, lo pinta perfecto, tanto ese método como todos los demás que se han sugerido, pero en cuanto empiezas a moverte por el grid arriba y abajo, con teclas o con el ratón, yendo al primero o al último con ctrl-inicio y ctrl-fin, página arriba y abajo, etc. siempre acaba descontrolando los colores por lo dicho anteriormente, el "anterior" no tiene por qué ser el que está "antes" en el dbgrid.

Entonces las únicas soluciones posibles son las que sacan el color del propio registro, independientemente de lo que tengan los otros registros anteriores o posteriores.
Ya sea mediante procedimiento almacenado, tabla en memoria, etc.

Bueno, esto que comento es lo que me parece según lo visto, puedo estar totalmente equivocado y ahora alguno expone un código que consigue el resultado esperado.

Chris 07-01-2011 05:07:05

[quote=Delphius;386876] ... ... ... [/]
Es obvio que te molestó mi comentario. Sorry, pero es mi opinión y mi filosofía de desarrollo. Por lo que tú digas, no la cambiaré porque no creo estar equivocado.

Tú bien sabes -lo has dicho- que existe una solución sin recurrir a la base de datos, y si esa fuera matar moscas con cañonazos, pues que así sea. Aveces, algunas "tonterías" -desde el punto de vista de la GUI- necesitan cientos de línea y docenas de horas en moldearse."

Cita:

Empezado por Delphius (Mensaje 386876)
Si el motor tiene la capacidad y los datos necesarios para ayudar a facilitar algunas operaciones del lado del cliente es más que una buena posibilidad de evaluarlo. ¿No es acaso una de las reglas que un desarrollador debe siempre considerar?

Si el servidor puede asumir esa tarea y puede darnos los datos pre-masticados que la haga.... para todo lo demás existe mastercard... este... digo el sistema cliente. :D

Aquí estamos totalmente deacuerdo. Pero esa ley no la debes tomar universalmente. Desde mi filosofía, es adecuado implementar esta regla para la lógica de negocios de la aplicación, no para ayudarte a pintar la GUI. Si tienes problemas para pintar la GUI, pídele ayuda a otro programador, no a la base de datos.

Cita:

Empezado por Delphius (Mensaje 386876)
Quizá un SP no se tan rápido que una consulta. Quizá se pierda un poco de velocidad y perfomance cuando se tengan varios registros y sean muchos clientes quienes estén atacando el servidor pero la posibilidad de que esté el SP ayuda a que buena parte del código sea más simple.

Acaso valdrá la pena que tus usuarios queden colgados por N segundos solo porque un programador prefirió que su código fuera más simple?

Cita:

Empezado por Delphius (Mensaje 386876)
No se trata de una chapuza como lo quieres vender, ni que el programador es ineficiente o incompetente por no haber logrado algo por otra vía. Si tanto te preocupa encontrar una solución que no esté vinculada con la base de datos y sea por código yo ya había indicado una vía...

Cómo tarea es una solución ingeniosa, eso sin duda. Para un sistema en producción, es deficiente. Punto! Mejor sigamos por tu vía, es mucho mejor.

Cita:

Empezado por Delphius (Mensaje 386876)
El punto es que NECESARIAMENTE se debe contar con toda la información de todos los registros para saber de que color pintar. No puede verse y atacar el problema considerando el registro de forma individual, ya que su color está relacionado con su predecesor y es necesario mantener en memoria, de alguna forma, el color asignado para que a efectos de un desplazamiento podamos volver al estado original.

Saludos,

Has terminado muy bien. Sigamos con el hilo, está cada vez más interesante. No lo desvirtuemos.

Chris 07-01-2011 05:10:29

Cita:

Empezado por Casimiro Notevi (Mensaje 386878)
[font=monospace]
Creo que se está llegando a la conclusión de que esa parte es la que no funciona en este sistema, no se puede comparar con el valor del "último valor" porque puede ser cualquier registro, por ejemplo cuando ha llegado al último registro y ahora se posiciona en el primero, los colores pueden ser iguales, o no, depende de si el número de "asientos" es par o impar.
O sea, pintarlo, lo pinta perfecto, tanto ese método como todos los demás que se han sugerido, pero en cuanto empiezas a moverte por el grid arriba y abajo, con teclas o con el ratón, yendo al primero o al último con ctrl-inicio y ctrl-fin, página arriba y abajo, etc. siempre acaba descontrolando los colores por lo dicho anteriormente, el "anterior" no tiene por qué ser el que está "antes" en el dbgrid.

Entonces las únicas soluciones posibles son las que sacan el color del propio registro, independientemente de lo que tengan los otros registros anteriores o posteriores.
Ya sea mediante procedimiento almacenado, tabla en memoria, etc.

Bueno, esto que comento es lo que me parece según lo visto, puedo estar totalmente equivocado y ahora alguno expone un código que consigue el resultado esperado.

Solo una pregunta. Independientemente del número en que se inicie el valor del campo ASIENTO, ya sea 5,6,7, etc. los números siempre serán consecutivos? Si fuese así, puedes utilizar el valor del número más bajo. Hacer una resta y del residuo calcular si es par o impar. Par un color, impar otro color.

Delphius 07-01-2011 06:24:33

Cita:

Empezado por Chris (Mensaje 386883)
Es obvio que te molestó mi comentario. Sorry, pero es mi opinión y mi filosofía de desarrollo. Por lo que tú digas, no la cambiaré porque no creo estar equivocado.

Y si me molestó, porque lanzaste un comentario a modo de indirecta a todo aquella persona que ha propuesto una ALTERNATIVA. Repito: ALTERNATIVA, no una solución que sea perfecta, bonita y que te caiga bien a tus propios gustos.

Estamos presentando alternativas, no sabíamos que te tenía que caer bien a vos.

Luego venía el debate de sus pros y contras.

Cita:

Empezado por Chris (Mensaje 386883)
Tú bien sabes -lo has dicho- que existe una solución sin recurrir a la base de datos, y si esa fuera matar moscas con cañonazos, pues que así sea. Aveces, algunas "tonterías" -desde el punto de vista de la GUI- necesitan cientos de línea y docenas de horas en moldearse."

Hay veces que debemos matar moscas a cañones, y otras veces se puede llegar a un término medio no con un cañón pero si con un mosquete y para otras será válida un simple revólver .22.

Tu que eres el mega chingón desarrollador, y tanto se ve que sabes deberías estar bien al tanto que en ocasiones no existe el blanco o el negro y debe encontrarse una solución en términos grises.

Cita:

Empezado por Chris (Mensaje 386883)
Aquí estamos totalmente deacuerdo. Pero esa ley no la debes tomar universalmente.

En ningún momento dije que haya que tomarla univesalmente. Más bien dije que mientras que nos permita aplicarla deberías considerarla.
Algunas reglas están para romperse, otras no.. y otras tantas a medias.

Para alguien que pretende decir que no debería tomarse universalmente me sorprende que intentes convencer que la solución pase únicamente por el lado del cliente.
A ver chiquito... estamos debatiendo pero parece que a vos no te agrada que otros presentemos otras vías posibles de encararlo.

Allí si tu tienes tu estilo, al menos otros estamos buscando darles giros al asunto y no quedarnos monotemáticos.

Cita:

Empezado por Chris (Mensaje 386883)
Desde mi filosofía, es adecuado implementar esta regla para la lógica de negocios de la aplicación, no para ayudarte a pintar la GUI. Si tienes problemas para pintar la GUI, pídele ayuda a otro programador, no a la base de datos.

¿Y no crees que Casi ha pedido ayuda y aquí entre todos, cada uno desde su lugar hizo o está haciendo un esfuerzo?
Tu pretendes tildar a Casi y a los demás como incompetente. Evita esas indirectas molestas... aqui ninguno viene con aires de traer la superioridad...

Y si no has sabido interpretar algunas cosas que se han dicho con humor... bueno, eso ya es otra cosa.

Cita:

Empezado por Chris (Mensaje 386883)
Acaso valdrá la pena que tus usuarios queden colgados por N segundos solo porque un programador prefirió que su código fuera más simple?

No podemos asegurar que sea N segundos, quizá sea N/2 lo cual sería un factor considerable. Y te digo que en ocasiones es preferible que se la aguanten un poquito antes que tener un código que podría tener la posibilidad de estallar en un futuro y ser inestable en cuanto se añadan nuevas mejoras o adiciones.

Sabes que existe algo llamado KISS... a lo siento... tu prefieres seguir rompiéndote la cabeza y no intentar darle un giro a tus ideas. Bien por ti, si quieres seguir complicándote.

Cita:

Empezado por Chris (Mensaje 386883)
Cómo tarea es una solución ingeniosa, eso sin duda. Para un sistema en producción, es deficiente. Punto! Mejor sigamos por tu vía, es mucho mejor.

¿Y como sabes y estás tan seguro que tan deficiente eres? ¿Que carajos sabes de los factores que inducen a la perfomance a la que verá sometido el sistema de Casimiro? Quizá esta consulta la use unas pocas personas, muy pocas veces al día, quizá tenga un buen servidor...
Hay más que mirar, y no necesariamente habrá una perdida considerable de perfomance.

Y allí si digo... punto final.

Cita:

Empezado por Chris (Mensaje 386883)
Sigamos con el hilo, está cada vez más interesante. No lo desvirtuemos.

Si, sigamos con el hilo... que no tiene sentido discutir, menos con alguien que pretende ponerle punto final a un debate de ideas.

Te aviso además, que no fui el iniciador y motivador principal de la solución por el lado de la base de datos... fue román, si tienes algo que decir y objetar crítica a él. Yo solamente seguí su planteo y propuse una ALTERNATIVA.

REPITO Y SOSTENGO HASTA EL CANSANCIO... HABLAMOS DE ALTERNATIVAS.. NO DE QUIEN SE LLEVA EL PREMIO A LA RAZÓN. La verdadera razón se la doy a Dios.

Saludos Cris....

Saludos a los demás.

fjcg02 07-01-2011 09:09:38

Demonios, qué caro se está poniendo el jamón :eek:

Que no cunda el pánico. Independientemente de la solución que se adopte, hay que tener en cuenta que los partícipes en este hilo no somos aprendices, y la verdad, hemos tardado en encontrar la solución; desde Casimiro que lo abrió al último participante. Y sí, parecía cosa de niños, pero realmente no era así.

Una vez tengamos una sóla o infinidad de soluciones, dejémosle a quien tiene que resolver el problema que lo resuelva como mejor crea conveniente, ya que de sus sistema, de sus usuarios y de sus problemáticas es él quien tiene el máximo de información.

La solución planteada desde la parte del servidor, puede ser tan buena como otra cualquiera, dependerá de la cantidad de veces que ese proceso se lanza, del equilibrio entre coste-beneficio, de lo pijo que sea el usuario, ... como bien comentabais antes.


Saludos

duilioisola 07-01-2011 10:57:55

Yo lo he logrado con el código que puse anteriormente. (Modificado un poco)




Resumiendo:
Poner AutoCalcFields = False;
Creando un campo calculado
Creando el evento OnCalcFields

Código Delphi [-]
{En el DataModule}
{Campo calculado SOMBRA integer}
{Propiedad AutoCalcFields=False}
{Variable global al DataModule (private de DMMayor) Sobra boolean}
{Variable global al DataModule (private de DMMayor) ValorAnterior string}

procedure TDMMayor.xMayorBeforeOpen(DataSet: TDataSet);
begin
   Sombra := False;
   ValorAnterior := '';
end;

procedure TDMMayor.xMayorCalcFields(DataSet: TDataSet);
begin
   {El campo calculado se inicializa a 0. Solo recalculo si es este valor}
   {ValorAnterior siempre guarda el valor del ultimo registro}

   {Si todavía no he establecido el valor del campo calculado}
   if (DataSet.FieldByName('SOMBRA').AsInteger = 0) then
   begin
      {Si el valor cambia, alterno el valor de Sombra}
      if (ValorAnterior <> DataSet.FieldByName('ASIENTO').AsString) then
      begin
         Sombra := not Sombra;
         ValorAnterior := DataSet.FieldByName('ASIENTO').AsString;
      end;
      
      if (Sombra) then
         DataSet.FieldByName('SOMBRA').AsInteger := 1
      else
         DataSet.FieldByName('SOMBRA').AsInteger := 2;
   end;
end;

{En el Formulario}

procedure TFCMayor.DBGConsultaDrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: integer; Column: TColumn; State: TGridDrawState);
begin
  with TDBGrid(Sender) do
  begin
     if (gdFocused in State) then //Si tiene el foco
     begin
        Canvas.Font.Color := clWhite;
        Canvas.Brush.Color := clHighlight;
     end
     else
     begin
        {Sombra puede ser 1 o 2. Si está a 0 no esta establecido}
        if (DataSource.DataSet.FieldByName('SOMBRA').AsInteger = 2) then
        begin
           Canvas.Font.Color := clBlack;
           Canvas.Brush.Color := clYellow;
        end
        else
        begin
           Canvas.Font.Color := clBlack;
           Canvas.Brush.Color := clInfoBk;
        end;
     end;
     DefaultDrawColumnCell(Rect, DataCol, Column, State);
  end;
end;


La franja horaria es GMT +2. Ahora son las 17:53:26.

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