unit uProcesarOptVarEstado;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, xMatDefs, uAuxiliares, Grids, ComCtrls, Math, utilidades,
  uFechas, uverdoc, utrazosxy, matreal, isocurvas, uEditarISONiveles, Menus,
  uResultadoOpt, ExtCtrls;

const
  archiEtiquetasNiveles = 'etiquetasNiveles.txt';

type
  TProcesarOptVarEstado = class(TForm)
    CBVarLibre: TComboBox;
    LVarLibre: TLabel;
    GBRangoFechas: TGroupBox;
    DTPDesde: TDateTimePicker;
    DTPHasta: TDateTimePicker;
    LDesde: TLabel;
    LHasta: TLabel;
    CBVarsFijas: TComboBox;
    LVarsFijas: TLabel;
    UDVarFija: TUpDown;
    EnEstadoVarFija: TEdit;
    SGDatos: TStringGrid;
    LEstado: TLabel;
    BAyuda: TButton;
    BGraficarCostoPorColumnas: TButton;
    BExportarExcel: TButton;
    BGraficarCurvasISONivel: TButton;
    MainMenu1: TMainMenu;
    MHerramientas: TMenuItem;
    MGraficarCostoPorColumnas: TMenuItem;
    MGraficarCurvasISONivel: TMenuItem;
    MExportarAExcel: TMenuItem;
    MEditarISONiveles: TMenuItem;
    LValorEstado: TLabel;
    bCompararContraCorte: TButton;
    RGUsarTraduccion: TRadioGroup;
    procedure CBVarLibreChange(Sender: TObject);
    procedure CBVarsFijasChange(Sender: TObject);
    procedure UDVarFijaClick(Sender: TObject; Button: TUDBtnType);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure DTPChange(Sender: TObject);
    procedure BAyudaClick(Sender: TObject);
    procedure BGraficarCostoPorColumnasClick(Sender: TObject);
    procedure BExportarExcelClick(Sender: TObject);
    procedure BGraficarCurvasISONivelClick(Sender: TObject);
    procedure MGraficarCostoPorColumnasClick(Sender: TObject);
    procedure MEditarISONivelesClick(Sender: TObject);
    procedure MGraficarCurvasISONivelClick(Sender: TObject);
    procedure MExportarAExcelClick(Sender: TObject);
    procedure bCompararContraCorteClick(Sender: TObject);
    procedure RGUsarTraduccionClick(Sender: TObject);
  private
    //el indice de la variable fija seleccionada
    //para no estar calculandolo todo el tiempo
    iVarFija: Integer;

    optres: TResultadoOpt;

    //las finas inicial y final de los datos para el rango de fechas seleccionado
    filaIni, filaFin: Integer;

    //las columnas en los datos originales  que hay que ver para observar la
    //variable libre para los valores dados de las otras variables
    cols: TDAofNInt;

    //para el graficador de curvas ISONivel
    //guardan los nombres de cada nivel y sus valores
    etiquetasNiveles : TDAofString;
    niveles: TDAofNReal;

    //Ventana para gráficos
    trazos : TfrmDllForm;

    procedure leerEtiquetasNiveles;
    procedure guardarEtiquetasNiveles;
    procedure llenarRGTraduccion;

    procedure llenarTabla(filaIni, filaFin: Integer; cols: TDAofNInt);
    procedure graficarCostoColumnasEnFuncT(filaIni, filaFin: Integer; cols: TDAofNInt);
    procedure graficarCurvasISONivel(filaIni, filaFin: Integer; cols: TDAofNInt);
    procedure editarISONiveles(var niveles: TDAofNReal; var etiquetasNiveles : TDAofString);
    procedure compararContraCorte;
  public
    Constructor Create(owner : TComponent ; nArch: String); reintroduce;
    class function filtrosDeArchivos: String;
  end;
  
var
  ProcesarOptVarEstado: TProcesarOptVarEstado;

implementation

{$R *.dfm}

class function TProcesarOptVarEstado.filtrosDeArchivos: String;
begin
  result:= 'Archivos de Costos Futuros Hidraulicos (opt*.xlt)|opt*.xlt';
end;

procedure TProcesarOptVarEstado.BAyudaClick(Sender: TObject);
begin
  verdoc( 'procesador-resultados-VisualizadorCostosHidraulicos', 'Ayuda del Visualizador de Costos Hidráulicos');
