unit InformeEstPresupuestos;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  InformeEstadistico, Db, RxMemDS, StdCtrls, RdxComboBox, dxCntner, dxTL,
  dxDBCtrl, dxDBGrid, ExtCtrls, RdxTitulos, RdxPaneles,

  IBCustomDataSet, BaseDatos, IBSQL, IB, Excepciones, TeEngine, TeeFunci,
  Series, TeeProcs, Chart, DBChart, IBDatabase, Grids, DBGrids, RdxBotones,
  RdxBarras;

type
  TfrInformeEstPresupuestos = class(TfrInformeEstadistico)
    pnlResumen2: TRdxPanel;
    cResumen2: TRdxCabecera;
    pnlDatosResumen2: TPanel;
    pnlGrid2: TPanel;
    gridResumen2: TdxDBGrid;
    pnlTitulosResumen2: TPanel;
    DBChart1: TDBChart;
    Series1: TBarSeries;
    Series2: TBarSeries;
    Series3: TBarSeries;
    IBDatabase1: TIBDatabase;
    IBTransaction1: TIBTransaction;
    DataSource1: TDataSource;
    IBDataSet1: TIBDataSet;
    IBDataSet3: TIBDataSet;
    IBDataSet2: TIBDataSet;
    Series4: TBarSeries;
    Series5: TBarSeries;
    Series6: TBarSeries;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label10: TLabel;
    pnlA1T1: TLabel;
    pnlA1T2: TLabel;
    pnlA1T3: TLabel;
    Label11: TLabel;
    Label12: TLabel;
    Label13: TLabel;
    etiComp: TLabel;
    Label15: TLabel;
    Label16: TLabel;
    Label17: TLabel;
    Label18: TLabel;
    Label19: TLabel;
    Label20: TLabel;
    Label21: TLabel;
    Label22: TLabel;
    pnlResumen3: TRdxPanel;
    cResumen3: TRdxCabecera;
    pnlDatosResumen3: TPanel;
    pnlGrid3: TPanel;
    gridResumen3: TdxDBGrid;
    pnlTitulosResumen3: TPanel;
    Label23: TLabel;
    Label24: TLabel;
    Label25: TLabel;
    Label26: TLabel;
    dsResumen2: TDataSource;
    TablaResumen2Mem: TRxMemoryData;
    dsResumen3: TDataSource;
    TablaResumen3Mem: TRxMemoryData;
    Panel1: TPanel;
    Label27: TLabel;
    cbxFiltroGrafico: TRdxComboBox;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    Label9: TLabel;
    pnlA2T1: TLabel;
    pnlA2T2: TLabel;
    pnlA2T3: TLabel;
    pnlA3T1: TLabel;
    pnlA3T2: TLabel;
    pnlA3T3: TLabel;

    procedure gridCustomDrawCell(Sender: TObject; ACanvas: TCanvas;
      ARect: TRect; ANode: TdxTreeListNode; AColumn: TdxTreeListColumn;
      ASelected, AFocused, ANewItemRow: Boolean; var AText: String;
      var AColor: TColor; AFont: TFont; var AAlignment: TAlignment;
      var ADone: Boolean); override;

    procedure bCancelarClick(Sender: TObject);
    procedure bImprimirClick(Sender: TObject);
    procedure cbxFiltroGraficoChange(Sender: TObject);

  private
    FTotAno11: Integer;
    FTotAno12: Integer;
    FTotAno13: Integer;
    FTotAno21: Integer;
    FTotAno22: Integer;
    FTotAno23: Integer;

    TablaResumen1 : TIBDataSet;
    sqlResumen1 : TStrings;
    TablaResumen2 : TIBDataSet;
    sqlResumen2 : TStrings;
    TablaResumen3 : TIBDataSet;
    sqlResumen3 : TStrings;

    procedure LimpiarTotales;
    function CalcularPre(const pSituacion: String; var TotalAno1: Integer; var TotalAno2: Integer): Boolean;
    function GenerarTablaInforme: TRxMemoryData;

    function InicializarResumen1: Boolean;
    function FinalizarResumen1: Boolean;
    function CalcularResumen1: Boolean;
    procedure InicializarGridResumen1(var Grid: TdxDBGrid);

    function InicializarResumen2: Boolean;
    function FinalizarResumen2: Boolean;
    function CalcularResumen2: Boolean;
    procedure InicializarGridResumen2(var Grid: TdxDBGrid);

    function InicializarResumen3: Boolean;
    function FinalizarResumen3: Boolean;
    function CalcularResumen3: Boolean;
    procedure InicializarGridResumen3(var Grid: TdxDBGrid);

    function CalcularResumen23Aux(const CodigosCliente: TStringList; const pSituacion: String;
    Tabla: TPTablaMem): Boolean;

  protected
    procedure SetAno2(const Value: Variant); override;
    function InicializarFiltros: Boolean; override;
    function InicializarCamposTMem: Boolean; override;
    function InicializarGrids: Boolean; override;
    function CalcularDatos: Boolean; override;

    function InicializarResumenes: Boolean; override;
    function RefrescarResumenes: Boolean; override;
    function FinalizarResumenes: Boolean; override;

  public
    constructor Create (AOwner : TComponent); override;
  end;

var
  frInformeEstPresupuestos: TfrInformeEstPresupuestos;

implementation

uses Tipos, Literales, Constantes, dxGrClms, Mensajes, TablaPresupuestos, RdxEmpresaActiva,
StrFunc, InfEstReportPresupuestos, Configuracion, SysFunc;

{$R *.DFM}

{ TfrInformeEstPresupuestos }


{ TfrInformeEstPresupuestos }

function TfrInformeEstPresupuestos.CalcularDatos: Boolean;
var
  Aux: Double;
  i: Integer;
  Aux2: String;

