Newsgroup: it.comp.lang.delphi
Titolo: Proprieta' faReadOnly del TFieldDefs

Ho un'AdoQuery che carica nel proprio dataset una vista di dati da un db access.
Dovendo permettere all'utente di effettuare browsing e ricerche di informazioni su
questo dataset, ho inserito un RxMemoryData che tramite il metodo LoadFromDataset(ADOQUERY)
si carica tutti i dati in memoria, rendondo poi possibile ordinarli per colonne 
ed effettuare ricerche per porzioni di chiavi.
Il problema e' che la query contiene un campo definito come espressione:
IIf([ragionesociale] Is Null,[Denominazione],[RagioneSociale]) AS Intestatario
che sortisce l'effetto di generare nel dataset un field di tipo ReadOnly.
Ora, il metodo LoadFromDataset usa una routine che inserisce (Append) uno ad uno
tutti i record dal dataset sorgente (l'ADOQUERY), ma quando si tratta di copiare
il valore della colonna Intestario, esso solleva un'eccezione perche' il field
e' definito readonly
Ho cercato di aggirare il problema con il seguente workaround, ma non ho avuto
successo, il field continua a mantenersi readonly, e non mi spiego il perche'.
var fa : TFieldAttributes;
for I := RxMemoryData1.FieldDefs.Count - 1 downto 0 do begin
   fa := RxMemoryData1.FieldDefs.Items[I].Attributes;   
   fa := fa - [DB.faReadOnly];
   RxMemoryData1.FieldDefs.Items[I].Attributes := fa;   
end;
i := RxMemoryData1.LoadFromDataSet(ADODataSet1,0,lmCopy); //qui da' errore....
Suggerimenti ??
--
Morde. 
morde[at]programmer[.]net

trattandosi di Rx, dovresti avere i sorgenti.
Io farei un trace per vedere nel codice del metodo LoadFromDataset quale è
il blocco o la riga che tenta di fare qualcosa sul campo readonly...
Bye
A.



L'ho fatto, Alberto, la riga e' segnalata sotto:
procedure AssignRecord(Source, Dest: TDataSet; ByName: Boolean);
var  I: Integer;  F, FSrc: TField;
begin
  if not (Dest.State in dsEditModes) then _DBError(SNotEditing);
  if ByName then begin
    for I := 0 to Source.FieldCount - 1 do begin
      F := Dest.FindField(Source.Fields[I].FieldName);
      if F <> nil then begin
{$IFDEF WIN32}
// ***** QUI DA' L'ERRORE (CERCA DI SCRIVERE IN UN TFIELD READONLY)
        F.Value := Source.Fields[I].Value; 
// ***** QUI DA' L'ERRORE
{$ELSE}
        if (F.DataType = Source.Fields[I].DataType) and
          (F.DataSize = Source.Fields[I].DataSize) then
          F.Assign(Source.Fields[I])
        else F.AsString := Source.Fields[I].AsString;
{$ENDIF}
      end;
    end;
  end


Prima di tutto, lasciamo da parte il problema legato al codice e vediamo
cosa ti aspetti TU dal codice.
Per tutti i db credo sia normale che i campi COMPUTED siano readonly:
altrimenti il valore dove andrebbe scritto?
Quindi, dovresti decidere a quale dei 2 campi che potrebbero contenere il
valore vuoi assegnare il nuovo valore.
A tal proposito, il tuo dataset dovrebbe includere uno o entrambi i campi
incriminati e dovresti poi stabilire una regola in base alla quale assegnare
ad uno piuttosto che all'altro.
Riguardo il problema degli RX, visto che oramai è stata assorbita da
sourceforge, potresti modificarti i sorgenti aggiungendo un workaround del
tipo:
if Not F.ReadOnly then
  F.Value := Source.Fields[I].Value
Bye
A

  F.Value := Source.Fields[I].Value
Grazie del consiglio, Alberto, anche se cosi' facendo non raggiungerei
lo scopo che e' quello di copiare il dataset dalla query all'rxmemorydata.
Cmq se non ne riesco a uscire, domani cambio strada.
Ciao!!