end;

procedure TProcesarOptVarEstado.bCompararContraCorteClick(Sender: TObject);
begin
  compararContraCorte;
end;

procedure TProcesarOptVarEstado.BExportarExcelClick(Sender: TObject);
begin
  optres.exportarAxlt(CBVarLibre.Items[CBVarLibre.ItemIndex], filaIni, filaFin, cols);
end;

procedure TProcesarOptVarEstado.BGraficarCostoPorColumnasClick(Sender: TObject);
begin
  graficarCostoColumnasEnFuncT(filaIni, filaFin, cols);
end;

procedure TProcesarOptVarEstado.BGraficarCurvasISONivelClick(Sender: TObject);
begin
  graficarCurvasISONivel(filaIni, filaFin, cols);
end;

procedure TProcesarOptVarEstado.CBVarLibreChange(Sender: TObject);
var
  i: Integer;
begin
  //Relleno la caja de fijas
  CBVarsFijas.Items.Clear;
  CBVarsFijas.Items.Capacity:= optRes.descVars.Count - 1;
  for i:= 0 to optRes.descVars.Count - 1 do
    if TDescVar(optRes.descVars[i]).nombre <> CBVarLibre.Items[CBVarLibre.ItemIndex] then
      CBVarsFijas.Items.Add(TDescVar(optRes.descVars[i]).nombre);

  if CBVarsFijas.Items.count > 0 then
  begin
    CBVarsFijas.ItemIndex:= 0;
    CBVarsFijasChange(Sender);
  end;

  llenarRGTraduccion;
  RGUsarTraduccion.ItemIndex:= 0;

  cols:= optRes.recalcCols(CBVarLibre.Items[CBVarLibre.ItemIndex]);
  if sender <> NIL then //Inicialización
  begin
    llenarTabla(filaIni, filaFin, cols);
  end;
end;

procedure TProcesarOptVarEstado.CBVarsFijasChange(Sender: TObject);
var
  descVarFija: TDescVar;
begin
  iVarFija:= optres.indiceDescVar(CBVarsFijas.Items[CBVarsFijas.ItemIndex]);
  descVarFija:= TDescVar(optRes.descVars[iVarFija]);
  UDVarFija.Min:= 1;
  UDVarFija.Max:= descVarFija.nDiscs;
  UDVarFija.Position:= descVarFija.pos +1;
  LValorEstado.Caption:= FloatToStrF(descVarFija.discretizaciones[descVarFija.pos], ffFixed, 10, 2) + ' ' + descVarFija.unidades;
end;

Constructor TProcesarOptVarEstado.Create(owner : TComponent ; nArch: String);
begin
  inherited Create(owner);
  trazos:= nil;
  try
    optres:= TResultadoOpt.Create(nArch, true);

    if FileExists(archiEtiquetasNiveles) then
      leerEtiquetasNiveles
    else
    begin
      //niveles:=[250, 400, 1200, 2000, 63.87, 71.2, 163.08, 122.3, 89.36, 216.5];
      SetLength(niveles, 10);
      niveles[0]:= 250;
      niveles[1]:= 400;
      niveles[2]:= 1200;
      niveles[3]:= 2000;
      niveles[4]:= 63.87;
      niveles[5]:= 71.2;
      niveles[6]:= 163.08;
      niveles[7]:= 122.3;
      niveles[8]:= 89.36;
      niveles[9]:= 216.5;

      //etiquetasNiveles= ['F1', 'F2', 'F3', 'F4', '5ta','6ta', 'CTR', 'PTI', 'SB', 'TGAA'];
      SetLength(etiquetasNiveles, length(niveles));
      etiquetasNiveles[0]:= 'F1';
      etiquetasNiveles[1]:= 'F2';
      etiquetasNiveles[2]:= 'F3';
      etiquetasNiveles[3]:= 'F4';
      etiquetasNiveles[4]:= '5ta';
      etiquetasNiveles[5]:='6ta';
      etiquetasNiveles[6]:= 'CTR';
      etiquetasNiveles[7]:= 'PTI';
      etiquetasNiveles[8]:= 'SB';
      etiquetasNiveles[9]:= 'TGAA';
    end;
  Except
    ShowMessage('Error leyendo desde archivo');
    PostQuitMessage(0);
  end;
end;