begin
  LimpiarTotales;
  FTotAno11:= 0;
  FTotAno21:= 0;
  FTotAno12:= 0;
  FTotAno22:= 0;
  FTotAno13:= 0;
  FTotAno23:= 0;
  CalcularPre(CTE_ACEPTADO,FTotAno11,FTotAno21);
  CalcularPre(CTE_ANULADO,FTotAno12,FTotAno22);
  CalcularPre(CTE_PENDIENTE,FTotAno13,FTotAno23);

  if FTotAno11 <> 0 then
     pnlA1T1.Caption := IntToStr(FTotAno11);
  if FTotAno12 <> 0 then
     pnlA1T2.Caption := IntToStr(FTotAno12);
  if FTotAno13 <> 0 then
     pnlA1T3.Caption := IntToStr(FTotAno13);

  //Solo calculamos totales en el caso de que se comparen dos años
  if not varIsNull(Ano2) then
  begin
    if FTotAno21 <> 0 then
    pnlA2T1.Caption := IntToStr(FTotAno21);
    if FTotAno22 <> 0 then
    pnlA2T2.Caption := IntToStr(FTotAno22);
    if FTotAno23 <> 0 then
    pnlA2T3.Caption := IntToStr(FTotAno23);

    if CalcularResta(FTotAno11, FTotAno21) < 0 then
      pnlA3T1.Font.Color := COLOR_NEGATIVO
    else
      pnlA3T1.Font.Color := COLOR_POSITIVO;
    if CalcularResta(FTotAno12, FTotAno22) < 0 then
      pnlA3T2.Font.Color := COLOR_NEGATIVO
    else
      pnlA3T2.Font.Color := COLOR_POSITIVO;
    if CalcularResta(FTotAno13, FTotAno23) < 0 then
      pnlA3T3.Font.Color := COLOR_NEGATIVO
    else
      pnlA3T3.Font.Color := COLOR_POSITIVO;

    if CalcularResta(FTotAno11, FTotAno21) <> 0 then
       pnlA3T1.Caption := IntToStr(CalcularResta(FTotAno11, FTotAno21));
    if CalcularResta(FTotAno12, FTotAno22) <> 0 then
       pnlA3T2.Caption := IntToStr(CalcularResta(FTotAno12, FTotAno22));
    if CalcularResta(FTotAno13, FTotAno23) <> 0 then
       pnlA3T3.Caption := IntToStr(CalcularResta(FTotAno13, FTotAno23));
  end;

  for i:=0 to DBChart1.SeriesList.CountActive-1 do
  begin
    Aux2 := DBChart1.SeriesList.Series[i].Title;
    case i of
    0,3: begin
            if i=0
            then DBChart1.SeriesList.Series[i].Title := ('Aceptados ' + cbxFiltro2.Text)
            else DBChart1.SeriesList.Series[i].Title := ('Aceptados ' + cbxFiltro3.Text);
            DBChart1.SeriesList.Series[i].XLabelsSource := CTE_CAMPO2;
            DBChart1.SeriesList.Series[i].XValues.ValueSource := CTE_CAMPO1;
            DBChart1.SeriesList.Series[i].YValues.ValueSource := CTE_ACEPTADO;
         end;
    1,4: begin
            if i=1
            then DBChart1.SeriesList.Series[i].Title := ('Anulados ' + cbxFiltro2.Text)
            else DBChart1.SeriesList.Series[i].Title := ('Anulados ' + cbxFiltro3.Text);
            DBChart1.SeriesList.Series[i].XLabelsSource := CTE_CAMPO2;
            DBChart1.SeriesList.Series[i].XValues.ValueSource := CTE_CAMPO1;
            DBChart1.SeriesList.Series[i].YValues.ValueSource := CTE_ANULADO;
         end;
    2,5: begin
            if i=2
            then DBChart1.SeriesList.Series[i].Title := ('Pendientes ' + cbxFiltro2.Text)
            else DBChart1.SeriesList.Series[i].Title := ('Pendientes ' + cbxFiltro3.Text);
            DBChart1.SeriesList.Series[i].XLabelsSource := CTE_CAMPO2;
            DBChart1.SeriesList.Series[i].XValues.ValueSource := CTE_CAMPO1;
            DBChart1.SeriesList.Series[i].YValues.ValueSource := CTE_PENDIENTE;
         end;
    end;
  end;
end;

function TfrInformeEstPresupuestos.CalcularPre(const pSituacion: String; var TotalAno1: Integer;
var TotalAno2: Integer): Boolean;
var
  oSQL: TIBSQL;
  Semaforo: Boolean; //Semaforo para controlar la pasada del Ano2 y asi empezar
  Contador: Integer; //a compara con los datos de la tabla de memoria en lugar de
                     //el recordset
begin
  Result := False;
  Semaforo := False;

  //PREPARAMOS LA SENTENCIA SQL A LANZAR
  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;

    SQL.Add('select EXTRACT(YEAR FROM P.FECHAALTA) as ANO');
    //Calculamos el intervalo correspondiente a cada una de las posibilidades
    Case Intervalo of
      tiMensual :    SQL.Add(',EXTRACT(MONTH FROM FECHAALTA) as NFILA');
      tiTrimestral : SQL.Add(',CAST((DIV(EXTRACT(MONTH FROM FECHAALTA),4)+1) AS SMALLINT) as NFILA');
      tiSemestral :  SQL.Add(',CAST((DIV(EXTRACT(MONTH FROM FECHAALTA),8)+1) AS SMALLINT) as NFILA');
    end;
    SQL.Add(',COUNT(P.CODIGO) as NUMPRE');
    SQL.Add('from PRESUPUESTOSCLIENTE P');
    SQL.Add('where P.CODIGOEMPRESA = :CODIGOEMPRESA');
    SQL.Add('and (EXTRACT(YEAR FROM P.FECHAALTA) = :ANO1');
    SQL.Add('or EXTRACT(YEAR FROM P.FECHAALTA) = :ANO2)');
    SQL.Add('and upper(SITUACION) = :SITUACION');
    SQL.Add('group by 1,2');

    if (not VarIsNull(Ano2)) and (Ano1 < Ano2)
    then SQL.Add('order by 1,2 asc')
    else SQL.Add('order by 1 desc,2 asc');
    try
      ParamByName('CODIGOEMPRESA').AsString := EmpresaActiva.Codigo;
      ParamByName('ANO1').AsString := Ano1;
      //En el caso de no compara con otro año se busca solo el año1
      if VarIsNull(Ano2)
      then ParamByName('ANO2').AsString := Ano1
      else ParamByName('ANO2').AsString := Ano2;
      ParamByName('SITUACION').AsString := pSituacion;
      Prepare;
      ExecQuery;

//Rellenamos los grid resultado
      TMemAnoCom1.First;
      TMemAnoCom2.First;
      TMemComparativa.First;
      TMemGraficoAno1.First;
      TMemGraficoAno2.First;

//Inicio de recorrido del resultado
      while not EOF do begin

//Rellenamos los datos del Año1
        if (FieldByName('ANO').AsString = Ano1) then
        begin
          //En el caso de solo tener datos en ciertos intervalos, los que no tienen datos los
          //no los rellenamos
          while TMemAnoCom1.FieldByName(CTE_CAMPO1).AsInteger <> FieldByName(CTE_CAMPO1).AsInteger do
          begin
            TMemAnoCom1.Next;
            TMemGraficoAno1.Next;
          end;
          //Metemos el dato obtenido en la sql en su intervalo correspondiente
          TMemAnoCom1.Edit;
          TMemAnoCom1.FieldByName(pSituacion).AsInteger := FieldByName('NUMPRE').AsInteger;
          TMemAnoCom1.Post;
          TMemGraficoAno1.Edit;
          TMemGraficoAno1.FieldByName(pSituacion).AsInteger := FieldByName('NUMPRE').AsInteger;
          TMemGraficoAno1.Post;
          //Vamos incrementando la suma total
          TotalAno1 := TotalAno1 + FieldByName('NUMPRE').AsInteger;
          TMemAnoCom1.Next;
          TMemGraficoAno1.Next;
        end

