Ir al contenido


Foto

Editar datos del DBGrid?


  • Por favor identifícate para responder
32 respuestas en este tema

#1 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 03 mayo 2016 - 02:59

Visto las inserciones de datos al dbgrid, he probado a volcar esos mismos datos a unos Tedit. He visto montones de formas de hacerlo, pero no quiero salirme de la metodología de uso que he venido realizando y bien me habéis asesorado. He probado con la instrucción.


php
  1. form.edit1.text:=Datamodule1.ZQuery2.ParamByName('nombre').AsString; 

pero no se si hay que realizar un SQL.text:= Select  antes. Zquery2 no se que hacer con el, y no se que componente tiene los datos de la fila seleccionada o activa en el dbgrid.

 

ya que al cargar el form, intento cargar los datos de la fila seleccionada del dbgrid en los campos Tedit el formulario. Esto lo realizo en el Oncreate del form, pero me da error! 

 

 


  • 0

#2 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 03 mayo 2016 - 03:02

Mmm, a ver si entiendo, quieres cargar los datos de una celda o registro seleccionado en un DBGrid a componentes TEdits?


  • 0

#3 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 03 mayo 2016 - 05:47

Si quieres mostrar los datos del registro activo del query en unos edits con el objetivo de que el usuario pueda verlos y modificarlos debes tener lo siguiente:

1. Dicho Query debe contener la consulta SQL SELECT correspondiente

2. Este mismo query debe estar abierto

 

Cuando se abre el Query el primer registro está "activo" por lo que una lectura de los campos como la que haces en tu código que nos muestras hará que en el edit en cuestión aparezcan estos datos.

 

Ahora bien, cuando te muevas entre los registros del DBGrid deberás "actualizar" el contenido de los edits. Una posibilidad de hacer esto es implementar justamente el evento OnAfterScroll, y ahí mismo leer el registro "reposicionado". La otra posibilidad es emplear el mecanismo que te ofrecen los data-ware: usar un DBNavigator, un TDataSource, y unos DBEdits, que solitos hacen "el trabajo sucio" que estás implementando.

 

Para que esto funcione, naturalmente el Query debe estar en todo momento abierto.

 

Lo que sigue es disponer de un botón "Editar" y ahí mismo poner el Query en modo de edición (si es que lo permite... no todos los tipos de consultas son actualizables) y hacer el paso inverso: pasar el contenido del edit (cambiado o no por el usuario) al respectivo campo y confirmar.

Ahora bien, por seguridad yo te aconsejo emplear otro Query distinto. Es lo que hacemos muchos: Tenemos querys, tables, etc. para cada cosa: insertar, mostrar, actualizar, borrar, para consultas tipo informes, para filtrar, etc. Y lo que hacemos es abrirlos y cerrarlos en los momentos oportunos.

Llamemosle QueryActualizar que tenga una SQL del tipo UPDATE. A éste Query se le pasa el contenido de los edits, y se ejecuta la consulta. Para que esto funcione naturalmente tal consulta SQL UPDATE debe tener en su parte WHERE las condiciones necesarias para identificar de forma inequívoca al registro en cuestión. Razón por la cual es que se aconseja sabiamente emplear los dichosos campos IDs que tu aún te resignas utilizar. Sin ese campo ID la cosa se hace más complicada, porque ahora deberás tener un WHERE que contemple todo los campos antes de la modificación. En sintesis algo como:


sql
  1. UPDATE TABLE <NombreTabla>
  2. SET Campo1=<Valor1>, Campo2=<Valor2>, ...
  3. WHERE (Campo1=<Valor1AntesDeCambiar>) AND (Campo2=<Valor2AntesDeCambiar>) ...

Es decir deberás tener unas variables (tantas como campos se necesiten) para almacenar temporalmente el contenido de los campos del registro leído, y de esta forma poder indentificar el registro que queremos modificar ¡Sin el WHERE (o un mal condicional) podrías llegar a alterar otros registros o hasta incluso TODOS!. Y obviamente, cuando se mueve de un registro a otro del DBGrid también debe irse "actualizando" estas variables.

 

Con un campo PRIMARY KEY la cosa es más sencilla. No hace falta tanta evaluaciones, simplemente un WHERE como esto:


sql
  1. ...
  2. WHERE (ID = IDEnCuestion)

Naturalmente, ese ID no debería ser modificable bajo ningún motivo.

