2

I need during debugging my Delphi app to get many database fields foreign keys value to use them while debugging a stored procedure behavior. the fields are so many and so I wonder if there is a quicker way to get these values like populating all of them into watches window instead of writing an expression for every single field I need to watch.

In other words I need to watch all fields values for several tables. I wont need all of them but I can easily pick what I need from a list like this.

currently I am writing watches expression like this:

<data module>.<Table Component>.fieldbyname('Field_Name').asinteger
4

3 回答 3

6

并不真地。没有办法循环设置手表,或者没有任何代码设置一次在多个数据库字段上设置手表。

在 Delphi 2010 及更高版本中,您可以编写自己的调试器可视化工具(请参阅 参考资料部分External-Viewer Visualizers)为您提供自定义视图,但这将是一项相当广泛的任务。(文件夹中提供了一个示例$(BDS)\Source\Visualizers;外部查看器是StringListViewer.)

您可以创建持久字段以简化将它们添加到观察窗口(双击表格组件并选择Add Field...Add All Fields),然后您可以将它们引用为datamodule.tablefield.AsInteger.

或者,您可以将字段分配给单独的局部变量,然后只观察它们):

var
  AField: TField;
  AnotherField: TField;
begin
  AField := dm.TableA.FieldByName('FieldA');
  AnotherField := dm.TableA.FieldByName('FieldB');
  ...
end;

然后打开AField.AsInteger手表,这会加快手表的设置速度。

(对于非调试目的,声明局部TField变量并在循环之前设置它们可以通过删除字段的常量查找来大大加快代码速度FieldByName。)

另一种可能性是声明并使用您在循环中分配的局部变量,然后您可以观察该局部变量:

var
  FieldAValue: Integer;
  FieldA: TField;
begin
  FieldA := dm.TableA.FieldByName('FieldA');
  while not dm.TableA.Eof do
  begin
    FieldAValue := FieldA.AsInteger;
    // Use FieldAValue here instead of the Field.AsInteger, so the
    // compiler doesn't eliminate it. You can add a watch by right-clicking
    // FieldAValue and choosing Debug->Add watch at cursor or Ctrl+F5.
    TableA.Next;
  end;
end;
于 2013-07-05T00:19:17.207 回答
2

为此,我将字段转储到跟踪日志中,如下所示:

function IfThen(AValue: Boolean; const ATrue, AFalse: string): string; overload;
begin
  if AValue then
    Result := ATrue
  else
    Result := AFalse;
end;

procedure LogDebugFields(ADat: TDataset; ADirection: string = '');
var
  OwnerName: string;
  Idx: integer;
  Field: TField;
begin
  if not Assigned(ADat) or not (ADat is TDataset) then
    exit;
  if Assigned(ADat.Owner) then
    OwnerName := ADat.Owner.Name + '_'
  else
    OwnerName := '';
  LogDebugStringFmt('Dump of dataset in the state "%s" with "%d" fields',
      [DatasetStateToStr(ADat.State), ADat.Fields.Count],
    OwnerName + ADat.Name, ADirection);
  for Idx := 0 to ADat.Fields.Count - 1 do
  begin
    Field := ADat.Fields[Idx];
    LogDebugContinued(Format('[%2.2d] %-48.48s = %s',
        [Idx, Format('%s (%s%s)', [Field.FieldName, Field.ClassName,
          IfThen(Field.Required, ', NOT NULL)', '')]), Field.AsString]));
  end;
end;
于 2013-07-05T05:23:53.247 回答
0

您可以通过退出 IDE 并编辑[Watches].DSK 文件中的部分来快速将监视添加到您的项目中。

这是一个示例,我想复制和修改一组 8 个手表(Watch4..Watch11):

[Watches]
Count=12
Watch0='AEvent.getcustomfieldvaluebyname(splantaskfromdate)',256,0,18,1,1,'Watches',1
Watch1='AEvent.getcustomfieldvaluebyname(splantasktodate)',256,0,18,1,1,'Watches',1
Watch2='aevent.start',256,0,18,1,1,'Watches',1
Watch3='aevent.finish',256,0,18,1,1,'Watches',1
Watch4='FDMPPlan.FEvent1833.start',256,0,18,1,1,'Watches',1
Watch5='FDMPPlan.FEvent1833.finish',256,0,18,1,1,'Watches',1
Watch6='FDMPPlan.FEvent1833.getcustomfieldvaluebyname(''tt_fromdate'')',256,0,18,1,1,'Watches',1
Watch7='FDMPPlan.FEvent1833.getcustomfieldvaluebyname(''tt_todate'')',256,0,18,1,1,'Watches',1
Watch8='FEvent1833.start',256,0,18,1,1,'Watches',1
Watch9='FEvent1833.finish',256,0,18,1,1,'Watches',1
Watch10='FEvent1833.getcustomfieldvaluebyname(''tt_fromdate'')',256,0,18,1,1,'Watches',1
Watch11='FEvent1833.getcustomfieldvaluebyname(''tt_todate'')',256,0,18,1,1,'Watches',1

[Watches]
Count=20
Watch0='AEvent.getcustomfieldvaluebyname(splantaskfromdate)',256,0,18,1,1,'Watches',1
Watch1='AEvent.getcustomfieldvaluebyname(splantasktodate)',256,0,18,1,1,'Watches',1
Watch2='aevent.start',256,0,18,1,1,'Watches',1
Watch3='aevent.finish',256,0,18,1,1,'Watches',1
Watch4='FDMPPlan.FEvent1833.start',256,0,18,1,1,'Watches',1
Watch5='FDMPPlan.FEvent1833.finish',256,0,18,1,1,'Watches',1
Watch6='FDMPPlan.FEvent1833.getcustomfieldvaluebyname(''tt_fromdate'')',256,0,18,1,1,'Watches',1
Watch7='FDMPPlan.FEvent1833.getcustomfieldvaluebyname(''tt_todate'')',256,0,18,1,1,'Watches',1
Watch8='FEvent1833.start',256,0,18,1,1,'Watches',1
Watch9='FEvent1833.finish',256,0,18,1,1,'Watches',1
Watch10='FEvent1833.getcustomfieldvaluebyname(''tt_fromdate'')',256,0,18,1,1,'Watches',1
Watch11='FEvent1833.getcustomfieldvaluebyname(''tt_todate'')',256,0,18,1,1,'Watches',1
Watch12='FDMPPlan.FEvent1834.start',256,0,18,1,1,'Watches',1
Watch13='FDMPPlan.FEvent1834.finish',256,0,18,1,1,'Watches',1
Watch14='FDMPPlan.FEvent1834.getcustomfieldvaluebyname(''tt_fromdate'')',256,0,18,1,1,'Watches',1
Watch15='FDMPPlan.FEvent1834.getcustomfieldvaluebyname(''tt_todate'')',256,0,18,1,1,'Watches',1
Watch16='FEvent1834.start',256,0,18,1,1,'Watches',1
Watch17='FEvent1834.finish',256,0,18,1,1,'Watches',1
Watch18='FEvent1834.getcustomfieldvaluebyname(''tt_fromdate'')',256,0,18,1,1,'Watches',1
Watch19='FEvent1834.getcustomfieldvaluebyname(''tt_todate'')',256,0,18,1,1,'Watches',1
于 2016-03-16T14:00:31.507 回答