PDA

Ver la Versión Completa : Validar datos en una grilla/tabla


lbidi
08-07-2013, 23:14:51
Estimados.

Tengo una grilla de n filas por 2 columnas, asociada a una tabla. En la misma debo ingresar/modificar solamente números los cuales no se pueden repetir en ninguna otra celda de la tabla.

No me doy cuenta en cual evento puedo controlar esto, si en alguno de la tabla o de la grilla, porque
debo hacer todos los controles sobre todos las posibles salidas de la celda actual, sea con Enter o movimientos de cursor.

Se agradece cualquier sugerencia y/o comentario.

Saludos

Leo

ozsWizzard
09-07-2013, 05:09:27
Solución 1
En el DataSet hay un beforesinsert y un beforeupdate, y validas antes de grabar en la tabla.

Eso se me ocurre.

Solución 2
Yo tengo un StringGrid (porque dices una grilla y he asumido que es un DBGrid) al que le creé el evento "ExitCell", pero esta solución te hace cargar los datos a mano en el Grid

Definición, justo después del uses

TExitCell = procedure(Sender: TObject; const ACol, ARow: Integer) of object;

TStringGrid = class(Vcl.Grids.TStringGrid)
private
FCol: Integer;
FRow: Integer;
FEntrar: Boolean;
EditCel: Boolean;

FExitCell: TExitCell;
protected
function SelectCell(ACol, ARow: LongInt): Boolean; override;

procedure DoEnter; override;
procedure DoExit; override;
public
property ColAux: Integer read FCol write FCol default 0;
property RowAux: Integer read FRow write FRow default 0;
property Entrar: Boolean read FEntrar write FEntrar;

//Eventos
property OnExitCell: TExitCell read FExitCell write FExitCell;
end;


Implementación

{ TStringGrid }

procedure TStringGrid.DoEnter;
begin
inherited;
ColAux := Col;
RowAux := Row;
Entrar := true;
end;

procedure TStringGrid.DoExit;
begin
if Assigned(OnExitCell) then OnExitCell(Self, ColAux, RowAux);
inherited;
end;

function TStringGrid.SelectCell(ACol, ARow: LongInt): Boolean;
begin
//Para no repetir el evento OnExitCell cuando se entra al StringGrid
if Entrar then
Entrar := false
else
if Assigned(OnExitCell) then OnExitCell(Self, ColAux, RowAux);
inherited;
ColAux := ACol;
RowAux := ARow;

EditCel := false;
Result := true;
end;



Solamente falta crear el procedimiento y asignarlo en tiempo de ejecución a la propiedad "OnExitCell".

También se puede meter en una unidad y ponerla siempre después de Grids.

ecfisa
09-07-2013, 15:01:14
Hola Ibidi.

Otra opción, usando un TDBGrid, es aprovechar el evento OnValidate de los dos campos que no deberán repetirse (vg. CAMPO1 y CAMPO2):

...
procedure TForm.FormCreate(Sender: TObject);
begin
tuTabla.FieldByName('CAMPO1').OnValidate := tbCamposValidate;
tuTabla.FieldByName('CAMPO2').OnValidate := tbCamposValidate;
end;

procedure TForm.tbCamposValidate(Sender: TField);
begin
tuQuery.Close;
tuQuery.SQL.Clear;
tuQuery.SQL.Add('SELECT Campo1 FROM ATABLA');
tuQuery.SQL.Add('WHERE Campo1 = :PVALUE OR Campo2 = :PVALUE');
tuQuery.ParamByName('PVALUE').AsInteger := Sender.AsInteger;
tuQuery.Open;
if not tuQuery.IsEmpty then
raise Exception.Create('Valor existente');
tuQuery.Close;
end;
...
procedure TForm.FormDestroy(Sender: TObject);
begin
tuTabla.FieldByName('CAMPO1').OnValidate := nil;
tuTabla.FieldByName('CAMPO2').OnValidate := nil;
end;

Para que sea mas claro asigné el evento OnValidate en tiempo de ejecución. Pero lo podes hacer mediante el Object Inspector creando los campos persistentes en diseño y ahorrándote la asignación por código.

Saludos.

Saludos. :)