Según yo recuerdo tu tienes definido como PRIMARY KEY al campo Nombre. No es tan mal, pero imagínate el siguiente escenario: en una Oficina de Registro Civil llega un padre contento para anotar a su primer hijo recién nacido. El nombre elegido es Miguel Lopes. (Si, con Lopes, con s y sin acento en la o), el agente social que lo atiende escucha el nombre y lo graba como Miguel López. El padre no se da cuenta del error, y se va ya con la partida de nacimiento y el DNI confeccionado.

Vuelve al día siguiente con el humor cambiado, y pide que le cambien el nombre... ¡El es descendiente de portugueses no de españoles! Es Lopes, no López. Los que diseñaron el sistema pusieron como clave primaria el nombre.... el desastre viene cuando hay el sistema no les deja alterarla.

Otro escenario: Al intentar ingresar el nombre como Miguel López, el sistema detecta que ya hay una persona con el mismo nombre... un tipo de 34 años. Ya vez porqué nunca es buena señal que los nombres sean claves primarias.

 

 

Para finalizar, no quisiera terminar mi post si hacerte una fuerte crítica. Ya sabes como son las cosas en el foro dooper. Sin decirnos el error, y sin aportarnos mayores detalles que nos den un panorama más amplio es difícil que lleguemos a predecir efectivamente cual es el problema que tienes. Esa simple línea de código no nos dice nada.

 

Saludos,


  • 0

#4 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 04 mayo 2016 - 11:02

Mmm, a ver si entiendo, quieres cargar los datos de una celda o registro seleccionado en un DBGrid a componentes TEdits?

 

Cargar los datos de la fila completa activa del dbgrid, en un form con componentes TEdits (nombre, edad y sexo).


php
  1. Para finalizar, no quisiera terminar mi post si hacerte una fuerte crítica. Ya sabes como son las cosas en el foro dooper.
  2. Sin decirnos el error, y sin aportarnos mayores detalles que nos den un panorama más amplio es difícil que lleguemos a predecir
  3. efectivamente cual es el problema que tienes. Esa simple línea de código no nos dice nada

 Si es que no puedo aportar mayores detalles, ni errores ya que no hay errores, y los detalles que expongo son esos. He sacado de conclusión que sería la inversa de la inserción, pero veo que no. Tengo muchas lineas de código en la cabeza, pero no consigo asociarlas a lo que realmente quiero, y lo que es realmente necesario, por ello necesito algo que me encauce a nivel de codigo, ya que he visto codigo por ahí que me desvían de mi metolodogía y la que habéis podido darme como aprendizaje.

 

Un saludo


  • 0

#5 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 04 mayo 2016 - 11:29

Veamos, con este código  consigo que aparezca el 1º registro en los TEdit del form, pero si cierro el form, y selecciono otro registro activo, al cargar el form me sigue saliendo en 1º registro, cuando debería visualizar el registro que ahora está activo en la grilla.


php
  1. procedure TForm4.FormCreate(Sender: TObject);
  2. begin
  3. Datamodule1.ZQuery2.Close;
  4. DataModule1.ZQuery3.SQL.Text := 'SELECT * FROM "personas"';
  5. DataModule1.ZQuery3.Open;
  6.  
  7. form.edit1.text:=Datamodule1.ZQuery3.ParamByName('nombre').AsString;
  8. // Con ParamByName me da error, si lo cambio por
  9. // FieldByName funciona, a que se debe esto. la
  10. // inserción uso ParamByName y no da error

Tipo de error: Excepción EDatabaseError con el código ZQuery3: Parameter "nombre" not found.


  • 0

#6 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 05 mayo 2016 - 12:46

Tomando todas las consideraciones y consejos de mi compañero y estimado Delphius, no termino de ubicar el problema.

 

Creo un Zquery3 para la edición en el datamodule. Al pulsar el botón "Editar" me carga un Form, pero siempre visualiza el 1º registro del DBGrid.

 

En este form en el evento Oncreate he insertado el código indicado arriba, para cuando cargue visualice los campos del registro el DBGrid supuestamente activo.

 

Al cerrar el formulario y seleccionar otro registro distinto del primero en el dbgrid, y volver a editar los datos a través del Form, nada! Siempre

carga el registro nº 1, indpendiente del registro activo.

 

Intentado usar el evento OnAfterScroll en el componente Zquery3, pero no se que insertar en él, ya que todo lo realizo en el Oncreate.

 

Me estoy centrando en la edición de los campos, otra cuestión será la modificación UPDATE.

 

Un saludo


  • 0

#7 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 05 mayo 2016 - 02:06

