Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Desproteger DBGrid en ejecución (https://www.clubdelphi.com/foros/showthread.php?t=91500)

aguml 20-02-2017 15:49:15

Desproteger DBGrid en ejecución
 
Hola amigos, estoy trasteando un poco con las bases de datos y me encuentro con el siguiente problema. Tengo un DBGrid el cual de inicio se selecciona toda la fila, no tiene habilitada la opcion de seleccionar varias filas, no se puede editar el valor de las celdas y tiene la propiedad de ReadOnly a true. Quiero revertir todo eso para poder hacerlo al ingresar una contraseña y de momento estoy con esta prueba:
Código PHP:

void __fastcall TForm2::ButtonDesbloquearClick(TObject *Sender)
{
    
AnsiString pass "1234567890";
    
AnsiString cadena InputBox("Desbloqueo de lista","Introduce la contraseña:","");
    if(
pass == cadena)
    {
        
DBGrid1->Options TDBGridOptions(DBGrid1->Options) >> dgRowSelect >> dgEditing;
        
DBGrid1->ReadOnly false;
        
DBNavigator1->Enabled true;
    }else{
        
ShowMessage("Contraseña incorrecta. No se ha desbloqueado la lista.");
    }


Me encuentro con que se deshabilita la opcion dgRowSelect pero parece que la opcion dgEditing no porque no me deja editar nada. ¿Pueden ayudarme?

ecfisa 20-02-2017 16:14:57

Hola.

Código PHP:

...
{
  
DBGrid1->ReadOnly false;
  
DBGrid1->Options  DBGrid1->Options +
    
TDBGridOptions() >> dgRowSelect << dgEditing << dgMultiSelect ;
  
// O también:
  // DBGrid1->Options  = TDBGridOptions(DBGrid1->Options) >> dgRowSelect
  //  << dgEditing << dgMultiSelect ;
 


Saludos :)

aguml 20-02-2017 16:44:21

Gracias lo pruebo cuando llegue y te digo que tal. Por cierto no quiero que se pueda hacer multiseleccion nunca así que lo que haces al final supongo que puedo quitarlo.
Otro problema que tenia es que uso en el evento onclick del dbgrid:
Código PHP:

EditNombre->Text=DBGrid1->DataSource->DataSet->FieldValue["Nombre"]; 

Una vez que podía editar si creo un nuevo registro con el botón + del DBNavigator aparecía la línea y si la selecciono me sale un error donde dice que no se puede convertir una variable de tipo null a string. Lo he "solucionado" usando un try catch pero me gustaría hacerlo correctamente y no se como seria. ¿podrías ayudarme con eso también?

ecfisa 20-02-2017 17:09:18

Cita:

Empezado por aguml (Mensaje 513498)
Por cierto no quiero que se pueda hacer multiseleccion nunca así que lo que haces al final supongo que puedo quitarlo.

Si, así es.

Cita:

Empezado por aguml (Mensaje 513498)
... si creo un nuevo registro con el botón + del DBNavigator aparecía la línea y si la selecciono me sale un error donde dice que no se puede convertir una variable de tipo null a string. Lo he "solucionado" usando un try catch pero me gustaría hacerlo correctamente y no se como seria. ¿podrías ayudarme con eso también?

Agrega el mismo código al evento BeforeAction:
Código PHP:

void __fastcall TForm1::DBNavigator1BeforeAction(TObject *Sender,
      
TNavigateBtn Button)
{
  if ( 
Button == nbInsert )  // ¿ inserta ?
 
{  
    
DBGrid1->ReadOnly false;
    
DBGrid1->Options  TDBGridOptions(DBGrid1->Options) >> dgRowSelect
                        
<< dgEditing;
  }


Saludos :)

aguml 20-02-2017 18:18:34

Creo que no me he explicado bien, el DBNavigator por defecto esta deshabilitado y al desbloquear todo también habilito a este. Si le doy al + pero no escribo nada y cambio de columna en la misma fila y luego vuelvo a la celda de columna Nombre de esa fila, en ese momento es cuando me tira la excepción.

ecfisa 20-02-2017 18:45:08

Hola.
Cita:

Empezado por aguml (Mensaje 513503)
Creo que no me he explicado bien, el DBNavigator por defecto esta deshabilitado y al desbloquear todo también habilito a este. Si le doy al + pero no escribo nada y cambio de columna en la misma fila y luego vuelvo a la celda de columna Nombre de esa fila, en ese momento es cuando me tira la excepción.

Reproduje la situación que comentas arriba y no obtengo error.

Tal vez descubriríamos algo si nos publicas los eventos y código donde desactivas y donde activas las acciones.

Saludos :)

aguml 20-02-2017 22:01:07

Te pongo el enlace para poder descargar el proyecto: https://mega.nz/#!Uo0y2ZbT!WT7qUG6OQ...OoLYEFu6bTkt4E
Es solo una prueba para experimentar con sqlite y zeosdb ya que no se casi nada de ellos y queria ver su uso un poco haciendo una especie de base de datos de clientes donde se van insertando las consumisiones.

ecfisa 21-02-2017 13:19:21

Hola.

No pude compilar y/o ejecutar tu código por que me faltan componentes, pero cuando usas la propiedad vectorial FieldValues en el evento OnCellClick deberías revisar que el valor del campo actual no sea nulo:
Código PHP:


void __fastcall TForm2
::DBGrid1CellClickTColumn *Column )
{
  
TDBGrid  *GR static_cast<TDBGrid*>( DBGrid1 );
  
TDataSet *DS static_cast<TDataSet*> ( DBGrid1->DataSource->DataSet );

  
EditNombre->Text VarToStrDef(DS->FieldValues["Name"], "");  // <-
  
EditPrecio->Text VarToStrDef(DS->FieldValues["Area"], "0"); // <-  

  
if ( EditUnidades->Text != "" && EditPrecio->Text != "" )
    
EditTotal->Text EditUnidades->Text.ToDouble() *
                      
EditPrecio->Text.ToDouble();


Por mi parte prefiero no usar la propiedad FieldValues ya que, debido a que usa Variants, es la opción mas lenta.

Mas rápido es:
Código PHP:

...
void __fastcall TForm2::DBGrid1CellClickTColumn *Column )
{
  
TDBGrid  *GR static_cast<TDBGrid*>( DBGrid1 );
  
TDataSet *DS static_cast<TDataSet*>( DBGrid1->DataSource->DataSet );

  
EditNombre->Text DS->FieldByName("Nombre")->AsString;
  
EditPrecio->Text DS->FieldByName("Precio")->AsString;

  if ( 
EditUnidades->Text != "" && EditPrecio->Text != "" )
    
EditTotal->Text EditUnidades->Text.ToDouble() *
                      
EditPrecio->Text.ToDouble();
}
... 

Por último la opción mas eficiente es crear los campos persistentes del TDatSet y citarlos por su nombre.

Saludos :)

aguml 21-02-2017 17:16:21

Que es eso de los campos persistentes?

ecfisa 21-02-2017 20:24:45

Hola.
Cita:

Empezado por aguml (Mensaje 513545)
Que es eso de los campos persistentes?

Para crearlos en tiempo de diseño básicamente los pasos son:
  1. Doble click sobre el componente DataSet (se abre ventana)
  2. Click botón derecho sobre la nueva ventana
  3. Click botón izquierdo sobre el ítem: Add all fields
Vas a encontrar una explicación detallada sobre el tema en el capítulo "Acceso a campos" de La cara oculta de Delphi 4.

Saludos :)


La franja horaria es GMT +2. Ahora son las 08:35:33.

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