Lazarus, Free Pascal y muchos de sus componentes son sencillamente espectaculares, más aún teniendo en cuenta que es un proyecto de código abierto que comenzó hace muchos años (2001 creo), con pocos programadores para tamaño proyecto, actualmente entre Free Pascal y Lazarus, son unos 20.
El problema, lo dije desde un principio cuando retomé la programación, motivado por la existencia del IDE Lazarus, es la documentación, muchas veces inexistente y otras veces hay que dedicar mucho tiempo para dar con ella.
Los tutoriales para trabajar con bases de datos son pocos, algunos desactualizados y casi siempre los mismo ejemplos.
Es así como aprendí que para conectar y trabajar con una BD se necesitan 3 componentes: el conector (TZConnection), la consulta (TZQuery) y la fuente de datos (TDataSource). Pues no es así. Me di cuenta leyendo y participando del foro, cuando un usuario planteó una duda y detecté que en su código no utilizaba ningún TDataSource, le pregunté y me respondió si era necesario. Me sembró la duda y de hecho la respuesta es: No. Eso es cambia mucho mi panorama, para empezar no necesitaré tantos data modules si solo tengo un para de consultas, puedo declarar las conexiones y consultas sin necesidad de utilizar el data aware y que no molesten en el Form. Ahora entiendo por qué una vez me dijeron que cuando comienzas con esto, usas todo data aware y luego vas directamente por el código, y así es.
El data aware TDataSource solo es necesario cuando necesitamos enlazar los datos con un componente como puede ser un DBGrid, DBComboBox, etc. caso contrario no es necesario.
El ícono es muy claro, el componente envía los datos de un TDataSet hacia otros componentes, es indispensable para un TDBGrid por ejemplo, por eso es que el DataSource se debe vincular con un DataSet (y éste con un conector) y lo que alimenta al DBGrid es el DataSource. Ahora si no necesitamos alimentar ningún control, entonces no es necesario utilizar ningún DataSource.
Mostrando entradas con la etiqueta TDataSet. Mostrar todas las entradas
Mostrando entradas con la etiqueta TDataSet. Mostrar todas las entradas
miércoles, 23 de mayo de 2018
viernes, 24 de noviembre de 2017
Borrar registros de un dataset mediante While
El problema aquí es que pasa con el puntero cuando se elimina un registro y el next. Pues bien, cuando se elimina el registro, pasa al siguiente, por lo tanto hay que evitar el next cuando se borra.
En este caso debo eliminar registros duplicados de lector biométrico, en algunacondicion evaluo si el registro es duplicado y tomo los datos antes de borrarlo, porque a veces los datos están hasta quintuplicados.
Como puede verse, el Next lo realizo solo si no se elimina el registro (fila).
Si el volumen de datos a procesar es grande, conviene utilizar una conexión sin autocommit y utilizar BEGIN y COMMIT tal como se explica aquí.
While not (DMF.ZQReg.EOF ) do
begin
if algunacondicion then
begin
nEmple:=DMF.ZQReg.FieldByName('regemple').AsInteger;
dFechaHora:=DMF.ZQReg.FieldByName('regfechahora').AsDateTime;
DMF.ZQReg.Edit;
DMF.ZQReg.Delete;
Inc(nContador);
end
else
begin
nEmple:=DMF.ZQReg.FieldByName('regemple').AsInteger;
dFechaHora:=DMF.ZQReg.FieldByName('regfechahora').AsDateTime;
DMF.ZQReg.Next;
end;
end;
En este caso debo eliminar registros duplicados de lector biométrico, en algunacondicion evaluo si el registro es duplicado y tomo los datos antes de borrarlo, porque a veces los datos están hasta quintuplicados.
Como puede verse, el Next lo realizo solo si no se elimina el registro (fila).
Si el volumen de datos a procesar es grande, conviene utilizar una conexión sin autocommit y utilizar BEGIN y COMMIT tal como se explica aquí.
domingo, 8 de octubre de 2017
RecNo: obtener el registro actual de un DataSet
Un error muy común es intentar obtener y establecer el puntero de un DataSet desde la propiedad del mismo, ¿por qué? porque no está implementada y siempre retornará -1 o 0 (cero), se necesita acceder a ella a través de una clase descendiente que la implemente, por ejemplo, una query de SQL.
También es importante no confundir RecNo con RowID ni con la clave primaria ni con nada, es un puntero al registro actual y se manifiesta en forma de un número entero, un LongInt para ser más precisos, por ende puede almacenarse este valor en una variable del tipo Integer.
Ejemplo de forma incorrecta de leer la propiedad RecNo:
La forma correcta es:
Por ejemplo:
También es importante no confundir RecNo con RowID ni con la clave primaria ni con nada, es un puntero al registro actual y se manifiesta en forma de un número entero, un LongInt para ser más precisos, por ende puede almacenarse este valor en una variable del tipo Integer.
Ejemplo de forma incorrecta de leer la propiedad RecNo:
ZQuery.DataSource.DataSet.RecNo
La forma correcta es:
ZQuery.RecNo
Por ejemplo:
var
RegistroActual:Integer;
begin
RegistroActual:=ZQuery.RecNo;
ZQuery.Close;
//...Se hace algo....
ZQuery.Open;
ZQuery.RecNo:=RegistroActual;
end;
jueves, 22 de junio de 2017
Locate: función para buscar en un TDataSet
Locate es una función pública de la clase TDataSet para encontrar un registro y posicionar sobre él el puntero, muy práctico para utilizar juntamente con un TDBGrid. Si se encuentra lo buscado retorna true y posiciona el puntero sobre el registro, caso contrario, retorna false y el puntero no se mueve.
Ejemplo:
DMInsu.ZQ.Locate ( 'insumo' , edBuscar.Text, [loCaseInsensitive, loPartialKey] );
Busca en el campo llamado insumo el texto ingresado en el TEdit buscar, ignorando mayúsculas y minúscalas y aceptando encontrar parcialmente, es decir, si el usuario ingresó "az" y existe un registro con el campo insumo con el valor "azúcar", devolverá true.
Para el caso de buscar número enteros, como por ejemplo un ID, funciona correctamente pero no se deben especificar las opciones de búsqueda.
DMInsu.ZQ.Locate ( 'id' , edBuscar.Text, []);
También se pueden realizar búsquedas complejas con varios campos y pasar un vector (array).
loCaseInsensitive y loPartialKey son las únicas opciones.
Más información:
http://wiki.freepascal.org/locate
http://lazarus-ccr.sourceforge.net/docs/fcl/db/tdataset.locate.html
http://lazarus-ccr.sourceforge.net/docs/fcl/db/tlocateoption.html
Ejemplo:
DMInsu.ZQ.Locate ( 'insumo' , edBuscar.Text, [loCaseInsensitive, loPartialKey] );
Busca en el campo llamado insumo el texto ingresado en el TEdit buscar, ignorando mayúsculas y minúscalas y aceptando encontrar parcialmente, es decir, si el usuario ingresó "az" y existe un registro con el campo insumo con el valor "azúcar", devolverá true.
Para el caso de buscar número enteros, como por ejemplo un ID, funciona correctamente pero no se deben especificar las opciones de búsqueda.
DMInsu.ZQ.Locate ( 'id' , edBuscar.Text, []);
También se pueden realizar búsquedas complejas con varios campos y pasar un vector (array).
loCaseInsensitive y loPartialKey son las únicas opciones.
Más información:
http://wiki.freepascal.org/locate
http://lazarus-ccr.sourceforge.net/docs/fcl/db/tdataset.locate.html
http://lazarus-ccr.sourceforge.net/docs/fcl/db/tlocateoption.html
Suscribirse a:
Entradas (Atom)