Ver Mensaje Individual
  #17  
Antiguo 26-08-2010
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Reputación: 30
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Hola de nuevo Dclase.

Lo primero sería comentarte que hay una mejor manera de crear un TClientDataSet bajo una estructura de campos específica. Para ello puedes hacer uso de su propiedad FieldDefs y de su método CreateDataSet. La ayuda de Delphi viene con un buen ejemplo y seguramente en este foro encontrarás varios ejemplos más.

Allende de lo anterior, me llamó la atención esto que comentaste:

Cita:
Empezado por Dclase Ver Mensaje
...el ClientDataSet2, es un componente TClientDataSet que lo agrego en modo de diseño, lo conecto a un Provider el cual a su vez esta conectado a un TADODataSet (a este ultimo le paso un String con los campos k rekiero de una tabla en especifico), al activar el ClientDataSet, me trae los campos resultantes de la consulta, limpio la propiedad ProviderName, y ya tengo el ClientDataSet2 con los campos k requiero. Bueno y si vienen campos con la propiedad ReadOnly = True, los cambio a False...
Hay que decir que cuando se cambia la propiedad ReadOnly de un campo perteneciente a un TClientDataSet que cargó sus datos mediante un objeto proveedor, tal cambio no tiene efecto sobre el cursor del conjunto de datos. El cursor es un objeto interno que manejan todos los conjuntos de datos cliente y dicho objeto contiene, entre muchos datos, una lista de descriptores de campos.

Estos descriptores son elementos que definen a cada uno de los campos del cursor, como su tipo, tamaño y si son de lectura y escritura o sólo lectura. Cuando el conjunto de datos es abierto, el cursor inicializa sus descriptores de campos con base en la información obtenida de parte del proveedor.

Así pues, si el conjunto de datos que es servido por el proveedor (el TADODataSet en tu caso) viene con un campo cuya propiedad ReadOnly es True, el respectivo descriptor en el interior del cursor cliente quedará marcado con un atributo de sólo lectura (constante fldAttrReadOnly). Algo curioso de este atributo es que solamente tiene efecto en las modificaciones, pero no en las inserciones de registros (por ello has podido agregar filas, pero no cambiarlas).

Viendo tu caso, me dediqué un rato a investigar y hacer pruebas de cómo se podría quitar ese atributo del descriptor, considerando que este es un objeto interno de la propiedad interfaz DSCursor del conjunto de datos.

La clave está en llamar al método SetProp de esa interfaz con una constante que no aparece en Delphi (al menos no hasta la versión 7), pero que al parecer existe en MIDAS desde hace tiempo: curpropFLD_MAKERW; además de proporcionar el número de campo en cuestión.

Creé esta rutina que sirve para quitar el atributo de sólo lectura de un campo, tanto a nivel de la propiedad ReadOnly como a nivel de su respectivo descriptor en el interior del cursor:

Código Delphi [-]
Type
  TClientDataSetAccess = Class (TClientDataSet);
Procedure MakeReadWrite (Const Field :TField);
Begin
  Field.ReadOnly := False;

  With TClientDataSetAccess (Field.DataSet As TClientDataSet) Do
    Check (DSCursor.SetProp (CURProp (4) { curpropFld_MakeRW },
      Field.FieldNo));
End;

// Ejemplo de uso
procedure TForm1.Button1Click(Sender: TObject);
begin
  MakeReadWrite (CDS.FieldByName ('Numero'));
end;

Hice la prueba y funciona, el conjunto de datos cliente permite hacer y guardar modificaciones hechas sobre campos que venían marcados como de sólo lectura.

Lo anterior puede sernos útil en algún momento, pero no está demás recordarle a Dclase mi sugerencia de usar el método CreateDataSet, ya que además de emplear menos memoria de programa, no tendrá que hacer consulta alguna a la base de datos.

Saludos a FGarcia, por quien supe que existía la constante curpropFld_MakeRW.

Un abrazo.

Al González.
Responder Con Cita