Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   ClientDataset no inserta registros si sistema tarda en inactividad (https://www.clubdelphi.com/foros/showthread.php?t=78183)

Tcmn 27-03-2012 05:10:35

ClientDataset no inserta registros si sistema tarda en inactividad
 
Hola, disculpen si es muy largo el titulo del hilo.

Tengo algo muy raro en un sistema que ya esta en funcionamiento desde hace algunos meses y aunque así estan trabajando los usuarios, obviamente no es lo mas optimo como se daran cuenta.

El escenario es:

Delphi 6

Firebird 2.1

ClientDataset

Objetos de Interbase para conexion

Windows XP Profesional SP3

El asunto es que una tabla que es detalle se "bloquea" y no acepta inserciones si el usuario a durado 5 o mas minutos sin usar el programa. La tabla maestra se llama Contratos y esta a su vez tiene como tablas de detalles a ObjetosEmpeñados, Intereses, Abonos y Aumentos.

En la capa de acceso a datos uso IBQuery y con ellos establezco la relacion Maestro/Detalle con la propiedad DataSource de las tablas detalles. Posteriormente en la capa donde van todos los DatasetProvider y ClientDataset conecto las tablas de detalles usando la capacidad de ClientDataset de usar datos anidados con los FieldDataSet.

Todas las tablas de detalle funcionan bien todo el tiempo, y también todas las demas tablas de la base de datos trabajan y responden al momento, pero en el caso de una tabla detalle (ObjetosEmpeñados), al ejecutar la instruccion:

Código Delphi [-]
ObjetosEmpenados.Insert;

Los controles DataAware no responden, no permite al operario escribir nada, pero si cancela la alta presionando el respectivo
boton para cancelar la alta, ahora si deja insertar los detalles. Ya revise todo lo que se me ha ocurrido, como la configuracion de los campos(providerFalgs) pero no mas no.

Es muy raro el comportamiento, y ya no se me ocurre que mas verificar.

Espero haberme explicado y si alguien puede echarme una mano, seran bienvenidas las observaciones.

Gracias de antemano

Al González 27-03-2012 06:16:31

Cita:

Empezado por Tcmn (Mensaje 428538)
Todas las tablas de detalle funcionan bien todo el tiempo, y también todas las demas tablas de la base de datos trabajan y responden al momento, pero en el caso de una tabla detalle (ObjetosEmpeñados), al ejecutar la instruccion:

Código Delphi [-]
ObjetosEmpenados.Insert;

Los controles DataAware no responden, no permite al operario escribir nada, pero si cancela la alta presionando el respectivo
boton para cancelar la alta, ahora si deja insertar los detalles.

Ayúdame a entender. ¿Dices que cuando el registro maestro está en modo de inserción (captura de alta), es cuando no deja poner en modo de inserción también al conjunto de datos detalle ObjetosEmpenados? Es decir, ¿que sólo permite agregar detalles a un registro maestro ya guardado?

Creo que hay que precisar los detalles del caso para que podamos comprender mejor lo que está sucediendo.

Saludos. :)

Tcmn 27-03-2012 21:51:37

Cita:

Empezado por Al González (Mensaje 428540)
Ayúdame a entender. ¿Dices que cuando el registro maestro está en modo de inserción (captura de alta), es cuando no deja poner en modo de inserción también al conjunto de datos detalle ObjetosEmpenados? Es decir, ¿que sólo permite agregar detalles a un registro maestro ya guardado?


Cuando se da de alta en la tabla maestra un nuevo registro, el sistema tiene un candado de que el usuario no puede meter registro detalles, a menos que ya haya guardado por lo menos una vez la cabecera.

El procedimiento habitual es:

1.- Usuario presiona botón "Alta de contrato"
2.- Especifica el monto que se prestara al cliente.
3.- Presiona botón "Guardar contrato" (El sistema hace commit, para obtener la clave maestra que servirá como clave foránea con la tabla detalle)
4.- Usuario presiona botón "Insertar objeto a empeñar" [FONT='Calibri','sans-serif'](Hasta aquí siempre va bien)[/font]

[FONT='Calibri','sans-serif']5.-[/font][FONT='Calibri','sans-serif'] Se pone el foco en el primer BDEdit que debe almacenar la información del detalle del contrato. [/font][FONT='Calibri','sans-serif'](Aquí es donde a veces falla cuando tiene un ratito el sistema en inactividad)[/font]

6.- Si no se puede poner nada de información en los controles DataAware, el usuario presiona “Cancelar alta de objeto a empeñar”, y después debe presionar otro botón que dice “Deshacer alta del contrato” para que se cancele el alta del nuevo empeño, ese botón, lo que hace es eliminar el nuevo registro que se dio de alta en la tabla que es cabecera (Contratos), para que después el usuario vuelva a presionar el botón “Alta de contrato” o en otras palabras vuelva a iniciar en el paso 1 de este proceimiento.

Espero haber respondido dudas.

Al González 27-03-2012 22:13:54

Cita:

Empezado por Tcmn (Mensaje 428608)
[...] el sistema tiene un candado de que el usuario no puede meter registro detalles, a menos que ya haya guardado por lo menos una vez la cabecera [...]

