Mensaje    Asunto: Todo con Enter y Esc Incluyendo DBGrids Responder citando

Se muestra como avanzar y retroceder con Enter y Esc por todos los controles del form inclusive las celdas de los DBGrids, Hacer validaciones y completar valores. Esta tecnica es muy apreciada por los usuarios que deben rellenar ingente cantidad de informacion.

Este ejemplo es una tipica aplicacion de facturacion con tablas en relacion master/detail, coloca las tablas y establece la relacion, los DBEdits y la DBGrid (pueden ser varias, tambien funciona) pon el Key Preview del Form a true y el codigo siguente en el evento OnKeyPress, ponemos tambien una Query para ayudarnos en las validaciones.

Código:
void __fastcall TfProformas::FormKeyPress(TObject *Sender, char &Key)
{

if (Key == 13)
{
 TDBGrid* DBGrid = dynamic_cast<TDBGrid*>(ActiveControl);
 if (DBGrid)
 {
  //recorrer celdas hasta siguente readonly=false
  while(true)
  {
   if (DBGrid->SelectedIndex < DBGrid->FieldCount-1)
    if(DBGrid->Columns->Items[DBGrid->SelectedIndex+1]->ReadOnly==true)//No se detiene en celdas ReadOnly
     DBGrid->SelectedIndex += 1;
    else
     break;
    else
     break;
  }
  if (DBGrid->SelectedIndex < DBGrid->FieldCount-1)
   DBGrid->SelectedIndex += 1; // siguente columna


  else
   SelectNext(ActiveControl, true, true);// salir del grid

 }
else // no es dbgrid
{
 SelectNext(ActiveControl, true, true); //adelante

}
}
else // no es Enter
if (Key == 27)//Esc retrocedemos
SelectNext(ActiveControl, false, true); // atras
}
//---------------------------------------------------------------------------

El siguente codigo hace que al entrar al grid se seleccione la primera celda de la fila activa e inserte un nuevo registro si no lo hubiese.
Código:
//---------------------------------------------------------------------------
void __fastcall TfProformas::DBGrid11Enter(TObject *Sender)
{
if(tbDetalles->RecordCount==0)
 tbDetalles->Append();
DBGrid1->SelectedIndex=1;

}
//---------------------------------------------------------------------------

Ahora veremos como validar lo tecleado y/o proporcionar ayuda para el usuario, primero necesitamos "marcar" el indice activo de la grid al entrar ya que este cambiara cuando el usuario vuelva a presionar Enter.
Para ello usaremos una variable privada Index de tipo entero y escribimos la respuesta al evento OnKeyDown del DBGrid
Código:
//---------------------------------------------------------------------------
void __fastcall TfProformas::DBGrid11KeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{

Index=DBGrid1->SelectedIndex;

}
//---------------------------------------------------------------------------

Supongamos que queremos que al pulsar enter en la celda correspondiente al codigo del producto se verifique que este existe y en caso positivo llenar las casillas descripcion y precio... entonces interceptamos el evento OnKeyPress del grid asi:
Código:
void __fastcall TfProformas::DBGrid11KeyPress(TObject *Sender, char &Key)
{
if(tbDetalles->FieldByName("Renglon")->AsString=="")
 Key=0;//Si la celda esta vacia anulamos la accion
 if(Key==13 )
 {
 tbDetalles->Edit();
  if(Index==1)//index en el grid del campo Codigo
  {
    qryQuery->SQL->Clear();
    qryQuery->SQL->Add("Select Descripcion, Precio from Productos where Codigo='"+tbDetalles->FieldByName("Codigo")->AsString+"' ");
    qryQuery->Open();
    if(qryQuery->RecordCount==1)
    {
      tbDetalles->FieldByName("Descripcion")->AsString=
                   FQuery->Query1->FieldByName("Descripcion")->AsString;
      tbDetalles->FieldByName("Precio")->AsFloat=
                    FQuery->Query1->FieldByName("Precio")->AsFloat;
     DBGrid1->SelectedIndex=4;//Index correspondiente a Cantidad
     }
     else
       ShowMessage("Codigo Invalido");
  }
 }
}

Se puede añadir condiciones tales como verificar el Stock al dar enter en Cantidad y otras que se consideren necesarias.