Delphi : Setting OnGetText Event Handler for fields of a dynamic query
Asked Answered
G

2

8

I want to set my own procedure to OnGetText event of fields in a dynamic query

My procedure is like this :

procedure TMainFrm.MyFieldGetText(Sender: TField; var Text: String;
  DisplayText: Boolean);
begin

  ...

end;
  • "...Captions" are String array constants

I set the event handler in OnAfterOpen event of ADOQuery :

procedure TImportFrm.ADOQueryAfterOpen(DataSet: TDataSet);
var
 I : Integer;
begin
 for I := 0 to ADOQuery.FieldCount - 1 do
  ADOQuery.Fields[I].OnGetText := MainFrm.MyFieldGetText;
end;

But after opening ADOQuery , there is no Text to display , it looks like the Text value is empty !

It seems it doesn't matter what my procedure do , because when I set an empty procedure ( with no code ) , no text displayed too

what goes wrong ?

thanks ...

Gavrila answered 29/7, 2015 at 4:47 Comment(9)
Check your handler with the Debugger (set a breakpoint at the first line)Jammiejammin
thanks , but as I say : "It seems it doesn't matter what my procedure do , because when I set an empty procedure ( with no code ) , no text displayed too"Gavrila
Do you want to check against Sender.FieldName instead of Sender.Name?Trichina
but the problem is not procedure, as I mentioned aboveGavrila
Your concept is essentially correct. But your code is unsafe. Refer to DataSet and Self inside the AfterOpen event handler rather than to a component field and global form variable. Better write for I := 0 to DataSet.FieldCount - 1 do DataSet.Fields[I].OnGetText := MyFieldGetText;.Amytal
Your conclusion is wrong. If you assign a procedure to OnGetText you are responsible for the value. Therefore if you assign an empty procedure nothing is displayed. So the problem might be in the procedure.Arachne
You've not given much to go on. As @Amytal says, the code looks fine (other than the points he raised). Run the debugger, check that i) the event fires at all, ii) what the text variable is set to after calling. Also try stepping through the rest of the source to see what happens to Text.Reenter
@Amytal : thanks , I tried this but the problem not solved. In fact , the procedure is assigned but the problem is after assigning the procedure , DBGrid shows nothing !Gavrila
@Mahmood_M Do you, by any chance, remember what value does Text get after calling the procedure? If you do, you can add an answer hereLovato
S
3

Try this:

procedure TMainFrm.MyFieldGetText(Sender: TField; var Text: String;
  DisplayText: Boolean);
begin
  if Sender.FieldName = 'XX' then
   begin
     Text := .... String(Sender.Value);// ( or Text := Sender.AsString);
   end;
  if Sender.FieldName = 'YY' then
   begin
     Text := .... String(Sender.Value);// ( or Text := Sender.AsString);
   end;
  ...

end;
Schwa answered 29/7, 2015 at 8:39 Comment(2)
Why the branch for FieldName then ? You could directly write Text := Sender.AsString;.Amytal
@Amytal Because OP wrote this before he had editted the question.Schwa
G
1

Thanks all

The problem was that I should mention all situations of Text and should use Sender.value instead of Text in right side ! , I changed my procedure to this and problem solved :

procedure TMainFrm.MyFieldGetText(Sender: TField; var Text: String;
  DisplayText: Boolean);
begin
 if Sender.AsVariant = Null then
  Exit;

 Text := Sender.AsString;

 if MatchStr(Sender.FieldName, BooleanFieldNames) then
  Text := BooleanCaptions[Sender.AsInteger];

 if Sender.FieldName = 'BNStatus' then
  Text := BNStatusCaptions[Sender.AsInteger];

 if MatchStr(Sender.FieldName, ['FStatus', 'LStatus', 'FirstStatus']) then
  Text := FLStatusCaptions[Sender.AsInteger];

 if Sender.FieldName = 'PayType' then
  Text := PayTypeCaptions[Sender.AsInteger];

 if Sender.FieldName = 'BGType' then
  Text := BGTypeCaptions[Sender.AsInteger];

 if Sender.FieldName = 'Updated' then
  Text := UpdatedCaptions[Sender.AsInteger];

 if Sender.FieldName = 'DieUser' then
  Text := DieUserCaptions[Sender.AsInteger];

 if Sender.FieldName = 'LiveUser' then
  Text := LiveUserCaptions[Sender.AsInteger];

 if Sender.FieldName = 'NVStatus' then
  Text := NVStatusCaptions[Sender.AsInteger];

 if Sender.FieldName = 'BSGender' then
  Text := BSGenderCaptions[Sender.AsInteger];

 if Sender.FieldName = 'BSMType' then
  Text := BSMTypeCaptions[Sender.AsInteger];

end;

Thanks again ...

Gavrila answered 29/7, 2015 at 9:2 Comment(4)
did you see my answer?Schwa
You can use Sender.AsInteger instead of StrToInt(Sender.Value) if those fields are of integer type.Amytal
yes , I have changed to this, and added " if Sender.AsVariant = Null then Exit;" for make code safer for empty values.Gavrila
For checking if the field is NULL you can use Sender.IsNull.Amytal

© 2022 - 2024 — McMap. All rights reserved.