Ahí podría estar la clave del problema. ¿Cómo funciona ese candado? ¿Sería mucho pedir que pusieras aquí algo de código fuente? :)

Por otra parte, considera asignar la llave maestra desde que inicia la captura, no importando si el registro termina siendo guardado o no por parte del usuario. Aquí encontrarás varios temas sobre las ventajas de usar esta técnica y lo irrelevante que es el valor que tenga dicha llave (consecutiva o con "huecos") mientras cumpla la indispensable condición de ser única dentro de la tabla (llaves primarias artificiales).

También toma en cuenta que una de las ventajas de los conjuntos de datos anidados es poder enviar de un golpe todo el paquete (registro maestro y detalles) a la base de datos. Me resulta un poco extraño que el usuario deba guardar el maestro para luego permitirle capturar los detalles.

Saludos.

Tcmn 30-03-2012 18:24:44

Cita:

Empezado por Al González (Mensaje 428613)
Ahí podría estar la clave del problema. ¿Cómo funciona ese candado? ¿Sería mucho pedir que pusieras aquí algo de código fuente? :)

Pondre el codigo correspondiente a cada paso
1.- Alta del contrato:

Código Delphi [-]
procedure TFrmEmpenos.BtnAddContClick(Sender: TObject);
  begin
  LogicaNegocio.CTDContratos.EnableControls;
  LogicaNegocio.CTDContratos.Insert;
BtnGuardaCambiosAltaCont.Enabled:=True;
  BtnCancelarAltaCont.Enabled:=True;
  BtnQuitarPrendaDetalleContrato.Enabled:=False;
  BtnAddCont.Enabled:=False;
  DBEdit46.ReadOnly:=False;{numero de contrato}
  DBEdit46.SetFocus;
  end;

2.- Guardar el nuevo contrato:

Código Delphi [-]
procedure TFrmEmpenos.BtnGuardaCambiosAltaContClick(Sender: TObject);
  begin
  with LogicaNegocio do
    begin
  CadenaAbuscar:=CTDContratosNUM_CONT.AsString;
    CTDContratos.DisableControls;
    CTD1Cliente.DisableControls;
    if CTDContratos.State in dsEditModes then CTDContratos.Post;
    if CTD1Cliente.State in dsEditModes then CTD1Cliente.Post;
   
    CTD1Cliente.Refresh;
    CTDPrend_Emp.EnableControls;
    CTDContratos.Locate('num_cont',CadenaAbuscar,[loCaseInsensitive]);
    CTDContratos.EnableControls;
    CTD1Cliente.EnableControls;
    BtnGuardaCambiosAltaCont.Enabled:=False;
    BtnCancelarAltaCont.Enabled:=False;
    BtnDesHacerAltaContrato.Enabled:=True;
    DBEdit46.ReadOnly:=True; //Numero de contrato
  //Si la tabla esta en modo de insercion

  if EstadoInsert=True then
      begin
      RejillaPrendasEmpenadasAltaCont.Enabled:=False;
      NavegaPrendasEmpenadas.Enabled:=False;
      BtnInsertarPrendaAltaContrato.Enabled:=True;
      end;//if 
     if not CTDPrend_Emp.IsEmpty then BtnAddCont.Enabled:=True; 
    end;//with
  //Boton para eliminar el contrato por si finalmente no se concreta contrato nuevo con el cliente

BtnDesHacerAltaContrato.Enabled:=True;

  End;

3.- Una vez guardando el registro maestro, es decir, el contrato se procede a insertar las lineas de detalle del contrato por medio de un boton para agregar registros, con el siguiente codigo:

Código Delphi [-]
   procedure TFrmEmpenosCompraOro.BtnInsertarPrendaAltaContratoClick(
    Sender: TObject);
  begin
  {"Seguro" para que no se congele la aplicacion cuando ya tiene un rato sin
  trabajarse con ella}
  if AccesoDatos.Transaccion.Intransaccion=True then AccesoDatos.Transaccion.Commit;
  AccesoDatos.BasedeDatos.Connected:=False;
  AccesoDatos.BasedeDatos.Connected:=True;
  {Fin del "seguro"}
   
  LogicaNegocio.CTDPrend_Emp.Insert;
  BtnQuitarPrendaAltaContrato.Enabled:=False;
  BtnInsertarPrendaAltaContrato.Enabled:=False;
  BtnGuardarPrendaAltaContrato.Enabled:=True;
  BtnCancelarPrendaAltaContrato.Enabled:=True;
  NavegaPrendasEmpenadas.Enabled:=False;
  RejillaPrendasEmpenadasAltaCont.Enabled:=False;
  gbPrendaNuevaAltaContrato.Enabled:=True;//GroupBox que almacena Controles DataAware para insertar

EdtUnidadesNuevaPrendaAltaContrato.SetFocus;
   
  end;

Aunque se presiona el boton anterior, en ocasiones no se pueden insertar registros al detalle del contrato, por lo que se debe de presionar el boton Dehacer alta de contrato para que se elimine el registro que se genero en la cabecera, volver a insertar un nuevo registro en la cabecera y ahora si es posible añadir registros en el detalle, espero no haberte confundido mas.

Saludos Al.


La franja horaria es GMT +2. Ahora son las 09:13:18.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi