· Incluye varios métodos y propiedades que ahorran esfuerzo y código en tareas que son habituales.
· Hace más práctico y eficaz el manejo de puntos de restauración (save points).
· Permite aplicar al servidor las modificaciones hechas sin limpiar el registro de cambios, previendo que la actual transacción sea revertida al fallar la aplicación de actualizaciones en otro conjunto de datos.
· Su método Locate puede buscar un solo valor sobre varios campos.
· La aplicación de cambios al servidor puede ser inmediata (tras llamar a Post o Delete) e incluyendo registros detalles.
· A diferencia del ClientDataSet nativo, puede asociarse en tiempo de diseño a un componente proveedor que se encuentre en otro módulo de datos del proyecto.
· Evita abrir el conjunto de datos innecesariamente al cargar el módulo de datos en tiempo de diseño.
Propiedades:
AutoCancelDetails :Boolean
Esta propiedad afecta la manera en que son tratados los registros detalles de la actual fila del conjunto de datos. Cuando su valor es True (el predeterminado) y se llama a los métodos Cancel o Delete, lo primero que ocurre es una llamada al método CancelDetails. Con ello se le da más congruencia a la operación, ya que el comportamiento nativo heredado de TDataSet es intentar guardar cualquier cambio que esté pendiente de ello en los conjuntos de datos detalles (lo cual resulta poco lógico si la operación deseada es cancelar o eliminar el registro maestro). Por otra parte, cuando esta propiedad es True y el método CancelUpdates es ejecutado, primeramente el componente llama al método CancelUpdates de todos los conjuntos de datos detalles.
DetailedApplying :Boolean
Cuando es establecida en True provoca que los métodos ApplyUpdates y ApplyChangeLog apliquen no sólo el registro de cambios del conjunto de datos, sino también los cambios pendientes de aplicar de sus conjuntos de datos detalles. Esto hace que sea muy práctico que, con una sola instrucción de programa, se apliquen todos los cambios que haya pendientes en un grupo de conjuntos de datos relacionados entre sí. El uso de DetailedApplying junto con los nuevos métodos ApplyUpdates sirven de buena alternativa al empleo de conjuntos de datos anidados, cuando del lado del proveedor las consultas SQL involucradas no son propiamente maestro-detalle. Su valor predeterminado es False.
En ciertas operaciones de búsqueda y filtraje suelen emplearse conjuntos de datos parametrizados, presentándose con frecuencia la necesidad de conocer qué parámetros están relacionados con un campo en particular. Esta propiedad ayuda a establecer relaciones entre campos y parámetros del conjunto de datos, asignándole un valor como Campo1=Parametro1;Campo2=Parametro2. Un uso típico de esta propiedad es indicarle a un conjunto de datos detalle cuál es el nombre del parámetro por el cual debe filtrarse para corresponder al registro maestro, en casos donde dicho parámetro lleve un nombre diferente al indicado por IndexFieldNames o IndexName (diferencia de nombres que no admite el componente ClientDataSet nativo).
Cuando la propiedad Identify tiene un valor de True e ID no es una cadena vacía, el valor de esta última se usa como identificador del conjunto de datos en cada llamada que éste hace al componente proveedor (el cual debe tener su propiedad ClientActivity en True). NOTA: Cuando utilice esta propiedad debe asegurarse de darle un valor que sea único entre todos los conjuntos de datos que se conecten al mismo proveedor, incluyendo aquellos que pertenezcan a otras instancias de la aplicación u otros programas clientes. Debido a esto, es preferible dejar que el componente determine por sí mismo el identificador a utilizar dejando la propiedad en blanco.
Cuando esta propiedad tiene un valor de True, cada llamada que el conjunto de datos hace a su respectivo proveedor lleva incluido un parámetro adicional, en el variante OwnerData que siempre es enviado como argumento. Dicho parámetro es una cadena de caracteres que sirve para identificar al conjunto de datos ante el proveedor, y es el valor de la propiedad ID cuando ésta no se encuentra vacía. Si ID es una cadena vacía, el identificador es automáticamente generado por el componente con ayuda de la función CreateGUID. NOTA: Esta característica de identificación requiere que el proveedor del conjunto de datos sea de clase TMagiaDataSetProvider o descendiente, y que la propiedad ClientActivity de éste tenga un valor de True antes de realizar cualquier llamada al proveedor (TMagiaClientDataSet.Identify y TMagiaDataSetProvider.ClientActivity son mutuamente complementarias). Su valor predeterminado es False.
ImmediateApplying :Boolean
El valor predeterminado de esta propiedad es False, pero, cuando es puesta en True, cada llamada a los métodos Post y Delete va acompañada de un ApplyUpdates automático. Es decir, cada registro guardado es inmediatamente enviado al servidor y cada registro eliminado es borrado inmediatamente de la base de datos. En otras palabras, esta propiedad permite que el componente se comporte como si fuese un conjunto de datos ligado directamente a una tabla de la base de datos, reflejando en ésta cualquier cambio ocurrido en las filas de memoria en cuanto esos cambios suceden. Esto evita el típico uso de los eventos AfterPost y AfterDelete para llamar explícitamente al método ApplyUpdates (comúnmente con interfaces de captura de pagos, documentos, etcétera). Pero otra gran ventaja de la propiedad ImmediateApplying es que conserva el estado del registro (sea dsInsert, dsEdit o dsBrowse) y el conjunto de datos en general, cuando la operación de guardado o eliminación falla por alguna validación del servidor.
Esta es una propiedad de solo lectura que devuelve el conjunto de datos maestro del componente, en caso de tener asignado un objeto fuente de datos en su propiedad MasterSource. Es decir, Master envuelve a la propiedad MasterSource.DataSet. Devuelve Nil si el conjunto de datos no tiene asignada una fuente de datos maestra.
Parent :TMagiaClientDataSet
Esta es una propiedad de solo lectura que devuelve el conjunto de datos padre del componente, en caso de ser un conjunto de datos anidado dentro de otro. Es decir, Parent envuelve a la propiedad DataSetField.DataSet. Devuelve Nil si no tiene valor asignado en su propiedad DataSetField.
PersistentState :TDataSetState
Esta propiedad de solo lectura devuelve el estado persistente del conjunto de datos. Es decir, el mismo que arroja la propiedad State, pero sin contar estados temporales (como dsOldValue, dsInternalCalc y dsOpening), a los que ocasionalmente entra un conjunto de datos durante ciertas operaciones.
Propiedad auxiliar de solo lectura que indica si el conjunto de datos se encuentra ejecutando el método Post. Un valor de True significa que se ha llamado al método Post del conjunto de datos (o de alguno de sus conjuntos de datos padre, en caso de ser anidado). False indica que no se está ejecutando el método Post. Posting adquiere un valor de False cuando el método Post termina de ejecutarse.
PrevPersistentState :TDataSetState
Propiedad de sólo lectura que devuelve el último valor anterior que tuvo PersistentState. Cada vez que cambia la propiedad PersistentState, PrevPersistentState adquiere el valor que la primera tenía.
Provider :TCustomProvider
Alternativa a la propiedad ProviderName. Su función principal es permitir asociar en tiempo de diseño el conjunto de datos con un componente proveedor localizado en otro módulo de datos del proyecto, a diferencia de la nativa ProviderName, que sólo acepta el nombre de un proveedor cuyo contenedor sea el mismo que el del componente o un módulo de datos remoto del servidor de aplicaciones.
RootParent :TMagiaClientDataSet
Si el componente es un conjunto de datos anidado, RootParent devuelve el conjunto de datos raíz de todo el árbol de componentes anidados. De lo contrario su valor es Nil.
SavePoints :TMagiaClientDataSetSavePoints
Es un objeto especial dentro del componente, cuya función es permitir marcar, confirmar y revertir puntos de restauración. Tiene mayores alcances que la propiedad nativa SavePoint, aunque internamente hace uso de los mismos mecanismos que ésta. Emplea el sistema Correlated Save Points (CSP) de Sistemas GH, el cual permite relacionar entre sí a puntos de restauración de diferentes índoles.
Propiedad para indicar si la propiedad Active debe ser guardada o no en el archivo DFM. Con esto se consigue evitar que el conjunto de datos intente abrirse cada vez que se carga el módulo de datos en el IDE, o al correr la aplicación y crearse el módulo de datos sin estar todo listo para abrir el cursor. En el entorno de Delphi, es común establecer la propiedad Active en True por motivos de diseño, pero es bastante frecuente que el programador quiera que esa propiedad esté en False las siguiente vez que abra el proyecto o ejecute el programa. Su valor predeterminado es False.
Métodos:
Function ApplyChangeLog (MaxErrors :Integer = 0;
ConfirmSuccess :TghTernary = ghterDefault) :Integer;
ApplyChangeLog es un sustituto opcional del tradicional método ApplyUpdates (ver descripción de éste en la ayuda de Delphi). Tiene dos ventajas importantes. No intenta guardar el registro que actualmente esté en edición, sólo aplica a la base de datos los cambios que ya han sido guardados en memoria. Esto es útil en situaciones especiales cuando, por alguna condición del programa, deben enviarse a la base de datos los cambios realizados en otros registros diferentes al que el usuario está capturando en ese momento, pero sin perder el estado actual (dsInsert / dsEdit) de éste último. La segunda y mayor ventaja es que puede recibir un parámetro adicional, ConfirmSuccess, el cuál le indica al componente qué debe hacer después de aplicar los cambios cuando ninguno de ellos causó error. Si ConfirmSuccess es igual a la constante ghterTrue, el método MergeChangeLog es llamado para dejar en blanco el registro de cambios (como lo hace de forma nativa el método TClientDataSet.ApplyUpdates). Si ConfirmSuccess es ghterFalse, el registro de cambios se queda intacto aún después de aplicarse todos los cambios. Esto permite que pueda revertirse (rollback) la transacción activa del servidor y seguidamente pueda llamarse todavía al método CancelUpdates del conjunto de datos para regresarlo al estado donde se encontraba antes de las modificaciones hechas durante esa transacción. La alternativa acostumbrada con un componente ClientDataSet nativo es una costosa llamada al método Refresh (una nueva consulta de datos al servidor que con MagiaClientDataSet ya no es necesaria). Si se omite este parámetro o se proporciona en su lugar un valor de ghterDefault, después de aplicar las actualizaciones del conjunto de datos exitosamente se limpiará el registro de cambios, sólo si el componente no tiene marcado un punto de restauración CSP posterior a otro punto de restauración CSP pendiente de ser confirmado dentro del mismo hilo del programa. Es decir, cuando la aplicación de cambios es exitosa y el parámetro ConfirmSuccess es ghterDefault, ApplyChangeLog no llamará a MergeChangeLog si el conjunto de datos tiene un punto de restauración correlacionado con otro punto de restauración maestro (cuando el punto de restauración maestro se confirme o se revierta, el conjunto de datos hará lo propio con el registro de cambios). Al igual que el método ApplyUpdates nativo, devuelve la cantidad de errores que se presentaron al ejecutar la operación, pero incluyendo también los ocurridos en conjuntos de datos detalles, cuando la propiedad DetailedApplying es True.
Segunda versión del método ApplyChangeLog, para omitir el parámetro MaxErrors pero no el parámetro ConfirmSuccess.
Este método tiene la misma utilidad que ApplyChangeLog, al cual llama internamente, pero después de ejecutar el método CheckBrowseMode para guardar cualquier cambio que estuviera pendiente en el registro actual.
Esta versión del método ApplyUpdates envuelve a la anterior, dándole el parámetro MaxErrors y la constante ghterDefault como segundo argumento.
Esta versión del método ApplyUpdates envuelve a la primera, dándole como argumentos las constantes 0 y ghterDefault.
CancelDetails llama al método Cancel de todos los conjuntos de datos detalles del componente, así como de todos los detalles de sus conjuntos de datos anidados, cubriendo recursivamente toda la rama del árbol de componentes maestro-detalle / padre-anidado, a partir de los conjuntos de datos detalles del nodo que representa el componente y los conjuntos de datos detalles de sus componentes anidados (sin llamar al método Cancel de ningún conjunto de datos anidado).
Llama al método CancelUpdates nativo pero realizando validaciones y establecimientos adicionales. Entre otras cosas, si la propiedad AutoCancelDetails es True, llama al método CancelUpdates de todos los conjuntos de datos detalles (directos e indirectos) del componente. También se encarga de eliminar todos los puntos de restauración que el conjunto de datos haya marcado con su propiedad SavePoints, disparándose el método Restore de cualquier punto de restauración CSP detalle marcado en otro lugar del programa dentro del mismo hilo.
Suma la propiedad ChangeCount de todos los conjuntos de datos detalles del componente, así como de todos los conjuntos de datos detalles de sus conjuntos de datos anidados (detalles directos e indirectos). Devuelve el resultado de dicha suma, que, en concreto, es la cantidad de filas detalles agregadas, eliminadas o modificadas que están pendientes de ser aplicadas al servidor.
Function DetailClone (Const MasterSource :TComponent;
Const MasterFields :String; Const IndexFieldNames :String = '';
Const FieldParamName :String = '') :TMagiaClientDataSet;
Este método crea un clon del componente y lo prepara para ser detalle de otro conjunto de datos. El parámetro MasterSource debe ser la fuente e datos o el conjunto de datos maestro al que estará subordinado. Los parámetros MasterFields, IndexFieldNames y FieldParamNames son los valores que serán asignados en el clon a las propiedades que llevan esos mismos nombres. Si se omite el parámetro IndexFieldNames la propiedad IndexFieldNames del clon tendrá el mismo valor que MasterFields. DetailClone devuelve el nuevo objeto creado y preparado.
Function EnumFields (Const Cls :TFieldClass; Const Routine :TghEnumProc;
Const Params :Variant) :TField;