我都要疯了,三层,客户端clientdataset+dbgrid, 在编辑dbgrid时,修改记录后,老出现:“Trying to modify read-only field”

我都要疯了,三层,客户端clientdataset+dbgrid, 在编辑dbgrid时,修改记录后,老出现:“Trying to modify read-only field” Delphi / Windows SDK/API
http://www.delphi2007.net/DelphiDB/html/delphi_20061222154437161.html
我都要疯了,三层,客户端clientdataset+dbgrid,   在编辑dbgrid时,修改记录后,不能上下移动,老出现:“Trying   to   modify   read-only   field”  
   
  我知道它的意思,可我发现我从中间层取过来的数据有的字段就是只读,   在客户端修改也不行!  
   
  到底是为啥?

别疯了,是不是你数据库里的字段设置为只读?

1。中间层使用视图,在客户端一般是不可以编辑的。  
  2。中间层使用Union语句,在客户端一般也是不可以编辑的。  
  3。中间层使用计算字段(如Price*Count   as   Total),则Total这个字段是不能编辑的。  
  4。其他的情况。

用ADO连接的话,比如:select   *,a=0   from   xxx   象a字段是不能修改的,如果用BDE连接a就可以修改.再看看datasetprovider中是不是设置了只读.

1:检查一下你的数据集控件是否设置了只读(中间层的TDATASET、TDataSetProvider)、及客户端的TClientDataSet控件  
   
  2:检查一下你是否创建了永久性字段,并进行了设置  
   
  3:如果以上两点都正确,请像楼上的几位所提,检查你的数据集来源是否是从单一的数据表,如果不是   或者使用了视图、存储过程等,请将select   ...   from   ...   语句改为:   select   top   100   percent   ....   from   ....   格式   (top   100   percent   在SQL   SERVER中能将你的数据集变为一个可写的数据包)

4:如果试过以上方法还不行的话,可使用下面的这个函数,它会将TClientDataSet中的所有数据字段转为可读写的:  
   
  调用方式为:SetDstAllFieldCanEdit(ClientDataSetName);  
  写在ClientDataSet打开之后即可  
   
  procedure   SetDstAllFieldCanEdit(dstNm:   TClientDataSet;   AddFields:   string='');  
  var   tmpDst:   TClientDataSet;  
          I:   Integer;  
  begin  
      tmpDst   :=   TClientDataSet.Create(nil);  
      Try  
          dstNm.DisableControls;  
          tmpDst.Data   :=   dstNm.Data;  
          dstNm.Close;  
          dstNm.FieldDefs.Clear;  
          for   I   :=   0   to   tmpDst.FieldDefs.Count   -   1   do  
          begin  
              with   dstNm.FieldDefs.AddFieldDef   do  
              begin  
                  DataType   :=   tmpDst.FieldDefs[I].DataType;  
                  Size   :=   tmpDst.FieldDefs[I].Size;  
                  Name   :=   tmpDst.FieldDefs[I].Name;  
              end;  
          end;  
  //         CreateAttachColumns(dstNm,AddFields);  
          dstNm.CreateDataSet;  
          with   tmpDst   do  
          begin  
              First;  
              while   not   Eof   do  
              begin  
                  dstNm.Append;  
                  for   I   :=   0   to   Fields.Count   -   1   do  
                      dstNm.Fields[I].Value   :=   Fields[I].Value;  
                  Next;  
              end;  
          end;  
          if   dstNm.State   in   [dsInsert,dsEdit]   then   dstNm.Post;  
          dstNm.MergeChangeLog;  
      Finally  
          dstNm.EnableControls;  
          tmpDst.Free;  
      End;  
  end;

谢谢大家,结帖!

你可能感兴趣的:(read-only)