procedure TProcesarOptVarEstado.DTPChange(Sender: TObject);
begin
  optres.recalcRangoFechas(trunc(DTPDesde.Date), trunc(DTPHasta.Date), filaIni, filaFin);
  llenarTabla(filaIni, filaFin, cols);
end;

procedure TProcesarOptVarEstado.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  guardarEtiquetasNiveles;
  ModalResult:= mrOk;
end;

procedure TProcesarOptVarEstado.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  self.Top:= 5;
  self.Left:= 5;

  SGDatos.DefaultColWidth:= SGDatos.Canvas.TextWidth('0000000000.00');//Numeros de 10 digitos y 2 posiciones decimales

  CBVarLibre.Items.Capacity:= optRes.descVars.Count;
  CBVarsFijas.Items.Capacity:= optRes.descVars.Count -1;
  CBVarLibre.Items.Add(TDescVar(optRes.descVars[0]).nombre);
  CBVarLibre.ItemIndex:= 0;
  for i:= 1 to optRes.descVars.Count - 1 do
  begin
    CBVarLibre.Items.Add(TDescVar(optRes.descVars[i]).nombre);
    CBVarsFijas.Items.Add(TDescVar(optRes.descVars[i]).nombre);
  end;
  CBVarLibreChange(NIL);

  DTPDesde.MinDate:= optRes.datos[0][0];
  DTPDesde.MaxDate:= optRes.datos[optRes.nPasos - 1][0];
  DTPDesde.Date:= DTPDesde.MinDate;

  DTPHasta.MinDate:= DTPDesde.MinDate;
  DTPHasta.MaxDate:= DTPDesde.MaxDate;
  DTPHasta.Date:= DTPHasta.MaxDate;

  optres.recalcRangoFechas(DTPDesde.Date, DTPHasta.Date, filaIni, filaFin);

  llenarTabla(filaIni, filaFin, cols);
end;


procedure TProcesarOptVarEstado.UDVarFijaClick(Sender: TObject;
  Button: TUDBtnType);
var
  descVarFija: TDescVar;
begin
  descVarFija:= TDescVar(optRes.descVars[iVarFija]);
  descVarFija.pos:= UDVarFija.Position -1;
  LValorEstado.Caption:= FloatToStrF(descVarFija.discretizaciones[descVarFija.pos], ffFixed, 10, 2) + ' ' + descVarFija.unidades;
  cols:= optRes.recalcCols(CBVarLibre.Items[CBVarLibre.ItemIndex]);
  llenarTabla(filaIni, filaFin, cols);
end;

procedure TProcesarOptVarEstado.leerEtiquetasNiveles;
var
  f: TextFile;
  i: Integer;
  linea: String;
  auxLectura: TStringList;
begin
  auxLectura:= TStringList.Create;
  AssignFile(f, archiEtiquetasNiveles);
  try
    Reset(f);
    //Etiqueta  Nivel
    readln(f, linea);
    while not Eof(f) do
    begin
      readln(f, linea);
      auxLectura.Add(linea);
    end;

    SetLength(etiquetasNiveles, auxLectura.Count);
    SetLength(niveles, auxLectura.Count);

    for i:= 0 to auxLectura.Count - 1 do
    begin
      linea:= auxLectura[i];
      etiquetasNiveles[i]:= NextPal(linea);
      niveles[i]:= NextFloat(linea);
    end;

    auxLectura.Free;
    CloseFile(f);
  except
    auxLectura.Free;
    CloseFile(f);    
    raise;
  end;
end;

procedure TProcesarOptVarEstado.guardarEtiquetasNiveles;
var
  f: TextFile;
  i: Integer;
