Ir al contenido


Foto

[RESUELTO] Autoincrementable para mostrar, por favor...


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

#1 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 06 octubre 2010 - 03:41

Buena tarde, jóvenes (y otros no tanto) compañerit@s del Foro...

Resulta que tengo una tabla con un campo autoincrementable que funge como número de folio, y que por necesidades del usuario, debo mostrar en un DbEdit para que lo tome en cuenta en una relación que llena manualmente al capturar datos, para control interno.

Ahora bien, resulta que no me muestra el contenido del campo aún habiéndole otorgado el modo "Insert" al TClientDataSet que controla la conexión entre los datos y los controles DbAware. Y no sólo éso, me marca un error al darle Tab o Enter anunciando que éste campo no puede ser editado ni modificado.

¿Alguna idea que me permita solucionar éste problema? Trabajo con MS SQL Server 2005 y Delphi 7
  • 0

#2 Caral

Caral

    Advanced Member

  • Moderador
  • PipPipPip
  • 4.266 mensajes
  • LocationCosta Rica

Escrito 06 octubre 2010 - 03:46

Hola
Al ser autonumerico no se podra modificar de ahí podría ser el error, lo curioso es que no lo muestre.
Y si le haces trampa?.
Pasa el dato a un edit normal o label a ver si lo muestra.
Saludos
  • 0

#3 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 06 octubre 2010 - 03:58

Con que te estás conectando?

  • 0

#4 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 06 octubre 2010 - 04:19

Hola
Al ser autonumerico no se podra modificar de ahí podría ser el error, lo curioso es que no lo muestre.
Y si le haces trampa?.
Pasa el dato a un edit normal o label a ver si lo muestra.
Saludos


Buena idea, la probaré.

Con que te estás conectando?

A través de un TADOConnection, un TADOQuery conectado a un TClientDataSet y de ahí a un TDataSet para los controles DbAware.
  • 0

#5 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 06 octubre 2010 - 04:28

...Y si le haces trampa?.
Pasa el dato a un edit normal o label a ver si lo muestra...


Solamente para redondear, ¿sabes dónde puedo obtener el "nuevo" número de folio que estoy añadiendo? Es que sabrás que estoy casi al punto del bloqueo de ideas.
  • 0

#6 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.446 mensajes
  • LocationMéxico

Escrito 06 octubre 2010 - 04:34


...Y si le haces trampa?.
Pasa el dato a un edit normal o label a ver si lo muestra...


Solamente para redondear, ¿sabes dónde puedo obtener el "nuevo" número de folio que estoy añadiendo? Es que sabrás que estoy casi al punto del bloqueo de ideas.


Hola



sql
  1. SELECT MAX(CampoIncr) FROM TuTabla



Salud OS
  • 0

#7 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 06 octubre 2010 - 04:37

Una forma que depronto te funciona, si usas campos persistentes,  colocar false a la propiedad Required del campo que hace de clave principal, tanto en el dataset que ataca la BD como en el  ClientDataset,  coloca en true la propiedad Options.poPropogateChanges del TDatasetProvider. Y la única forma de obtener ese valor es llamando el método RefreshRecord del TClientDataset, obviamente despues de aplicar los cambios. Al llamar el método Insert del TClientDataset es obvio que no te va a mostrar el siguiente valor puesto que esta operación se realiza en memoria a nivel local.

Con esta consulta obtienes el valor del último valor insertado autonumericamente en sql server.



sql
  1. SELECT @@IDENTITY AS ULTIMO_NUMERO


  • 0

#8 Caral

Caral

    Advanced Member

  • Moderador
  • PipPipPip
  • 4.266 mensajes
  • LocationCosta Rica

Escrito 06 octubre 2010 - 05:23

Hola
Esta bien hacer una consulta adicional pero por que no hacerla en la misma ya que estas usando un AdoQuery?.
Saludos
  • 0

#9 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 06 octubre 2010 - 09:06

Si la aplicación es monopuesto la mejor alternativa es la que te da Egostar, pero si se ataca la db desde varios puestos hay que lidiar un poco con eso.

A continuación te voy a describir algo que me funcionaba sin problemas en Sql Server 2000.  Depronto te sirve.

Vamos a suponer que la clave principal de tu tabla en cuestión se llama Id_Folio y está definido así:



sql
  1. CREATE TABLE FOLIOS(
  2. Id_Folio    INTEGER  NOT NULL  IDENTITY /*autoincremental*/
  3. /*El resto de campos*/
  4. PRIMARY KEY    (Id_Folio)
  5. )



Y vamos a suponer que tienes un TADOQUERY cuyo SQL es:


sql
  1. SELECT * FROM FOLIOS



