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

解决方案 »

  1.   

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

  2.   

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

  3.   

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

  4.   

    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;