//Rellenamos los datos del Año2
        else
        begin
          //Si es la primera tupla del recordset de este año establecemos el semaforo
          //y la tabla de datos del Año1 en el primer elemento para tener en cuenta los
          //datos de dicha tabla en lugar de los del recordset para el Año1
          if not Semaforo then
          begin
            TMemAnoCom1.First;
            Semaforo := True;
          end
          else
            TMemAnoCom1.Next;

          //En el caso de solo tener datos en ciertos intervalos, los que no tienen datos los
          //no los rellenamos
          while TMemAnoCom2.FieldByName(CTE_CAMPO1).AsInteger <> FieldByName(CTE_CAMPO1).AsInteger do
          begin
            //Calculamos TablaComaprativa
            //En el caso de no existir el valor en Año1 o en Año2 de este determinado intervalo
            //no rellenariamos calculo ninguno
            if (not VarIsNull(TMemAnoCom1.FieldByName(pSituacion).AsVariant))
            and (not VarIsNull(TMemAnoCom2.FieldByName(pSituacion).AsVariant)) then
            begin
              TMemComparativa.Edit;
              TMemComparativa.FieldByName(pSituacion).AsInteger := TMemAnoCom1.FieldByName(pSituacion).AsInteger;
              TMemComparativa.Post;
            end;
            TMemComparativa.Next;
            TMemAnoCom2.Next;
            TMemAnoCom1.Next;
            TMemGraficoAno2.Next;
          end;

          //Metemos el dato obtenido en la sql en su intervalo correspondiente y calculamos
          TMemAnoCom2.Edit;
          TMemAnoCom2.FieldByName(pSituacion).AsInteger := FieldByName('NUMPRE').AsInteger;
          TMemAnoCom2.Post;
          TMemGraficoAno2.Edit;
          TMemGraficoAno2.FieldByName(pSituacion).AsInteger := FieldByName('NUMPRE').AsInteger;
          TMemGraficoAno2.Post;
          //Calculamos TablaComaprativa
          //En el caso de no existir el valor en Año1 o Año2 de este determinado intervalo
          //no rellenariamos calculo ninguno
          if (not VarIsNull(TMemAnoCom1.FieldByName(pSituacion).AsVariant))
          and (not VarIsNull(TMemAnoCom1.FieldByName(pSituacion).AsVariant)) then
          begin
            TMemComparativa.Edit;
            TMemComparativa.FieldByName(pSituacion).AsInteger := CalcularResta(TMemAnoCom1.FieldByName(pSituacion).AsInteger, TMemAnoCom2.FieldByName(pSituacion).AsInteger);
            TMemComparativa.Post;
          end;
          //Vamos incrementando la suma total
          TotalAno2 := TotalAno2 + FieldByName('NUMPRE').AsInteger;
          TMemComparativa.Next;
          TMemAnoCom2.Next;
          TMemGraficoAno2.Next;
        end;

        Next;
      end;
//Fin de recorrido del resultado
      Result := True;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

function TfrInformeEstPresupuestos.CalcularResumen1: Boolean;
var
  NumeroCampo : Integer;
  ImporteTotal : Double;
  Contador : Integer;

begin
  with TablaResumen1 do
  begin
    Close;
    Params.ByName('CODIGOEMPRESA').AsString := EmpresaActiva.Codigo;
    Params.ByName('ANO').AsString := Ano1;
    Params.ByName('SITUACION').AsString := CTE_ACEPTADO;
    Prepare;
    Open;
    //Borramos tabla y copiamos nuevamente la estructura
    TablaResumen1Mem.Close;
    TablaResumen1Mem.CopyStructure(TablaResumen1);
    //Añadimos el campo numero de fila
    TablaResumen1Mem.FieldDefs.Add(CTE_CAMPO1,ftInteger);
    TablaResumen1Mem.FieldDefs.Items[TablaResumen1Mem.FieldDefs.IndexOf(CTE_CAMPO1)].CreateField(Self);

    //Primera pasada donde sumamos el importe total
    ImporteTotal := 0;
    First;
    while not EOF do
    begin
      ImporteTotal := ImporteTotal + FieldByName('IMPORTETOTAL').AsFloat;
      Next;
    end;

    //Segunda pasada donde rellenamos con los primeros Top N de la lista
    if not IsEmpty then
    begin
      TablaResumen1Mem.DisableControls;
      TablaResumen1Mem.Open;
      First;
      Contador := 0;
      while ((not EOF) and (Contador < TopN)) do
      begin
        TablaResumen1Mem.Append;
        TablaResumen1Mem.FieldByName(CTE_CAMPO1).AsInteger := Contador + 1;

        for NumeroCampo := 0 to FieldCount-1 do
        begin
          if Fields[NumeroCampo].FieldName = 'PORCENTAJE' then
             TablaResumen1Mem.Fields[NumeroCampo].AsFloat := CalcularPorcentaje(ImporteTotal, Fields[NumeroCampo].AsFloat, False)
          else
             TablaResumen1Mem.Fields[NumeroCampo].AsString := Fields[NumeroCampo].AsString;
        end;
        TablaResumen1Mem.Post;
        Contador := Contador + 1;
        Next;
      end;
      TablaResumen1Mem.EnableControls;
    end;

    //Calculamos el nuevo height
    Contador := Contador + 1;
    pnlGrid.Height := (gridResumen.DefaultRowHeight) * Contador;
  end;
end;

function TfrInformeEstPresupuestos.CalcularResumen2: Boolean;
var
  NumeroCampo : Integer;
  Contador : Integer;
  CodigosCliente : TStringList;

begin
  CodigosCliente:= TStringList.Create;

  with TablaResumen2 do
  begin
    Close;
    Params.ByName('CODIGOEMPRESA').AsString := EmpresaActiva.Codigo;
    Params.ByName('ANO').AsString := Ano1;
    Params.ByName('SITUACION').AsString := CTE_ACEPTADO;
    Prepare;
    Open;
    //Borramos tabla y copiamos nuevamente la estructura
    TablaResumen2Mem.Close;
    TablaResumen2Mem.CopyStructure(TablaResumen2);
    //Añadimos el campo numero de fila
    TablaResumen2Mem.FieldDefs.Add(CTE_CAMPO1,ftInteger);
    TablaResumen2Mem.FieldDefs.Items[TablaResumen2Mem.FieldDefs.IndexOf(CTE_CAMPO1)].CreateField(Self);

    //Pasada donde rellenamos con los primeros Top N de la lista
    if not IsEmpty then
    begin
      TablaResumen2Mem.DisableControls;
      TablaResumen2Mem.Open;
      First;
      Contador := 0;
      while ((not EOF) and (Contador < TopN)) do
      begin
        TablaResumen2Mem.Append;
        TablaResumen2Mem.FieldByName(CTE_CAMPO1).AsInteger := Contador + 1;

        for NumeroCampo := 0 to FieldCount-1 do
        begin
          if Fields[NumeroCampo].FieldName = 'CODIGOCLIENTE' then
             CodigosCliente.Append(Fields[NumeroCampo].AsString);
          TablaResumen2Mem.Fields[NumeroCampo].AsString := Fields[NumeroCampo].AsString;
        end;

        TablaResumen2Mem.Post;
        Contador := Contador + 1;
        Next;
      end;

      //Calculamos y rellenamos los anulados y pendientes de los TopN, se hacen dos
      //accesos a base de datos porque obtener una unica SQL todo seria muy pesada
      CalcularResumen23Aux(CodigosCliente, CTE_ANULADO, @TablaResumen2Mem);
      CalcularResumen23Aux(CodigosCliente, CTE_PENDIENTE, @TablaResumen2Mem);
      TablaResumen2Mem.EnableControls;
    end;

    //Calculamos el nuevo height
    Contador := Contador + 1;
    pnlGrid2.Height := (gridResumen2.DefaultRowHeight) * Contador;
  end;
end;

function TfrInformeEstPresupuestos.CalcularResumen23Aux(const CodigosCliente: TStringList;
const pSituacion: String; Tabla: TPTablaMem): Boolean;
var
  oSQL : TIBSQL;
  i: Integer;
  Cadena: String;

begin
  if CodigosCliente.Count = 0 then
     exit;

  for i:=0 to CodigosCliente.Count-1 do
  begin
    //En el caso de ser un cliente que solo este en el presupuesto y no en la aplicacion
    if not esCadenaVacia(CodigosCliente.Strings[i]) then
    begin
      if i=0 then
         Cadena:= CodigosCliente.Strings[i]
      else
         Cadena:= Cadena + ', ' + CodigosCliente.Strings[i];
    end;
  end;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select EXTRACT(YEAR FROM P.FECHAALTA) as ANO, P.CODIGOCLIENTE, COALESCE(C.NOMBRE, P.NOMBRE) as NOMBRE,');
    SQL.Add('COUNT(P.CODIGO) as NUMPRE');
    SQL.Add('from PRESUPUESTOSCLIENTE P left join CLIENTES C');
    SQL.Add('on P.CODIGOCLIENTE = C.CODIGO');
    SQL.Add('where CODIGOEMPRESA = :CODIGOEMPRESA');
    SQL.Add('and EXTRACT(YEAR FROM FECHAALTA) = :ANO');
    SQL.Add('and upper(SITUACION) = :SITUACION');
    SQL.Add('and CODIGOCLIENTE in (' + Cadena + ')');
    SQL.Add('group by 1,2,3');
    SQL.Add('order by 2 desc');
    ParamByName('CODIGOEMPRESA').AsInteger :=  EmpresaActiva.Codigo;
    ParamByName('ANO').AsInteger := Ano1;
    ParamByName('SITUACION').AsString := pSituacion;

  try
    Prepare;
    ExecQuery;

    Tabla^.DisableControls;
    while not EOF do
    begin
      Tabla^.First;
      while (Tabla^.FieldByName('CODIGOCLIENTE').AsString <> FieldbyName('CODIGOCLIENTE').AsString) do
        Tabla^.Next;

      Tabla^.Edit;
      Tabla^.FieldByName(pSituacion).AsInteger := FieldbyName('NUMPRE').AsInteger;
      Tabla^.Post;
      Next;
    end;
    Tabla^.EnableControls;
  finally
    Close;
    Transaction := NIL;
    Free;
  end;
  end;
end;

function TfrInformeEstPresupuestos.CalcularResumen3: Boolean;
var
  NumeroCampo : Integer;
  Contador : Integer;
  CodigosCliente : TStringList;

begin
  CodigosCliente:= TStringList.Create;

  with TablaResumen3 do
  begin
    Close;
    Params.ByName('CODIGOEMPRESA').AsString := EmpresaActiva.Codigo;
    Params.ByName('ANO').AsString := Ano1;
    Params.ByName('SITUACION').AsString := CTE_ANULADO;
    Prepare;
    Open;
    //Borramos tabla y copiamos nuevamente la estructura
    TablaResumen3Mem.Close;
    TablaResumen3Mem.CopyStructure(TablaResumen3);
    //Añadimos el campo numero de fila
    TablaResumen3Mem.FieldDefs.Add(CTE_CAMPO1,ftInteger);
    TablaResumen3Mem.FieldDefs.Items[TablaResumen3Mem.FieldDefs.IndexOf(CTE_CAMPO1)].CreateField(Self);

    //Pasada donde rellenamos con los primeros Top N de la lista
    if not IsEmpty then
    begin
      TablaResumen3Mem.DisableControls;
      TablaResumen3Mem.Open;
      First;
      Contador := 0;
      while ((not EOF) and (Contador < TopN)) do
      begin
        TablaResumen3Mem.Append;
        TablaResumen3Mem.FieldByName(CTE_CAMPO1).AsInteger := Contador + 1;

        for NumeroCampo := 0 to FieldCount-1 do
        begin
          if Fields[NumeroCampo].FieldName = 'CODIGOCLIENTE' then
             CodigosCliente.Append(Fields[NumeroCampo].AsString);
          TablaResumen3Mem.Fields[NumeroCampo].AsString := Fields[NumeroCampo].AsString;
        end;

        TablaResumen3Mem.Post;
        Contador := Contador + 1;
        Next;
      end;

      //Calculamos y rellenamos los anulados y pendientes de los TopN, se hacen dos
      //accesos a base de datos porque obtener una unica SQL todo seria muy pesada
      CalcularResumen23Aux(CodigosCliente, CTE_ACEPTADO, @TablaResumen3Mem);
      CalcularResumen23Aux(CodigosCliente, CTE_PENDIENTE, @TablaResumen3Mem);
      TablaResumen3Mem.EnableControls;
    end;

    //Calculamos el nuevo height
    Contador := Contador + 1;
    pnlGrid3.Height := (gridResumen3.DefaultRowHeight) * Contador;
  end;
end;

function TfrInformeEstPresupuestos.FinalizarResumen1: Boolean;
begin
  sqlResumen1.Free;
  TablaResumen1Mem.Close;
  TablaResumen1.Close;
  TablaResumen1.UnPrepare;
  TablaResumen1.Free;
end;

function TfrInformeEstPresupuestos.FinalizarResumen2: Boolean;
begin
  sqlResumen2.Free;
  TablaResumen2Mem.Close;
  TablaResumen2.Close;
  TablaResumen2.UnPrepare;
  TablaResumen2.Free;
end;

function TfrInformeEstPresupuestos.FinalizarResumen3: Boolean;
begin
  sqlResumen3.Free;
  TablaResumen3Mem.Close;
  TablaResumen3.Close;
  TablaResumen3.UnPrepare;
  TablaResumen3.Free;
end;

function TfrInformeEstPresupuestos.FinalizarResumenes: Boolean;
begin
  FinalizarResumen1;
  FinalizarResumen2;
  FinalizarResumen3;
end;

