Master Detail Problem

Discussion of open issues, suggestions and bugs regarding Virtual Data Access Components for Delphi, C++Builder, Lazarus (and FPC)
Post Reply
Sugarloafer
Posts: 10
Joined: Wed 09 May 2012 21:00

Master Detail Problem

Post by Sugarloafer » Thu 10 May 2012 03:36

Hello,

I'm experiencing a problem when two detail tables share the same master table. I set up the master detail relationship at runtime. When setting up the second table, I get an error "Can not find field..." I have created a simple project to create the error:

.pas File

Code: Select all

unit frmVTableTest;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons, Data.DB,
  MemDS, VirtualTable;

type
  TForm1 = class(TForm)
    tblMaster: TVirtualTable;
    tblDetail1: TVirtualTable;
    tblDetail2: TVirtualTable;
    dsMaster: TDataSource;
    BitBtn1: TBitBtn;
    BitBtn2: TBitBtn;
    tblMasterIdxField: TIntegerField;
    tblMasterDataField: TIntegerField;
    tblDetail1IdxField: TIntegerField;
    tblDetail1DataField: TIntegerField;
    tblDetail2IdxField: TIntegerField;
    tblDetail2DataField: TIntegerField;
    tblDetail2Det2Idx: TIntegerField;
    tblDetail1Det1Idx: TIntegerField;
    procedure BitBtn1Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    procedure SetupDetailTable(theTable: TVirtualTable;
      theDataSource: TDataSource; const sIndexFields, sMasterFields,
      sDetailFields: string; const bOpen: boolean);
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  SetupDetailTable(tblDetail1, nil, 'IdxField;Det1Idx', '',
    '', True);
  SetupDetailTable(tblDetail2, nil, 'IdxField;Det2Idx', '',
    '', False);
  SetupDetailTable(tblDetail1, dsMaster, 'IdxField;Det1Idx', 'IdxField',
    'IdxField', False);
  SetupDetailTable(tblDetail2, dsMaster, 'IdxField;Det2Idx', 'IdxField',
    'IdxField', True);
 end;

procedure TForm1.FormShow(Sender: TObject);
begin
  tblMaster.Open;
end;

procedure TForm1.SetupDetailTable(theTable: TVirtualTable; theDataSource: TDataSource;
  const sIndexFields, sMasterFields, sDetailFields: string; const bOpen: boolean);
begin
  with theTable do
  begin
    IndexFieldNames := sIndexFields;
    MasterFields := sMasterFields;
    DetailFields := sDetailFields;
    MasterSource := theDataSource;
    if bOpen then
      Open;
  end;
end;

end.

.dfm file:

Code: Select all

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Test VTable Master Detail'
  ClientHeight = 310
  ClientWidth = 437
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnShow = FormShow
  PixelsPerInch = 96
  TextHeight = 13
  object BitBtn1: TBitBtn
    Left = 344
    Top = 8
    Width = 75
    Height = 33
    Caption = 'Link'
    Glyph.Data = {
      DE010000424DDE01000000000000760000002800000024000000120000000100
      0400000000006801000000000000000000001000000000000000000000000000
      80000080000000808000800000008000800080800000C0C0C000808080000000
      FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00333333444444
      33333333333F8888883F33330000324334222222443333388F3833333388F333
      000032244222222222433338F8833FFFFF338F3300003222222AAAAA22243338
      F333F88888F338F30000322222A33333A2224338F33F8333338F338F00003222
      223333333A224338F33833333338F38F00003222222333333A444338FFFF8F33
      3338888300003AAAAAAA33333333333888888833333333330000333333333333
      333333333333333333FFFFFF000033333333333344444433FFFF333333888888
      00003A444333333A22222438888F333338F3333800003A2243333333A2222438
      F38F333333833338000033A224333334422224338338FFFFF8833338000033A2
      22444442222224338F3388888333FF380000333A2222222222AA243338FF3333
      33FF88F800003333AA222222AA33A3333388FFFFFF8833830000333333AAAAAA
      3333333333338888883333330000333333333333333333333333333333333333
      0000}
    NumGlyphs = 2
    TabOrder = 0
    OnClick = BitBtn1Click
  end
  object BitBtn2: TBitBtn
    Left = 344
    Top = 47
    Width = 75
    Height = 33
    Kind = bkClose
    NumGlyphs = 2
    TabOrder = 1
  end
  object tblMaster: TVirtualTable
    Options = []
    IndexFieldNames = 'IdxField'
    FieldDefs = <
      item
        Name = 'IdxField'
        DataType = ftInteger
      end
      item
        Name = 'DataField'
        DataType = ftInteger
      end>
    Left = 56
    Top = 64
    object tblMasterIdxField: TIntegerField
      FieldName = 'IdxField'
    end
    object tblMasterDataField: TIntegerField
      FieldName = 'DataField'
    end
  end
  object tblDetail1: TVirtualTable
    Options = []
    FieldDefs = <
      item
        Name = 'IdxField'
        DataType = ftInteger
      end
      item
        Name = 'DataField'
        DataType = ftInteger
      end>
    Left = 240
    Top = 64
    object tblDetail1IdxField: TIntegerField
      FieldName = 'IdxField'
    end
    object tblDetail1Det1Idx: TIntegerField
      FieldName = 'Det1Idx'
    end
    object tblDetail1DataField: TIntegerField
      FieldName = 'DataField'
    end
  end
  object tblDetail2: TVirtualTable
    Options = []
    FieldDefs = <
      item
        Name = 'IdxField'
        DataType = ftInteger
      end
      item
        Name = 'DataField'
        DataType = ftInteger
      end>
    Left = 240
    Top = 120
    object tblDetail2IdxField: TIntegerField
      FieldName = 'IdxField'
    end
    object tblDetail2Det2Idx: TIntegerField
      FieldName = 'Det2Idx'
    end
    object tblDetail2DataField: TIntegerField
      FieldName = 'DataField'
    end
  end
  object dsMaster: TDataSource
    DataSet = tblMaster
    Left = 136
    Top = 64
  end
end
I just started using VirtualTable, and have not received the source code, yet. So I can't delve any deeper. Sorry.

Sugarloafer
Posts: 10
Joined: Wed 09 May 2012 21:00

Re: Master Detail Problem

Post by Sugarloafer » Thu 10 May 2012 17:10

OK. Got my source this morning. The problem is happening because the table is not Active.
If the table is not Active, the field descriptions are not loaded and the find detail field fails.

If I change my SetupDetailTable to:

Code: Select all

procedure TForm1.SetupDetailTable(theTable: TVirtualTable; theDataSource: TDataSource;
  const sIndexFields, sMasterFields, sDetailFields: string; const bOpen: boolean);
begin
  with theTable do
  begin
    if bOpen then
      Open;
    IndexFieldNames := sIndexFields;
    MasterFields := sMasterFields;
    DetailFields := sDetailFields;
    MasterSource := theDataSource;
  end;
end;
Now it works, and I can live with it.

However, I really think you should be able to set these properties on a closed table.

AndreyZ

Re: Master Detail Problem

Post by AndreyZ » Fri 11 May 2012 13:51

Hello,

Thank you for the information. We have fixed this problem. This fix will be included in the next VirtualTable build.

Post Reply