[DUG] Make all possible unique combinations

Sandeep Chandra sandeep_groups at yahoo.com
Thu Dec 10 12:54:32 NZDT 2009


Here is my way of doing this. Not sure if it is perfect but it seems to work.

I am pasting the dfm and pas file text.


***************************************************************************

object Form2: TForm2
  Left = 0
  Top = 0
  Caption = 'Form2'
  ClientHeight = 563
  ClientWidth = 796
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -13
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 16
  object Button1: TButton
    Left = 12
    Top = 12
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 0
    OnClick = Button1Click
  end
  object DBGrid1: TDBGrid
    Left = 0
    Top = 43
    Width = 796
    Height = 520
    Align = alBottom
    DataSource = DataSource1
    TabOrder = 1
    TitleFont.Charset = DEFAULT_CHARSET
    TitleFont.Color = clWindowText
    TitleFont.Height = -13
    TitleFont.Name = 'Tahoma'
    TitleFont.Style = []
  end
  object tbl: TClientDataSet
    Aggregates = <>
    FieldDefs = <>
    IndexDefs = <
      item
        Name = 'tblKey1'
        Options = [ixUnique]
      end>
    Params = <>
    StoreDefs = True
    Left = 352
    Top = 24
  end
  object DataSource1: TDataSource
    DataSet = tbl
    Left = 408
    Top = 24
  end
end

***************************************************************************
unit Unit2;
{$O-}
interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, DB, DBClient, Grids, DBGrids, Types;

type
  TFJStockTable = (
    stStGr, stStg1, stStg2, stStg3,
    stStg4, stStg5, stStg6);
  TFJStockTableSet = set of TFJStockTable;
const
  STOCK_TABLE_NAMES : array[TFJStockTable] of string = (
    'StGr', 'Stg1', 'Stg2', 'Stg3',
    'Stg4', 'Stg5', 'Stg6');

type
  TFJStockTableReader = class
  private
    FParentTable : TFJStockTableReader;
    FTable       : TStringDynArray;
  public
    FCurrRecIdx  : Integer;
    constructor Create(AParentTable : TFJStockTableReader;
      const ATable : array of string);
    function FJGetNextVal(
      const AIncrementIndex : Boolean = False) : string;
  end;

type
  TForm2 = class(TForm)
    Button1: TButton;
    tbl: TClientDataSet;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FStockTablesToUse: TFJStockTableSet;
    procedure FJSetupTable(const AStockTablesToUse: TFJStockTableSet);
  public
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.FJSetupTable(const AStockTablesToUse : TFJStockTableSet);
var
  lStkTbl : TFJStockTable;
begin
  FStockTablesToUse := AStockTablesToUse;
  // ATableCount is the number of tables(Stgr, Stg1, Stg2..) used by
  // a system.
  if (AStockTablesToUse = []) then
    Exit;

  tbl.IndexDefs[0].Fields := '';
  for lStkTbl in AStockTablesToUse do
  begin
   tbl.FieldDefs.Add(STOCK_TABLE_NAMES[lStkTbl], ftString, 20);
   with tbl.IndexDefs[0] do
   begin
     if (Fields <> '') then
       Fields := Fields + ';';
     Fields := Fields + STOCK_TABLE_NAMES[lStkTbl];
   end;
  end;

  tbl.CreateDataSet;
end;


const
  STGR : array[1..2] of string = ('A1', 'A2');
  STG1 : array[1..4] of string = ('B1', 'B2', 'B3', 'B4');
  STG2 : array[1..2] of string = ('C1', 'C2');

procedure TForm2.FormCreate(Sender: TObject);
begin
  FJSetupTable([stStgr, stStg1, stStg2, stStg3]);
end;

procedure TForm2.Button1Click(Sender: TObject);
var
  i : Integer;
  j : Integer;
  k : Integer;

  procedure FJAddValue;
  var
    lRdrStgr : TFJStockTableReader;
    lRdrStg1 : TFJStockTableReader;
    lRdrStg2 : TFJStockTableReader;
    i        : Integer;
    j        : TFJStockTable;
    lRdrStg3 : TFJStockTableReader;
  begin
    lRdrStgr := TFJStockTableReader.Create(nil     , ['A1', 'A2']);
    lRdrStg1 := TFJStockTableReader.Create(lRdrStgr, ['B1', 'B2', 'B3', 'B4', 'B5']);
    lRdrStg2 := TFJStockTableReader.Create(lRdrStg1, ['C1', 'C2']);
    lRdrStg3 := TFJStockTableReader.Create(lRdrStg2, ['D1', 'D2', 'D3', 'D4', 'D5']);

    for i := 1 to 100 { = Multiply reccnt in all tables } do
    begin
      tbl.Append;
//      for j := High(TFJStockTable) downto Low(TFJStockTable) do
//      begin
//        if (j in FStockTablesToUse) then
//          tbl.FieldByName(STOCK_TABLE_NAMES[j]).AsString := lRdrStg2.FJGetNextVal(True)
//      end;
      tbl.FieldByName(STOCK_TABLE_NAMES[stStg3]).AsString := lRdrStg3.FJGetNextVal(True);
      tbl.FieldByName(STOCK_TABLE_NAMES[stStg2]).AsString := lRdrStg2.FJGetNextVal;
      tbl.FieldByName(STOCK_TABLE_NAMES[stStg1]).AsString := lRdrStg1.FJGetNextVal;
      tbl.FieldByName(STOCK_TABLE_NAMES[stStgr]).AsString := lRdrStgr.FJGetNextVal;
      tbl.Post;
    end;
  end;

begin
  tbl.EmptyDataSet;

  FJAddValue;
end;

{ TFJStockTableReader }

constructor TFJStockTableReader.Create(AParentTable : TFJStockTableReader;
  const ATable : array of string);
var
  i : Integer;
begin
  inherited Create;

  FParentTable := AParentTable;

  FCurrRecIdx := -1;
  SetLength(FTable, Length(ATable));
  for i := 0 to High(ATable) do
    FTable[i] := ATable[i];
end;

function TFJStockTableReader.FJGetNextVal(
  const AIncrementIndex : Boolean = False) : string;
begin
  if (AIncrementIndex )
  or (FCurrRecIdx = -1) then
    Inc(FCurrRecIdx);

  if (FCurrRecIdx > High(FTable)) then
  begin
    FCurrRecIdx := 0;
    if (Assigned(FParentTable)) then
      Inc(FParentTable.FCurrRecIdx);
  end;
  
  Result := FTable[FCurrRecIdx];

end;

end.

***************************************************************************



      



More information about the Delphi mailing list