procedure TfrInformeEstPresupuestos.gridCustomDrawCell(Sender: TObject;
  ACanvas: TCanvas; ARect: TRect; ANode: TdxTreeListNode;
  AColumn: TdxTreeListColumn; ASelected, AFocused, ANewItemRow: Boolean;
  var AText: String; var AColor: TColor; AFont: TFont;
  var AAlignment: TAlignment; var ADone: Boolean);
var
  IndiceCol: Integer;

begin
  inherited;

  if ((Sender as TdxDBGrid).Name = gridComparativa.Name) then
  begin
    if (AColumn.Caption = CTE_ACEPTADO) then
    begin
      IndiceCol := (Sender as TdxDBGrid).ColumnByFieldName(CTE_ACEPTADO).Index;
      if (ANode.Values[IndiceCol] < 0) then
          AFont.Color := COLOR_NEGATIVO
      else
          AFont.Color := COLOR_POSITIVO;
    end;

    if (AColumn.Caption = CTE_ANULADO) then
    begin
      IndiceCol := (Sender as TdxDBGrid).ColumnByFieldName(CTE_ANULADO).Index;
      if (ANode.Values[IndiceCol] < 0) then
          AFont.Color := COLOR_NEGATIVO
      else
          AFont.Color := COLOR_POSITIVO;
    end;

    if (AColumn.Caption = CTE_PENDIENTE) then
    begin
      IndiceCol := (Sender as TdxDBGrid).ColumnByFieldName(CTE_PENDIENTE).Index;
      if (ANode.Values[IndiceCol] < 0) then
          AFont.Color := COLOR_NEGATIVO
      else
          AFont.Color := COLOR_POSITIVO;
    end;
  end;
end;

function TfrInformeEstPresupuestos.InicializarCamposTMem: Boolean;
begin
  inherited InicializarCamposTMem;

  //ANO1
  TMemAnoCom1.FieldDefs.Add(CTE_ACEPTADO,ftInteger);
  TMemAnoCom1.FieldDefs.Items[TMemAnoCom1.FieldDefs.IndexOf(CTE_ACEPTADO)].CreateField(Self);
  TMemAnoCom1.FieldDefs.Add(CTE_ANULADO,ftInteger);
  TMemAnoCom1.FieldDefs.Items[TMemAnoCom1.FieldDefs.IndexOf(CTE_ANULADO)].CreateField(Self);
  TMemAnoCom1.FieldDefs.Add(CTE_PENDIENTE,ftInteger);
  TMemAnoCom1.FieldDefs.Items[TMemAnoCom1.FieldDefs.IndexOf(CTE_PENDIENTE)].CreateField(Self);

  //ANO2
  TMemAnoCom2.FieldDefs.Add(CTE_ACEPTADO,ftInteger);
  TMemAnoCom2.FieldDefs.Items[TMemAnoCom2.FieldDefs.IndexOf(CTE_ACEPTADO)].CreateField(Self);
  TMemAnoCom2.FieldDefs.Add(CTE_ANULADO,ftInteger);
  TMemAnoCom2.FieldDefs.Items[TMemAnoCom2.FieldDefs.IndexOf(CTE_ANULADO)].CreateField(Self);
  TMemAnoCom2.FieldDefs.Add(CTE_PENDIENTE,ftInteger);
  TMemAnoCom2.FieldDefs.Items[TMemAnoCom2.FieldDefs.IndexOf(CTE_PENDIENTE)].CreateField(Self);

  //COMPARATIVA
  TMemComparativa.FieldDefs.Add(CTE_ACEPTADO,ftInteger);
  TMemComparativa.FieldDefs.Items[TMemComparativa.FieldDefs.IndexOf(CTE_ACEPTADO)].CreateField(Self);
  TMemComparativa.FieldDefs.Add(CTE_ANULADO,ftInteger);
  TMemComparativa.FieldDefs.Items[TMemComparativa.FieldDefs.IndexOf(CTE_ANULADO)].CreateField(Self);
  TMemComparativa.FieldDefs.Add(CTE_PENDIENTE,ftInteger);
  TMemComparativa.FieldDefs.Items[TMemComparativa.FieldDefs.IndexOf(CTE_PENDIENTE)].CreateField(Self);

  //Grafico
  TMemGraficoAno1.FieldDefs.Add(CTE_ACEPTADO,ftInteger);
  TMemGraficoAno1.FieldDefs.Items[TMemGraficoAno1.FieldDefs.IndexOf(CTE_ACEPTADO)].CreateField(Self);
  TMemGraficoAno1.FieldDefs.Add(CTE_ANULADO,ftInteger);
  TMemGraficoAno1.FieldDefs.Items[TMemGraficoAno1.FieldDefs.IndexOf(CTE_ANULADO)].CreateField(Self);
  TMemGraficoAno1.FieldDefs.Add(CTE_PENDIENTE,ftInteger);
  TMemGraficoAno1.FieldDefs.Items[TMemGraficoAno1.FieldDefs.IndexOf(CTE_PENDIENTE)].CreateField(Self);

  TMemGraficoAno2.FieldDefs.Add(CTE_ACEPTADO,ftInteger);
  TMemGraficoAno2.FieldDefs.Items[TMemGraficoAno2.FieldDefs.IndexOf(CTE_ACEPTADO)].CreateField(Self);
  TMemGraficoAno2.FieldDefs.Add(CTE_ANULADO,ftInteger);
  TMemGraficoAno2.FieldDefs.Items[TMemGraficoAno2.FieldDefs.IndexOf(CTE_ANULADO)].CreateField(Self);
  TMemGraficoAno2.FieldDefs.Add(CTE_PENDIENTE,ftInteger);
  TMemGraficoAno2.FieldDefs.Items[TMemGraficoAno1.FieldDefs.IndexOf(CTE_PENDIENTE)].CreateField(Self);
end;

function TfrInformeEstPresupuestos.InicializarFiltros: Boolean;
begin
  inherited InicializarFiltros;
  AnosMem := dmTablaPresupuestos.DarListaAnos(EmpresaActiva.Codigo, False);

  cbxFiltroGrafico.Items.Append(CTE_TODOS);
  cbxFiltroGrafico.Items.Append('Aceptados');
  cbxFiltroGrafico.Items.Append('Anulados');
  cbxFiltroGrafico.Items.Append('Pendientes');
  cbxFiltroGrafico.ItemIndex := 0;
  DBChart1.Title.Text.Text := CTE_TODOS;
end;

procedure TfrInformeEstPresupuestos.InicializarGridResumen1(
  var Grid: TdxDBGrid);
var
  Columna : TdxDBTreeListColumn;