Veamos, con este código  consigo que aparezca el 1º registro en los TEdit del form, pero si cierro el form, y selecciono otro registro activo, al cargar el form me sigue saliendo en 1º registro, cuando debería visualizar el registro que ahora está activo en la grilla.


php
  1. procedure TForm4.FormCreate(Sender: TObject);
  2. begin
  3. Datamodule1.ZQuery2.Close;
  4. DataModule1.ZQuery3.SQL.Text := 'SELECT * FROM "personas"';
  5. DataModule1.ZQuery3.Open;
  6.  
  7. form.edit1.text:=Datamodule1.ZQuery3.ParamByName('nombre').AsString;
  8. // Con ParamByName me da error, si lo cambio por
  9. // FieldByName funciona, a que se debe esto. la
  10. // inserción uso ParamByName y no da error

Tipo de error: Excepción EDatabaseError con el código ZQuery3: Parameter "nombre" not found.

 

Ese error se debe a que una cosa son los parámetros y otra los campos. Los parámetros se usan generalmente en consultas a las que se les va a suministrar o pasar un valor... justamente los parámetros. En el SQL se los referencia justamente anteponiendo dos puntos. El caso típico de ejemplo que puedes ver es en consultas INSERT. Por ejemplo:


sql
  1. INSERT INTO Personas(Nombre, Edad, Sexo) VALUES (:ParamNombre, :ParamEdad, :ParamSexo)

Puedes ver en ese SQL que se han definido 3 parámetros, justamente para hacerlo se han puesto dos puntos adelante. Esto le dice al Query que deberá tomar los valores mediante ParamByName.

Fíjate que para diferenciar el nombre de los campos (Nombre, Edad, Sexo) es que nombré a los parámetros por el prefijo "Param". Es legal tener el mismo nombre, aunque yo prefiero distinguirlos. Hay quienes consideran "Manual de estilo" que los parámetros se nombren como prefijo ":P" (P de Params) Por ejemplo, para un campo llamado Cantidad, su parámetro sea :PCantidad.

 

Entonces, una cosa es FieldByName, que es para acceder a los campos. Y otra es el ParamByName que es para acceder a los parámetros.

 Notarás que en tu código de muestra no hay parámetros. ¡Es un SELECT *! Por tanto si intentas hacer ParamByName() te reportará error.

 

Sobre lo otro que comentas, tengo que repensar un poco... a ver si comprendo la falla.

 

Saludos,


  • 0

#8 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 05 mayo 2016 - 03:09

Ahhh, pues lección aprendida amigo Delphius, luego ya se cuando usar uno u otro. Hay mucha teoría sobre el uso de estos dos nombres.

 

En  cuanto al segundo caso, no consigo, ni veo la opción de saber que "variable" (Dataset) tiene los datos del registro entero del DBgrid activo.

 

En el DBgrid cuando indicaba "SELECT * FROM "personas"" me volcaba todos los datos de personas. Pero no se como hacer con una sentencia SQL me devuelve el registro actual seleccionado en el DGBRid para luego dar la orden de


php
  1. form.edit1.text:=Datamodule1.ZQuery3.FieldByName('nombre').AsString;

y así visualizar el campo "nombre" en el Edit1.text. Todo esto lo hago, al pulsar button y cargar el Form.


  • 0

#9 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 06 mayo 2016 - 05:58

Por ejemplo, si el DBGrid esta conectado a un dataset llamesmole zempleados, para obtener el nombre del objeto activo simplemente haces esto:



delphi
  1. ZQuery3.SQL.text := 'select * from personas where nombre = ' + zempleados.fieldbyname('nombre').asstring;


Saludos.
  • 0

#10 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 06 mayo 2016 - 12:20

Yo tengo un solo DataSource y en su propiedad Dataset = Zquery1 que uso este Zquery1 para la consulta SELECT * FROM personas y así imprimir en el dbgrid todos las personas.

 

Luego zempleados.fieldbyname('nombre').asstring debería quedarme como zquery1.fieldbyname('nombre').asstring que es lo mismo?

 

 

Además, esa instrucción como guarda en el Edit1 del form el nombre, si no se hace referencia a ningun Edit?

 

Un saludo


  • 0

#11 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 06 mayo 2016 - 12:57

Como no estás trabajando con componentes DB-Aware, obvio debes trabajar a puras consultas, en tu caso, esa consulta te devuelve los datos del registro seleccionado en el DBGrid, por lo que resta hacer lo siguiente (Que se suponía que ya debieras tener conocimiento de ello):

 


