在DBGrid中获取当前单元格的值

3
在我的Delphi应用程序中,我使用查找字段,但是以不寻常的方式。实际上,我想更新底层数据集中的字段,就像它在同一张表中一样。
现有指南说没有问题,只需加入表格,就可以了...如果他们真的用这么简单的方法成功完成了这个任务,我会很羡慕。但我并没有。顺便说一下,我认为我已经接近达到我的目标了。我还有一个问题:我怎么才能得到我刚输入到DBGrid单元格中的值?
我尝试了DBGrid[FieldName].EditValue.DisplayText,但它们显示的值与Field.Value相同,在退出列后不会改变,因为它是查找字段。 Sender.NewValue为空。我正在使用此函数来更新查找表:
procedure TKDGridForm.LookupFieldChange(Sender: TField);
begin
  if not Assigned(Sender) then
    Exit;
  Sender.OnChange := nil;
  if not Assigned(Sender.LookupDataSet) then
    Exit;
  if Sender.LookupDataSet.Locate(Sender.LookupKeyFields, Sender.DataSet[Sender.KeyFields], []) then
    Sender.LookupDataSet.Edit
  else
    Sender.LookupDataSet.Append;
  // how do I get the value I just entered?
  Sender.Value := KDGrid3[Sender.FieldName].DisplayText;
  Sender.LookupDataSet.FieldValues[Sender.LookupResultField] := Sender.Value;
  Sender.LookupDataSet.Post;
  Sender.OnChange := LookupFieldChange;
end;

以下是我在使用查找字段之前使用的SQL:

select det.*, 
       od1.T_EQ T_SHABLON_EQ, 
       od1.T_NV T_SHABLON_NV, 
       od1.T_PRIM T_SHABLON_PRIM,
       od2.T_EQ T_PRAVKA_EQ, 
       od2.T_NV T_PRAVKA_NV, 
       od2.T_PRIM T_PRAVKA_PRIM,
       od3.T_EQ T_VALCOV_EQ, 
       od3.T_NV T_VALCOV_NV, 
       od3.T_PRIM T_VALCOV_PRIM,
       od4.T_EQ T_REZKA2_EQ, 
       od4.T_NV T_REZKA2_NV, 
       od4.T_PRIM T_REZKA2_PRIM
from CMKNEW.details det 
left join CMKNEW.OperDetails od1 
       ON det.nrec = od1.cdetail 
      and 81 = od1.coper 
left join CMKNEW.OperDetails od2 
       ON det.nrec = od2.cdetail 
      and 82 = od2.coper 
left join CMKNEW.OperDetails od3 
       ON det.nrec = od3.cdetail 
      and 83 = od3.coper 
left join CMKNEW.OperDetails od4 
       ON det.nrec = od4.cdetail 
      and 84 = od4.coper 
where det.ckd=:CKD order by det.NREC

希望这能更清晰地解释我的任务。如果您需要mcve,我可以扩展此内容,但我认为这并不重要。
我的数据库是Oracle,通过ADO连接。我希望解决方案尽可能简单。
1个回答

2
我猜你正在谈论标准的TDBGrid,你所问的是如何在输入之后,在网格的数据集更新之前获取单元格中显示的文本。此时,左侧列中的当前行指示器将从默认的右指向三角形更改为I型光标。
如果是这样,下面的代码片段将向您展示如何获取此文本值。关键点是,在我描述的情况下,单元格中的内容尚未被提交到底层数据集字段中。发生的情况是,当您开始编辑时,会动态创建一个InplaceEditor(TCustomMaskEdit的后代),它持有正在编辑的文本值。
请添加TTimer和TMemo到您的窗体,然后运行下面的代码以了解我的意思。
type
  TMyGrid = Class(TDBGrid);

procedure TMyForm.Timer1Timer(Sender: TObject);
var
  S : String;
  Grid : TmyGrid;
begin
  Grid := TmyGrid(DBGrid1);
  if Grid.InplaceEditor <> Nil then
    S := Grid.InplaceEditor.Text
  else
    S := IntToStr(Grid.Col) + ':' + IntToStr(Grid.Row);
  Grid.Invalidate;
  Memo1.Lines.Insert(0, S);
end;

实际上它是有效的。而且实际上并不能帮助我解决X问题的部分,因为OnFieldChange事件的调用方式是不可预测的 :( 我接受这个答案,因为这是我所询问的答案。 - Danatela
谢谢。为什么不尝试在新的问题中解释你仍然遇到的问题呢? - MartynA
你为这个答案提名赏金非常友善、慷慨和周到。我很感激。 - MartynA

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接