Entonces vamos a crear los campos persistentes en TADOQUERY (DobleClick sobre el TADOQUERY para que aparezca el editor de campos, luego cilck derecho sobre este y Add All Fields. Ahora deben aparecer en el editor de campos todos los "campos" de la consulta, vamos a hacer clic derecho sobre el campo ID_Folio y  y escogemos la opción Delete para borrarlo; lo borramos porque el tipo de este campo es TAutoIncField y es por este motivo que no nos deja editar ni hacer nada con el. Posteriormente en el editor de campos hacemos clik derecho y le damos  New Field en el cuadro de diálogo que aparece le colocamos en name: Id_Folio en Type:Integer y en FieldType : Data; con esta acción ya nuestro campo es perfectamente editable. Ahora nos aseguramos que solo queden en True de la propiedad  ProviderFlags [pfInKey, pfInWhere] las otras dos deben quedar en false.

Ahora vamos a arrastrar otro TADOQUERY que llamaremos qClaveFolio en su sql ponemos


sql
  1. SELECT @@IDENTITY AS ULTIMO_NUMERO



La anterior consulta nos servirá para la siguiente función:



delphi
  1. function Id : Integer;
  2. begin
  3. qClaveFolio.Open;
  4. Result:= qClaveFolio.FieldByName('ULTIMO_NUMERO').AsInteger;
  5. qClaveFolio.Close;



Ahora dijiste que estás utilizando un TClientDataset por lo tanto debes utilizar un TDatasetProvider, como te lo había dicho en un post anterior hay que colocar las opciones poPropogateChanges y PoIncFieldProps a True con el objeto de que los cambios realizados en la definición de campos y en la grabación se propaguen hasta el TClientDataset.

Para completar la tárea vamos a interceptar el evento AfterUpdateRecords del TDatasetProvider que vamos a suponer que se llama prFolios


delphi
  1. procedure TDataModule.PrFoliosAfterUpdateRecord(
  2. Sender: TObject; SourceDS: TDataSet;
  3. DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind);
  4. begin
  5. if UpdateKind = ukInsert then
  6. DeltaDS.FieldByName('ID_Folio').NewValue := Id;
  7. end;



Ahora solo basta inicializar el campo id_Folio en el TClientDataset, para esto capturamos el evento OnnewRecord de este mas o menos asi:



delphi
  1. procedure TDataModule.ClientDataSet1NewRecord(DataSet: TDataSet);
  2. begin
  3. Dataset.FieldByName('id_folio).Value := -1;
  4. end;



El valor -1 es solo para cumplir la propiedad required del campo, este valor será ignorado a la hora de grabar.
Esto funciona muy bien si grabamos un unico registro por vez.

La idea de todo esto es traer de vuelta al ClienteDataset el valor asignado por la Db a la clave principal.

Espero te sirva.

PD: Si optas por este camino, es bueno borrar el Tadoquery y el ClientDataset y crearlos de nuevo para evitar problemas.
  • 0

#10 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 07 octubre 2010 - 08:50

...Espero te sirva.

PD: Si optas por este camino, es bueno borrar el Tadoquery y el ClientDataset y crearlos de nuevo para evitar problemas.


¡¡Wow!!, más claro, imposible. Gracias, Wilson.
  • 0

#11 razadi

razadi

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 681 mensajes
  • LocationMéxico D.F.

Escrito 07 octubre 2010 - 09:54

Excelente eplicación Wilson, ya tiene mucho que no trabajo con SQL Server, espero poder hacer algo, e incluiré estas observaciones.

Saludos
  • 0

#12 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 07 octubre 2010 - 10:29

...Ahora vamos a arrastrar otro TADOQUERY que llamaremos qClaveFolio en su sql ponemos


sql
  1. SELECT @@IDENTITY AS ULTIMO_NUMERO


...


Ésta sentencia me está devolviendo nulo, Wilson..., ¿no le faltará algo más?
  • 0

#13 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 07 octubre 2010 - 11:31

Resuelto gracias a los buenos oficios de los compañeritos de DelphiAccess...
  • 0

#14 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 07 octubre 2010 - 11:35

Aunque ya lo resolviste es importante  tener en cuenta lo siguiente para que el ejemplo funcione:
Primero que todo revisa que el campo esté definido asi:


sql
  1. Id_Folio    INTEGER  NOT NULL  IDENTITY



Segundo :  Recuerda que ese valor solo es devuelto después de una inserción exitosa..

Si tienes acceso a la db y la puedes modificar, entonces es mejor crear un procedimiento almacenado asi:



sql
  1. CREATE PROCEDURE Obtener_Identidad
  2. WITH encryption AS
  3. BEGIN
  4. RETURN @@IDENTITY
  5. END



Y entonces en vez del TadoQuery qClaveFolio arrastramos un TADOStrodeProc que llamaremos spClaveFolio y lo configuramos con el procedimiento que creamos (Obtener_Identidad, nos aseguaramos de que la propiedad executedOptions tenga en true [eoExecuteNoRecords], ahora hay cambiar la función ID así:



delphi
  1. function ID: Integer;
  2. begin
  3. spClaveFolio.Execute;
  4. Result := spClaveFolio.Parameters[0].Value;
  5. end;


Lo demás puede quedar igual a la explicación del post anterior, aunque esto yo lo hacía sin problemas  con SQLServer 2000 creo que no tengas problema con la versión que está trabajando.

Saludos
  • 0




IP.Board spam blocked by CleanTalk.