delphi cxGrid做一个可以控制单元格数量上限和下限的功能

先看效果图

效果要求:

  1.点击申领数量时,自动设置此物料可领上限,与可退的下限

  2.申领数量为0时,不更新

说明:  

  1.使用了cxGrid+FireDAC

  2.TFDQuery控件不要开快储功能(CachedUpdates不要勾选)

 

3.因为表格数据为多表联合查询的数据,所以这里要设置一下更新指向.否则会报错.

设置TFDQuery控件-UpdateOptions-UpdateTableName为字段[申领数量]所在的数据表.这样更新就不会因为这个查询里有多个表,让程序不知道向哪里提交数据而报错了.

 

 这个属性,是可以用代码修改的,比如这个查询里用到了多个表的数据,当你修改的是A表的字段时,你就用代码设置这个属性指向A,B的就让它指向B

 

以下是制作过程:

  1.设置[申领数量]字段的Properties属性为SpinEdit,勾上MaxValue,MinValue

 

  2.设计表格的OnEdit事件,如果有多个字段是可编辑的,你还要额外做一下字段的判断.我这里因为只有申领数量这个字段是可编辑的,所以没有做判断.

procedure T申领申购报废清单.TV申领清单Editing(Sender: TcxCustomGridTableView; AItem:
  TcxCustomGridTableItem; var AAllow: Boolean);
var
  isql, Scode: string;
  Max, Min: Single;
begin
  Scode := DM.FDQ申领.FieldByName('物料代码').AsString;    //取得当前行的物料代码,以便查询它的参考库存与线上仓的数量
  isql := 'select 参考库存 FROM 物料信息 Where 物料代码=' + Scode.QuotedString;
  max := DM.PublicQuery(isql, '参考库存')[0];    //这个函数下面会讲
  TcxSpinEditProperties(T2申领数量.Properties).MaxValue := Max;  //设置上限值

  isql := 'SELECT Sum(申领数量) AS 在线数量  '
    + 'FROM 申领记录  '
    + 'HAVING 物料代码=' + Scode.QuotedString;
  Min := DM.PublicQuery(isql, '在线数量')[0] * -1;    //这个函数下面会讲.这里*-1是表示可以退仓的数量
  TcxSpinEditProperties(T2申领数量.Properties).MinValue := Min;   //设置下限值
end;
uses System.Varaints
type
  TVarArray = array of Variant; //动态数组
function PublicQuery(iSQL, backFieldName: string): TVarArray; overload;  //函数声明

//公共查询, 返回字段backFieldName的值
function TDM.PublicQuery(iSQL, backFieldName: string): TVarArray;
var
  i: Integer;
  arr: TVarArray;
  v: Variant;
begin
  with Self.FD公共查询 do  //这是个临时演员,另外一个共用的TFDQuery控件
  begin
    Close;
    SQL.Text := iSQL;
    Open();

    for i := 0 to RecordCount - 1 do    //这个RecordCount 有个坑,后面会讲
    begin
      SetLength(arr, i + 1);
      v := FieldByName(backFieldName).AsVariant;
      if (VarToStr(v) = '') or (VarToStr(v) = 'null') then
        v := 0;    //默认值为0
      arr[i] := v;
    end;
    Result := arr;
  end;
end;

3.设置TFDQery控件的提交前事件BeforPost,用于检查数据的合法性

//申领数量为0时,取消提交,你也可以加点提示什么的
procedure TDM.FDQ申领BeforePost(DataSet: TDataSet);
begin
  if DataSet.FieldByName('申领数量').AsSingle = 0 then
    FDQ申领.Cancel;
end;

至此,制作完成.

现在来说一下TFDQery.RecordCount的坑

这个属性就算它查询不到数据,它也会返回一个null,所以它的长度是1,而不是0,希望大家使用时要注意.

 

posted @ 2023-02-12 17:08  一曲轻扬  阅读(246)  评论(0编辑  收藏  举报