填充监视窗口中的所有字段值

时间:2013-07-05 00:12:32

标签: delphi debugging

我需要在调试我的Delphi应用程序时获取许多数据库字段的外键值,以便在调试存储过程行为时使用它们。字段是如此之多,所以我想知道是否有更快的方法来获取这些值,如将所有这些值填充到监视窗口,而不是为我需要观察的每个字段编写表达式。

换句话说,我需要查看几个表的所有字段值。我不需要所有这些,但我可以从这样的列表中轻松选择我需要的东西。

目前我正在写这样的手表表达式:

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

3 个答案:

答案 0 :(得分:6)

不是真的。如果没有一些代码设置,就无法循环设置监视,或者无法在多个数据库字段上设置监视。

在Delphi 2010及更高版本中,您可以编写自己的debugger visualizer(请参阅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;

答案 1 :(得分:2)

为此,我将字段转储到跟踪日志e.i.像这样的东西:

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;

答案 2 :(得分:0)

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

以下是我想要复制和修改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