begin
  gridResumen.ShowHeader := False;
  cResumen1.Caption := msgInfEstPreResumen1;

  with Grid do begin
    DestroyColumns;
    {Columna CODIGOCLIENTE}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := CTE_CAMPO1;
    Columna.Caption := 'NFila';
    Columna.Width := tamColCodigo2;
    Columna.Visible := False;
    {Columna CODIGOCLIENTE}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'CODIGOCLIENTE';
    Columna.Caption := 'Código';
    Columna.Width := tamColCodigo2;
    Columna.Visible := False;
    {Columna NOMBRE}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'NOMBRE';
    Columna.Caption := 'Nombre';
    Columna.Width := tamColDescripcion2;
    {Columna NUMPRE}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'NUMPRE';
    Columna.Caption := 'Núm. presupuestos';
    Columna.Width := tamColPrecio;
    {Columna NUMPRE}
    Columna := CreateColumn(TdxDBGridCurrencyColumn);
    Columna.FieldName := 'IMPORTETOTAL';
    Columna.Caption := 'Importe total';
    Columna.Width := tamColPrecio;
    (Columna as TdxDBGridCurrencyColumn).DisplayFormat := DISPLAY_EUROS2;
    {Columna PORCENTAJE}
    Columna := CreateColumn(TdxDBGridCurrencyColumn);
    Columna.FieldName := 'PORCENTAJE';
    Columna.Caption := 'Porcentaje(%)';
    Columna.Width := tamColPorcentaje2;
    (Columna as TdxDBGridCurrencyColumn).DisplayFormat := DISPLAY_PORCENTAJE;
  end;
end;

procedure TfrInformeEstPresupuestos.InicializarGridResumen2(
  var Grid: TdxDBGrid);
var
  Columna : TdxDBTreeListColumn;

begin
  gridResumen2.ShowHeader := False;
  cResumen2.Caption := msgInfEstPreResumen2;

  with Grid do begin
    DestroyColumns;
    {Columna CODIGOCLIENTE}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := CTE_CAMPO1;
    Columna.Caption := 'NFila';
    Columna.Width := tamColCodigo2;
    Columna.Visible := False;
    {Columna CODIGOCLIENTE}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'CODIGOCLIENTE';
    Columna.Caption := 'Código';
    Columna.Width := tamColCodigo2;
    Columna.Visible := False;
    {Columna NOMBRE}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'NOMBRE';
    Columna.Caption := 'Nombre';
    Columna.Width := tamColDescripcion2;
    {Columna ACEPTADO}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'ACEPTADO';
    Columna.Caption := 'Núm. pre. Aceptados';
    Columna.Width := tamColPreAceAnuPen;
    {Columna ANULADO}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'ANULADO';
    Columna.Caption := 'Núm. pre. Anulados';
    Columna.Width := tamColPreAceAnuPen;
    {Columna PENDIENTE}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'PENDIENTE';
    Columna.Caption := 'Núm. pre. Pendientes';
    Columna.Width := tamColPreAceAnuPen;
  end;
end;

procedure TfrInformeEstPresupuestos.InicializarGridResumen3(
  var Grid: TdxDBGrid);
var
  Columna : TdxDBTreeListColumn;

begin
  gridResumen3.ShowHeader := False;
  cResumen3.Caption := msgInfEstPreResumen3;

  with Grid do begin
    DestroyColumns;
    {Columna CODIGOCLIENTE}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := CTE_CAMPO1;
    Columna.Caption := 'NFila';
    Columna.Width := tamColCodigo2;
    Columna.Visible := False;
    {Columna CODIGOCLIENTE}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'CODIGOCLIENTE';
    Columna.Caption := 'Código';
    Columna.Width := tamColCodigo2;
    Columna.Visible := False;
    {Columna NOMBRE}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'NOMBRE';
    Columna.Caption := 'Nombre';
    Columna.Width := tamColDescripcion2;
    {Columna ANULADO}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'ANULADO';
    Columna.Caption := 'Núm. pre. Anulados';
    Columna.Width := tamColPreAceAnuPen;
    {Columna ACEPTADO}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'ACEPTADO';
    Columna.Caption := 'Núm. pre. Aceptados';
    Columna.Width := tamColPreAceAnuPen;
    {Columna PENDIENTE}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'PENDIENTE';
    Columna.Caption := 'Núm. pre. Pendientes';
    Columna.Width := tamColPreAceAnuPen;
  end;
end;

function TfrInformeEstPresupuestos.InicializarGrids: Boolean;
var
  Columna : TdxDBTreeListColumn;

begin
  inherited InicializarGrids;

  //Titulo general
  cGeneral.Caption := msgInfEstPreGeneral;

  //ANO1
  Columna := gridAnoCom1.CreateColumn(TdxDBTreeListColumn);
  Columna.FieldName :=   CTE_ACEPTADO;
  Columna.Caption := CTE_ACEPTADO;
  Columna.Visible := True;

  Columna := gridAnoCom1.CreateColumn(TdxDBTreeListColumn);
  Columna.FieldName := CTE_ANULADO;
  Columna.Caption := CTE_ANULADO;
  Columna.Visible := True;

  Columna := gridAnoCom1.CreateColumn(TdxDBTreeListColumn);
  Columna.FieldName := CTE_PENDIENTE;
  Columna.Caption := CTE_PENDIENTE;
  Columna.Visible := True;

  //ANO2
  Columna := gridAnoCom2.CreateColumn(TdxDBTreeListColumn);
  Columna.FieldName := CTE_ACEPTADO;
  Columna.Caption := CTE_ACEPTADO;
  Columna.Visible := True;

  Columna := gridAnoCom2.CreateColumn(TdxDBTreeListColumn);
  Columna.FieldName := CTE_ANULADO;
  Columna.Caption := CTE_ANULADO;
  Columna.Visible := True;

  Columna := gridAnoCom2.CreateColumn(TdxDBTreeListColumn);
  Columna.FieldName := CTE_PENDIENTE;
  Columna.Caption := CTE_PENDIENTE;
  Columna.Visible := True;

  //COMPARATIVA
  Columna := gridComparativa.CreateColumn(TdxDBTreeListColumn);
  Columna.FieldName := CTE_ACEPTADO;
  Columna.Caption := CTE_ACEPTADO;
  Columna.Width := tamColPorcentaje;
  Columna.Visible := True;

  Columna := gridComparativa.CreateColumn(TdxDBTreeListColumn);
  Columna.FieldName := CTE_ANULADO;
  Columna.Caption := CTE_ANULADO;
  Columna.Width := tamColPorcentaje;
  Columna.Visible := True;

  Columna := gridComparativa.CreateColumn(TdxDBTreeListColumn);
  Columna.FieldName := CTE_PENDIENTE;
  Columna.Caption := CTE_PENDIENTE;
  Columna.Width := tamColPorcentaje;
  Columna.Visible := True;

  gridIntervalo.ShowHeader := False;
  gridAnoCom1.ShowHeader := False;
  gridAnoCom2.ShowHeader := False;
  gridComparativa.ShowHeader := False;
end;

