我写的博客内容,都是在实际生产中遇到的问题,针对性很强,记录下来有两个目的,一是当成笔记,二是丰富Delphi的网上资料,让遇到相同问题的朋友,少走弯路.
如下图,我希望所属仓库,供应商,物料用途这三个字段,我希望做成下拉菜单的形式给用户选择,
但因为这个表格是多表联合查询得出来的结果,如果直接交给cxgrid自动处理的话,会产生错误
首先,先来实现下拉菜单的效果.我们以物料用途字段为例进行说明.
1.选中 物料用途 字段,在属性面板中设置properties=LookupComboBox,此时properties属性的左边会多出来一个大于号,像这样
2.点开这个大于号,设置ListSource为一个我们事先准备好的数据集.
3.在ListColumns中设置下拉菜单的显示列,可以同时显示多列,同时要设置KeyFieldNames属性,比如你在ListColumns中设置了 用途与单位 这两列,那么对应的,你要在KeyFieldNames中设置为: 用途;单位 ,列与列之间用分号隔开,这里是可以手输的.如果KeyFieldNames与ListColumns不对应,就会出错.
但切记要设置好列宽.下面几个参数要留意一下,它们都在properties属性中设置:
DropDownAutoSize: 使下拉菜单的宽度等于屏幕的宽度.除非你要显示的列非常多,否则不勾选.效果如下
DropDownRows:下拉菜单中最多显示多少行,这里很好理解,就不出图了
DropDownSizeable:使下拉菜单可以通过右下角进行拉伸,改变下拉菜单的大小,同时在左下角提供一个关闭下拉菜单的按钮
说完了下拉菜单设置,现在来说说怎么实现更新.这里先声明,我的方法可能并不是最优解,但能解决实际问题,欢迎大佬指点
这里要用到properties当中的两个事件OnInitPopup事件与OnValidate事件
OnInitPopup事件是在下拉菜单弹出之前,更新它的用途,因为每一行的数据可能不同,用途要通过查询才能返回对应的历史用途.
另外因为我使用的是Access数据库,SQL语句请按自己的对应的数据库语言来写
procedure T申领申购报废清单.T1用途PropertiesInitPopup(Sender: TObject); var codeText: string; begin codeText := DM.FDQ报废池.FieldByName('物料代码').AsString; //取得当前行的物料代码,然后再以此向数据库查询它的历史用途 with DM.FDQ用途 do //下拉菜单关联着这个查询的数据集,所以我们只要更新这个查询就可以了. begin close; SQL.Text := 'select distinct 用途 from(SELECT 用途 FROM 采购入仓记录 WHERE 物料代码=' + codeText.QuotedString + ' ORDER BY 入仓日期 DESC)'; Open(); end; end;
OnValidate事件:当焦点离开当前单元格时,触发此事件.同时会触发cxgrid的更新事件,但因为数据表是联合查询得来的,cxgrid会向一个不存在的表进行更新操作,所以导致出错
procedure T申领申购报废清单.T1用途PropertiesValidate(Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); var YT: string; begin YT := DisplayValue; //当前值,也就是用户点选的值 TV报废池.DataController.Cancel; //取消更新,避免出错. //重新定义更新内容,因为是临时的,所以用了一个公共的查询来执行更新操作 with DM.FD公共查询 do begin close; SQL.Text := 'update 报废池 set 用途=' + YT.QuotedString + ' where RecordID=' + dm.FDQ报废池.FieldByName('RecordID').asstring; ExecSQL; end; dm.FDQ报废池.Refresh; //更新数据集 end;
标签:多表,更新,查询,数据表,报废,用途,设置,下拉菜单 From: https://www.cnblogs.com/yoooos/p/17055169.html