begin
  AssignFile(f, archiEtiquetasNiveles);
  try
    Rewrite(f);
    Writeln(f, 'Etiqueta'#9'Nivel');
    for i:= 0 to high(etiquetasNiveles) do
    begin
      Writeln(f, etiquetasNiveles[i], #9, niveles[i]);
    end;
    CloseFile(f);
  Except
    CloseFile(f);
    raise;
  end;
end;

procedure TProcesarOptVarEstado.llenarRGTraduccion;
var
  descVarLibre: TDescVar;
begin
  descVarLibre:= optres.descVars[optres.indiceDescVar(CBVarLibre.Items[CBVarLibre.ItemIndex])];
  if descVarLibre.nombreTraduccion <> '' then
  begin
    RGUsarTraduccion.Items[0]:= descVarLibre.nombre;
    RGUsarTraduccion.Items[1]:= descVarLibre.nombreTraduccion;

    RGUsarTraduccion.Visible:= true;
  end
  else
    RGUsarTraduccion.Visible:= false;
end;

procedure TProcesarOptVarEstado.llenarTabla(filaIni, filaFin: Integer; cols: TDAofNInt);
var
  i, j, filaTabla: Integer;
  descVarLibre: TDescVar;
  fila: TDAofNReal;
begin
  SGDatos.RowCount:= filaFin - filaIni + 2;
  SGDatos.ColCount:= length(cols) + 1;

  descVarLibre:= optres.descVars[optres.indiceDescVar(CBVarLibre.Items[CBVarLibre.ItemIndex])];
  SGDatos.Cells[0, 0]:= 'Fecha\Estado[' + descVarLibre.unidades + ']';
  for j := 1 to SGDatos.ColCount - 1 do
    SGDatos.Cells[j, 0]:= FloatToStrF(descVarLibre.discretizaciones[j - 1], ffFixed, 10, 2);
  for i:= filaIni to filaFin do
  begin
    fila:= optres.datos[i];
    filaTabla:= i - filaIni + 1;

    SGDatos.Cells[0, filaTabla]:= DateToStr(fila[0]);
    for j:= 0 to high(cols) do
      SGDatos.Cells[j + 1, filaTabla]:= FloatToStr(fila[cols[j]]);
  end;

  utilidades.AutoSizeCol(SGDatos, 0);
{  utilidades.AutoSizeColsToMaxCol(SGDatos);}
  utilidades.AutosizeTableWidth(SGDatos);
end;

procedure TProcesarOptVarEstado.MEditarISONivelesClick(Sender: TObject);
begin
  editarISONiveles(niveles, etiquetasNiveles);
end;

procedure TProcesarOptVarEstado.MExportarAExcelClick(Sender: TObject);
begin
  optres.exportarAxlt(CBVarLibre.Items[CBVarLibre.ItemIndex], filaIni, filaFin, cols);
end;

procedure TProcesarOptVarEstado.MGraficarCostoPorColumnasClick(Sender: TObject);
begin
  graficarCostoColumnasEnFuncT(filaIni, filaFin, cols);
end;

procedure TProcesarOptVarEstado.MGraficarCurvasISONivelClick(Sender: TObject);
begin
  graficarCurvasISONivel(filaIni, filaFin, cols);
end;

procedure TProcesarOptVarEstado.RGUsarTraduccionClick(Sender: TObject);
var
  i: Integer;
  descVarLibre: TDescVar;
  discs: TDAOfNReal;
begin
  descVarLibre:= optres.descVars[optres.indiceDescVar(CBVarLibre.Items[CBVarLibre.ItemIndex])];
  if RGUsarTraduccion.ItemIndex = 0 then
    discs:= descVarLibre.discretizaciones
  else
    discs:= descVarLibre.discretizacionesTraduccion;

  for i:= 0 to descVarLibre.nDiscs - 1 do
    SGDatos.Cells[i + 1, 0]:= FloatToStrF(discs[i], ffFixed, 10, 2);
end;

procedure TProcesarOptVarEstado.graficarCostoColumnasEnFuncT(filaIni, filaFin: Integer; cols: TDAofNInt);
var
  minY, maxY: NReal;
  colorSerie: TColor;
  iSerie, iVarLibre, iVarsFijas: Integer;
  descVarLibre, descVarFija: TDescVar;
  titulo, nomSerie: String;
  nPuntos: Integer;
  iFila: Integer;
  fila: TDAofNReal;
begin
  if trazos <> NIL then
  begin
    trazos.Hide;
    trazos.Free;
  end;

  iVarLibre:= optres.indiceDescVar(CBVarLibre.Items[CBVarLibre.ItemIndex]);
  descVarLibre:= TDescVar(optres.descVars[iVarLibre]);
  nPuntos:= filaFin - filaIni + 1;
  colorSerie:= RGB(255, 0, 0);
  optres.minMaxDatos(filaIni, filaFin, cols, minY, maxY);
  trazos:= TfrmDllForm.Create(self);
  titulo:= 'Costo por Columnas en Función del Tiempo para ';
  for iVarsFijas:= 0 to iVarLibre - 1 do
  begin
    descVarFija:= TDescVar(optres.descVars[iVarsFijas]);
    titulo:= titulo + descVarFija.nombre + ' en ' + FloatToStrF(descVarFija.discretizaciones[descVarFija.pos], fffixed, 10, 1) + ' ' + descVarFija.unidades + ', ';
  end;
  for iVarsFijas:= iVarLibre + 1 to optres.descVars.Count -1 do
  begin
    descVarFija:= TDescVar(optres.descVars[iVarsFijas]);
    titulo:= titulo + descVarFija.nombre + ' en ' + FloatToStrF(descVarFija.discretizaciones[descVarFija.pos], fffixed, 10, 1) + ' ' + descVarFija.unidades + ', ';
  end;

  nomSerie:= FloatToStrF(descVarLibre.discretizaciones[0], ffFixed, 10, 2) + ' ' + descVarLibre.unidades;
  trazos.CrearDiagramaXY(titulo, nPuntos, false, 'Tiempo', nomSerie,
                         colorSerie, filaIni, filaFin, 0, maxY, 10, 10, Length(cols));

	trazos.titulo(titulo);
  trazos.xlabel('Tiempo');
	trazos.ylabel('Costo');

  for iSerie:= 1 to high(cols) do
  begin
    nomSerie:= FloatToStrF(descVarLibre.discretizaciones[iSerie], fffixed, 10, 2) + ' ' + descVarLibre.unidades;
    colorSerie:= RGB(random(256), random(256), random(256));
    trazos.CrearSerieXY(nomSerie, nPuntos, false, colorSerie);
  end;

  trazos.Show;

 	trazos.dbj_xlabel;
	trazos.dbj_ylabel;
	trazos.dbj_titulo;
	trazos.dbj_etiquetasx;
	trazos.dbj_etiquetasy;
	trazos.dbj_borde;
	trazos.Etiquetas_x(filaIni+1, filaFin +1);
	trazos.Etiquetas_y(0, maxY);

	trazos.dbj_gridX;
	trazos.dbj_gridY;

  trazos.BringToFront;
  for iFila:= filaIni to filaFin do
  begin
    fila:= optres.datos[iFila];
    trazos.tr1.PlotNuevo_x(iFila);
    for iSerie:= 1 to Length(cols) do
      trazos.tr1.PlotNuevo_y(iSerie, fila[cols[iSerie-1]]);
    Application.ProcessMessages;
  end;
end;

procedure PlotIsoCurvas(
  Titulo: string;
  xlabel: string;
  ylabel: string;
  M: TMatR; vx, vy: TVectR;
  niveles: array of NReal;
  etiquetas: array of string );
var
  trx: TfrmDllForm;
  IsoScanner: TIsoScannerMatricial;
  px, py: NReal;
  pol: TPoligonalXY;
  res: boolean;
  ramaDirecta: boolean;
  plabel_x, plabel_y: NReal;
  knivel: integer;
  lblxy: TLabelXY;
  color: TColor;

begin
  trx:=TfrmDllForm.Create(ProcesarOptVarEstado);

	trx.CrearDiagramaXY(
		titulo, // Nombres
		512, // MaxNPuntos
		true, // ciruclar
		'x', // nombre_sx
		'', // nombre_sy1: pchar;
		clRed, //	color_sy1: TColor;
		vx.e(1), vx.e(vx.n), //	x1, x2,
		vy.e(1), vy.e(vy.n), //y1, y2
    vx.n-1,vy.n-1    // NDivX, NDivY
	);

	trx.show;
	trx.dbj_gridx ;
	trx.dbj_gridy;
	trx.dbj_borde;
	trx.titulo( titulo  );
	trx.etiquetas_x( vx.e(1), vx.e(vx.n) );
	trx.etiquetas_y( vy.e(1), vy.e(vy.n) );
	trx.xlabel( xlabel );
	trx.ylabel( ylabel );

  for knivel:= 0 to high( niveles ) do
  begin
    IsoScanner:= TIsoScannerMatricial.create( m, vx, vy, niveles[ knivel ] );
    color:= paleta1[ knivel+1 ];
    pol:= TPoligonalxy.Create( trx.tr1, 'p', false, color );
    ramaDirecta:= true;
    plabel_y:= 100000;

    repeat
       res:=IsoScanner.GetPunto(px, py );  {pedimos un punto a iso90}
       if IsoScanner.Estado = Reversa then
          ramaDirecta:= not ramaDirecta;

       if res then   {Si el punto es valido lo dibuja}
       begin
          if py < plabel_y then   {elige el punto más bajo}
          begin
              plabel_x:= px;
              plabel_y:= py;          {para poner la etiqueta}
          end;
          if ramaDirecta then
            pol.nuevoPunto( px, py)
          else
            pol.nuevoPuntoAlInicio( px, py );
        end;

       if IsoScanner.Estado = Semiactivo then   {termino con una curva}
       begin

          pol.Replot;
          pol:= TPoligonalxy.Create( trx.tr1, 'p', false, color );
          ramaDirecta:= true;
          // labelXY(0,plabel.x,plabel.y,luxs); {etiqueta la curva}
          lblxy:= TLabelXY.Create( trx.tr1, 'l', plabel_x, plabel_y, etiquetas[knivel], color, 10 );
          plabel_y:=10000;
       end;
    until IsoScanner.Estado = fin;       {hasta terminar}
    trx.tr1.RePlot;
    IsoScanner.Free;
  end;
end;

procedure TProcesarOptVarEstado.graficarCurvasISONivel(filaIni, filaFin: Integer; cols: TDAofNInt);
var
  mat: TMatR;
  x, y : TVectR;

  nPuntosT: Integer;
  titulo: String;

  iVarsFijas: Integer;
  descVarFija: TDescVar;

  iVarLibre: Integer;
  descVarLibre: TDescVar;
  iFila, iColumna, iFilaMat: Integer;
  fila: TDAofNReal;
  filaMat: TVectR;
begin
  iVarLibre:= optres.indiceDescVar(CBVarLibre.Items[CBVarLibre.ItemIndex]);
  descVarLibre:= TDescVar(optres.descVars[iVarLibre]);
  nPuntosT:= filaFin - filaIni + 1;

  x:= TVectR.Create_Init(nPuntosT);
  for iFila:= 1 to x.n do
    x.pon_e(iFila, filaIni + iFila - 1);
  y:= TVectR.Create_FromDAofR(descVarLibre.discretizaciones);
  mat:= TMatR.Create_Init(x.n, y.n);

  for iFila:= filaIni to filaFin do
  begin
    iFilaMat:= iFila - filaIni + 1;
    fila:= optres.datos[iFila];
    filaMat:= mat.Fila(iFilaMat);
    for iColumna:= 0 to high(cols) do
      filaMat.pon_e(iColumna + 1, fila[cols[iColumna]]);
  end;

  titulo:= 'Curvas ISONivel para';
  for iVarsFijas:= 0 to iVarLibre - 1 do
  begin
    descVarFija:= TDescVar(optres.descVars[iVarsFijas]);
    titulo:= titulo + descVarFija.nombre + ' en ' + FloatToStrF(descVarFija.discretizaciones[descVarFija.pos], fffixed, 10, 1) + ' ' + descVarFija.unidades + ', ';
  end;
  for iVarsFijas:= iVarLibre + 1 to optres.descVars.Count -1 do
  begin
    descVarFija:= TDescVar(optres.descVars[iVarsFijas]);
    titulo:= titulo + descVarFija.nombre + ' en ' + FloatToStrF(descVarFija.discretizaciones[descVarFija.pos], fffixed, 10, 1) + ' ' + descVarFija.unidades + ', ';
  end;

  PlotIsoCurvas(titulo,
                'Paso de Tiempo', 'Estado ' + descVarLibre.nombre + '[' + descVarLibre.unidades + ']',
                mat, x, y,
                niveles, etiquetasNiveles);
end;

procedure TProcesarOptVarEstado.editarISONiveles(var niveles: TDAofNReal; var etiquetasNiveles : TDAofString);
var
  form: TEditarISONiveles;
begin
  form:= TEditarISONiveles.Create(self, niveles, etiquetasNiveles);
  if form.ShowModal = mrOk then
  begin
    niveles:= form.getNiveles;
    etiquetasNiveles:= form.getEtiquetasNiveles;
  end;
  form.Free;
end;

procedure TProcesarOptVarEstado.compararContraCorte;
var
  archiRes: String;
begin
  archiRes:= 'cortes.xlt';
  optres.compararVariableContraCortes(CBVarLibre.Items[CBVarLibre.ItemIndex], niveles,
                                      filaIni, filaFin, archiRes);
  ShowMessage('Resultados guardados en ' + archiRes);
end;

end.