function TfrInformeEstPresupuestos.InicializarResumen1: Boolean;
begin
  Result := False;
  try
    sqlResumen1 := TStringList.Create;
    with sqlResumen1 do
    begin
      Add('select EXTRACT(YEAR FROM P.FECHAALTA) as ANO, P.CODIGOCLIENTE, COALESCE(C.NOMBRE, P.NOMBRE) as NOMBRE, ');
      Add('COUNT(P.CODIGO) as NUMPRE, SUM(P.IMPORTETOTAL) as IMPORTETOTAL, SUM(P.IMPORTETOTAL) as PORCENTAJE ');
      Add('from PRESUPUESTOSCLIENTE P left join CLIENTES C ');
      Add('on P.CODIGOCLIENTE = C.CODIGO ');
      Add('where CODIGOEMPRESA = :CODIGOEMPRESA');
      Add('and EXTRACT(YEAR FROM FECHAALTA) = :ANO ');
      Add('and upper(SITUACION) = :SITUACION ');
      Add('group by 1,2,3 ');
      Add('order by 1,5 desc ');
    end;

    TablaResumen1 := TIBDataSet.Create(Self);
    with TablaResumen1 do
    begin
      Database := dmBaseDatos.BD;
      Transaction := dmBaseDatos.Transaccion;
      SelectSQL.Assign(sqlResumen1);
    end;
    InicializarGridResumen1(gridResumen);
    Result := True;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

function TfrInformeEstPresupuestos.InicializarResumen2: Boolean;
begin
  Result := False;
  try
    sqlResumen2 := TStringList.Create;
    with sqlResumen2 do
    begin
      Add('select EXTRACT(YEAR FROM P.FECHAALTA) as ANO, P.CODIGOCLIENTE, COALESCE(C.NOMBRE, P.NOMBRE) as NOMBRE,');
      Add('COUNT(P.CODIGO) as ACEPTADO, 0 as ANULADO, 0 as PENDIENTE');
      Add('from PRESUPUESTOSCLIENTE P left join CLIENTES C');
      Add('on P.CODIGOCLIENTE = C.CODIGO');
      Add('where CODIGOEMPRESA = :CODIGOEMPRESA');
      Add('and EXTRACT(YEAR FROM FECHAALTA) = :ANO');
      Add('and upper(SITUACION) = :SITUACION');
      Add('group by 1,2,3');
      Add('order by 4 desc');
    end;

    TablaResumen2 := TIBDataSet.Create(Self);
    with TablaResumen2 do
    begin
      Database := dmBaseDatos.BD;
      Transaction := dmBaseDatos.Transaccion;
      SelectSQL.Assign(sqlResumen2);
    end;
    InicializarGridResumen2(gridResumen2);
    Result := True;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

function TfrInformeEstPresupuestos.InicializarResumen3: Boolean;
begin
  Result := False;
  try
    sqlResumen3 := TStringList.Create;
    with sqlResumen3 do
    begin
      Add('select EXTRACT(YEAR FROM P.FECHAALTA) as ANO, P.CODIGOCLIENTE, COALESCE(C.NOMBRE, P.NOMBRE) as NOMBRE,');
      Add('COUNT(P.CODIGO) as ANULADO, 0 as ACEPTADO, 0 as PENDIENTE');
      Add('from PRESUPUESTOSCLIENTE P left join CLIENTES C');
      Add('on P.CODIGOCLIENTE = C.CODIGO');
      Add('where CODIGOEMPRESA = :CODIGOEMPRESA');
      Add('and EXTRACT(YEAR FROM FECHAALTA) = :ANO');
      Add('and upper(SITUACION) = :SITUACION');
      Add('group by 1,2,3');
      Add('order by 4 desc');
    end;

    TablaResumen3 := TIBDataSet.Create(Self);
    with TablaResumen3 do
    begin
      Database := dmBaseDatos.BD;
      Transaction := dmBaseDatos.Transaccion;
      SelectSQL.Assign(sqlResumen3);
    end;
    InicializarGridResumen3(gridResumen3);
    Result := True;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

function TfrInformeEstPresupuestos.InicializarResumenes: Boolean;
begin
  InicializarResumen1;
  InicializarResumen2;
  InicializarResumen3;      
end;

procedure TfrInformeEstPresupuestos.limpiarTotales;
begin
  pnlA1T1.Caption := '';
  pnlA1T2.Caption := '';
  pnlA1T3.Caption := '';
  pnlA2T1.Caption := '';
  pnlA2T2.Caption := '';
  pnlA2T3.Caption := '';
  pnlA3T1.Caption := '';
  pnlA3T2.Caption := '';
  pnlA3T3.Caption := '';
end;

function TfrInformeEstPresupuestos.RefrescarResumenes: Boolean;
begin
    CalcularResumen1;
    CalcularResumen2;
    CalcularResumen3;
end;

procedure TfrInformeEstPresupuestos.bCancelarClick(Sender: TObject);
begin
  CloseFrame;
end;

procedure TfrInformeEstPresupuestos.bImprimirClick(Sender: TObject);
var
  lInforme: TdmInfEstReportPresupuestos;
  DatosGenerales: TRxMemoryData;

begin
  try
    //Creamos informe
    lInforme:= TdmInfEstReportPresupuestos.Create(Self);

    //Asignamos la información al informe
    lInforme.Ano1 := Ano1;
    lInforme.Ano2 := Ano2;
    //Creamos una tabla con todos los datos del informe general, y la pasamos
    //al informe para que la copie, luego los destruimos
    DatosGenerales := GenerarTablaInforme;
    lInforme.setDatosGeneral(DatosGenerales);
    lInforme.A1T1 := pnlA1T1.Caption;
    lInforme.A1T2 := pnlA1T2.Caption;
    lInforme.A1T3 := pnlA1T3.Caption;
    lInforme.A2T1 := pnlA2T1.Caption;
    lInforme.A2T2 := pnlA2T2.Caption;
    lInforme.A2T3 := pnlA2T3.Caption;
    lInforme.A3T1 := pnlA3T1.Caption;
    lInforme.A3T2 := pnlA3T2.Caption;
    lInforme.A3T3 := pnlA3T3.Caption;

    //Creamos una imagen del grafico para luego insertarla en el informe
    lInforme.Fichero := DarFicheroBMPTemporal;
    DBChart1.SaveToBitmapFile(lInforme.Fichero);

    //Copiamos la información al informe
    lInforme.setDatosResumen1(TablaResumen1Mem);
    lInforme.setDatosResumen2(TablaResumen2Mem);
    lInforme.setDatosResumen3(TablaResumen3Mem);

    //Imprimimos
//    lInforme.Previsualizar;
    lInforme.Imprimir;
  finally
    FreeAndNil(DatosGenerales);
    DeleteFile(lInforme.Fichero);
    FreeAndNil(lInforme);
  end;
end;

function TfrInformeEstPresupuestos.GenerarTablaInforme: TRxMemoryData;
var
  TablaAux: TRxMemoryData;