delphi
  1. Edit.Text := ZQuery3.FieldByName('nombre').asString;

 

Por lo que quedaría así:


php
  1. ZQuery3.Close;
  2. ZQuery3.SQL.Text := 'select * from personas where nombre = ' + ZQuery1.fieldbyname('nombre').asstring;
  3. ZQuery3.open;
  4.  
  5. Edit1.text := ZQuery3.FieldByName('nombre').asstring;

Saludos.


  • 0

#12 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 06 mayo 2016 - 02:11

Gracias amigo Enecumene, me cuesta organizarme con tanto Query, y sentencias SQL. No hubiera sido más facil usar el componente ZTable?

usando edit, post, delete,....acortando instrucciones que usar SQL.text=

 

Acabo de probar tu ayuda enecumene,y zas...


php
  1. Excepcion "EDatabaseError' el mensaje ZQuery1: Parameter "nombre" not found"

ZQuery1 es usado para el volcado de datos  al Dbgrid con un Datamodule1.Zquery1.sql.text = 'Select * from "personas";


  • 0

#13 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 06 mayo 2016 - 03:10

Creo que has visto mal, estas usando ParamByName en vez de FieldByName ;).


  • 0

#14 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 06 mayo 2016 - 03:26

:( el código generado es este


php
  1. Datamodule1.ZQuery3.Close;
  2. Datamodule1.ZQuery3.SQL.Text := 'SELECT * FROM "personas" WHERE nombre = '+ Datamodule1.ZQuery1.FieldByName('nombre').AsString;
  3. Datamodule1.ZQuery3.Open;
  4.  
  5. form.edit1.text:=Datamodule1.ZQuery3.FieldByname('nombre').AsString;

no veo que use ParamByName, por ningun lado!


  • 0

#15 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 06 mayo 2016 - 03:41

:( el código generado es este


php
  1. Datamodule1.ZQuery3.Close;
  2. Datamodule1.ZQuery3.SQL.Text := 'SELECT * FROM "personas" WHERE nombre = '+ Datamodule1.ZQuery1.FieldByName('nombre').AsString;
  3. Datamodule1.ZQuery3.Open;
  4.  
  5. form.edit1.text:=Datamodule1.ZQuery3.FieldByname('nombre').AsString;

no veo que use ParamByName, por ningun lado!

 

No se ve porque no está usando parámetros, lo que hace es obtener el fieldByName('NOMBRE') como un campo string.

 

Si se quisiera utilizar parámetros sería mas o menos así.


delphi
  1. Datamodule1.ZQuery3.Close;
  2. Datamodule1.ZQuery3.SQL.Text := 'SELECT * FROM "personas" WHERE nombre = :nom ';
  3. Datamodule1.ZQuery3.ParamByname('NOM').AsString := Datamodule1.ZQuery1.FieldByName('nombre').AsString;
  4. Datamodule1.ZQuery3.Open;
  5. form.edit1.text := Datamodule1.ZQuery3.FieldByname('nombre').AsString;
  6.  

Saludos


  • 0

#16 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 06 mayo 2016 - 03:49

¿seguro?, porque eso es lo que implica el error que pones, revisa si el dataset ZQuery1 no tenga parámetros creados.


  • 0

#17 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 06 mayo 2016 - 03:50

Mi intención Egostar y creo que así me estaba guiando enecumene, es de la fila actual activa del DBGrid, recuperar los campos de esa fila y pasarlos a unos TEdit, si cambiara de fila actual activa, pues la misma operación pero con los datos nuevos. Entiendo en parte tu código!


  • 0

#18 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 06 mayo 2016 - 03:52

¿seguro?, porque eso es lo que implica el error que pones, revisa si el dataset ZQuery1 no tenga parámetros creados.

No! ZQuery1 -> propiedad  params-> items 0. 

 

Mismo error con sentencias de EgoStar. no se que puede tener Zquery1 para que me "tire" para atrás el parámetro nombre.

 

Nada de nada, Zquery1 me indica que field not found "nombre". Sigo sin entender por donde puede venir este error.


  • 0

#19 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 09 mayo 2016 - 08:23

Como puedo atacar este error? Llevo varios días y no se porque ZQuery1 que lo uso para un SELECT * pueda indicarme que no reconoce el parámetro

"nombre".


  • 0

#20 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 09 mayo 2016 - 09:06

Nada más se me ocurre crear de nuevo el ZQuery1, pero antes, verifica bien como tienes la consulta en el ZQuery1.


  • 0




IP.Board spam blocked by CleanTalk.