
[RESUELTO] Autoincrementable para mostrar, por favor...
#1
Escrito 06 octubre 2010 - 03:41
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
#2
Escrito 06 octubre 2010 - 03:46
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
#3
Escrito 06 octubre 2010 - 03:58
#4
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é.
A través de un TADOConnection, un TADOQuery conectado a un TClientDataSet y de ahí a un TDataSet para los controles DbAware.Con que te estás conectando?
#5
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.
#6
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
SELECT MAX(CampoIncr) FROM TuTabla
Salud OS
#7
Escrito 06 octubre 2010 - 04:37
Con esta consulta obtienes el valor del último valor insertado autonumericamente en sql server.
SELECT @@IDENTITY AS ULTIMO_NUMERO
#8
Escrito 06 octubre 2010 - 05:23
Esta bien hacer una consulta adicional pero por que no hacerla en la misma ya que estas usando un AdoQuery?.
Saludos
#9
Escrito 06 octubre 2010 - 09:06
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í:
CREATE TABLE FOLIOS( Id_Folio INTEGER NOT NULL IDENTITY /*autoincremental*/ /*El resto de campos*/ PRIMARY KEY (Id_Folio) )
Y vamos a suponer que tienes un TADOQUERY cuyo SQL es:
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
SELECT @@IDENTITY AS ULTIMO_NUMERO
La anterior consulta nos servirá para la siguiente función:
function Id : Integer; begin qClaveFolio.Open; Result:= qClaveFolio.FieldByName('ULTIMO_NUMERO').AsInteger; 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
procedure TDataModule.PrFoliosAfterUpdateRecord( Sender: TObject; SourceDS: TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind); begin if UpdateKind = ukInsert then DeltaDS.FieldByName('ID_Folio').NewValue := Id; end;
Ahora solo basta inicializar el campo id_Folio en el TClientDataset, para esto capturamos el evento OnnewRecord de este mas o menos asi:
procedure TDataModule.ClientDataSet1NewRecord(DataSet: TDataSet); begin Dataset.FieldByName('id_folio).Value := -1; 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.
#10
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.
#11
Escrito 07 octubre 2010 - 09:54
Saludos
#12
Escrito 07 octubre 2010 - 10:29
...Ahora vamos a arrastrar otro TADOQUERY que llamaremos qClaveFolio en su sql ponemos
sql
SELECT @@IDENTITY AS ULTIMO_NUMERO
...
Ésta sentencia me está devolviendo nulo, Wilson..., ¿no le faltará algo más?
#13
Escrito 07 octubre 2010 - 11:31
#14
Escrito 07 octubre 2010 - 11:35
Primero que todo revisa que el campo esté definido asi:
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:
CREATE PROCEDURE Obtener_Identidad WITH encryption AS BEGIN RETURN @@IDENTITY 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í:
function ID: Integer; begin spClaveFolio.Execute; Result := spClaveFolio.Parameters[0].Value; 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