begin
  //Creamos la tabla con los campos que vamos a tener para el informe
  TablaAux:= TRxMemoryData.Create(Self);
  with TablaAux do
  begin
    FieldDefs.Add('TITINTERVALO',ftString,20);
    FieldDefs.Items[FieldDefs.IndexOf('TITINTERVALO')].CreateField(Self);
    FieldDefs.Add('ANO1ACE',ftString,20);
    FieldDefs.Items[FieldDefs.IndexOf('ANO1ACE')].CreateField(Self);
    FieldDefs.Add('ANO1ANU',ftString,20);
    FieldDefs.Items[FieldDefs.IndexOf('ANO1ANU')].CreateField(Self);
    FieldDefs.Add('ANO1PEN',ftString,20);
    FieldDefs.Items[FieldDefs.IndexOf('ANO1PEN')].CreateField(Self);

    FieldDefs.Add('ANO2ACE',ftString,20);
    FieldDefs.Items[FieldDefs.IndexOf('ANO2ACE')].CreateField(Self);
    FieldDefs.Add('ANO2ANU',ftString,20);
    FieldDefs.Items[FieldDefs.IndexOf('ANO2ANU')].CreateField(Self);
    FieldDefs.Add('ANO2PEN',ftString,20);
    FieldDefs.Items[FieldDefs.IndexOf('ANO2PEN')].CreateField(Self);

    FieldDefs.Add('ANO3ACE',ftString,20);
    FieldDefs.Items[FieldDefs.IndexOf('ANO3ACE')].CreateField(Self);
    FieldDefs.Add('ANO3ANU',ftString,20);
    FieldDefs.Items[FieldDefs.IndexOf('ANO3ANU')].CreateField(Self);
    FieldDefs.Add('ANO3PEN',ftString,20);
    FieldDefs.Items[FieldDefs.IndexOf('ANO3PEN')].CreateField(Self);
  end;

  TablaAux.Open;

//Rellenamos el campo TITINTERVALO
  with TMemIntervalo do
  begin
    DisableControls;
    First;
    while not Eof do
    begin
      TablaAux.Append;
      TablaAux.FieldByName('TITINTERVALO').AsString := FieldByName('TITINTERVALO').AsString;
      TablaAux.Post;
      Next;
    end;
    EnableControls;
  end;

//Rellenamos los campos ANO1ACE, ANO1ANU, ANO1PEN
  with TMemAnoCom1 do
  begin
    DisableControls;
    First;
    TablaAux.First;
    while not Eof do
    begin
      TablaAux.Edit;
      TablaAux.FieldByName('ANO1ACE').AsString := FieldByName(CTE_ACEPTADO).AsString;
      TablaAux.FieldByName('ANO1ANU').AsString := FieldByName(CTE_ANULADO).AsString;
      TablaAux.FieldByName('ANO1PEN').AsString := FieldByName(CTE_PENDIENTE).AsString;
      TablaAux.Post;
      TablaAux.Next;
      Next;
    end;
    EnableControls;
  end;

//Rellenamos los campos ANO2ACE, ANO2ANU, ANO2PEN
  with TMemAnoCom2 do
  begin
    DisableControls;
    First;
    TablaAux.First;
    while not Eof do
    begin
      TablaAux.Edit;
      TablaAux.FieldByName('ANO2ACE').AsString := FieldByName(CTE_ACEPTADO).AsString;
      TablaAux.FieldByName('ANO2ANU').AsString := FieldByName(CTE_ANULADO).AsString;
      TablaAux.FieldByName('ANO2PEN').AsString := FieldByName(CTE_PENDIENTE).AsString;
      TablaAux.Post;
      TablaAux.Next;
      Next;
    end;
    EnableControls;
  end;

//Rellenamos los campos ANO3ACE, ANO3ANU, ANO3PEN
  with TMemComparativa do
  begin
    DisableControls;
    First;
    TablaAux.First;
    while not Eof do
    begin
      TablaAux.Edit;
      TablaAux.FieldByName('ANO3ACE').AsString := FieldByName(CTE_ACEPTADO).AsString;
      TablaAux.FieldByName('ANO3ANU').AsString := FieldByName(CTE_ANULADO).AsString;
      TablaAux.FieldByName('ANO3PEN').AsString := FieldByName(CTE_PENDIENTE).AsString;
      TablaAux.Post;
      TablaAux.Next;
      Next;
    end;
    EnableControls;
  end;

  Result:= TablaAux;
end;

procedure TfrInformeEstPresupuestos.cbxFiltroGraficoChange(
  Sender: TObject);
begin
  if cbxFiltroGrafico.Text = CTE_TODOS then
  begin
    DBChart1.SeriesList.Series[0].Active := True;
    DBChart1.SeriesList.Series[1].Active := True;
    DBChart1.SeriesList.Series[2].Active := True;
    DBChart1.SeriesList.Series[3].Active := True;
    DBChart1.SeriesList.Series[4].Active := True;
    DBChart1.SeriesList.Series[5].Active := True;
    DBChart1.Title.Text.Text := CTE_TODOS;
  end
  else if cbxFiltroGrafico.Text = 'Aceptados' then
  begin
    DBChart1.SeriesList.Series[0].Active := True;
    DBChart1.SeriesList.Series[1].Active := False;
    DBChart1.SeriesList.Series[2].Active := False;
    DBChart1.SeriesList.Series[3].Active := True;
    DBChart1.SeriesList.Series[4].Active := False;
    DBChart1.SeriesList.Series[5].Active := False;
    DBChart1.Title.Text.Text := 'Aceptados';
  end
  else if cbxFiltroGrafico.Text = 'Anulados' then
  begin
    DBChart1.SeriesList.Series[0].Active := False;
    DBChart1.SeriesList.Series[1].Active := True;
    DBChart1.SeriesList.Series[2].Active := False;
    DBChart1.SeriesList.Series[3].Active := False;
    DBChart1.SeriesList.Series[4].Active := True;
    DBChart1.SeriesList.Series[5].Active := False;
    DBChart1.Title.Text.Text := 'Anulados';
  end
  else if cbxFiltroGrafico.Text = 'Pendientes' then
  begin
    DBChart1.SeriesList.Series[0].Active := False;
    DBChart1.SeriesList.Series[1].Active := False;
    DBChart1.SeriesList.Series[2].Active := True;
    DBChart1.SeriesList.Series[3].Active := False;
    DBChart1.SeriesList.Series[4].Active := False;
    DBChart1.SeriesList.Series[5].Active := True;
    DBChart1.Title.Text.Text := 'Pendientes';
  end;
end;

constructor TfrInformeEstPresupuestos.Create(AOwner: TComponent);
begin
  inherited;
  Entidad := entInfEstPreCli;
  ConfigurarFrame(Self, Self.Entidad);
end;

procedure TfrInformeEstPresupuestos.SetAno2(const Value: Variant);
begin
  inherited;
  if not VarIsNull(Ano2) then
     etiComp.Caption := msgInfEstTit31 + IntToStr(Ano1) + msgInfEstTit32 + IntToStr(Ano2)
  else
     etiComp.Caption := '';
end;

end.
