LazStats: Beginning to refactor CrossTabUnit: include output in form.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7708 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-09-28 16:24:38 +00:00
parent 21b70d0447
commit 788f6feec0
2 changed files with 443 additions and 393 deletions

View File

@ -1,41 +1,108 @@
object CrossTabFrm: TCrossTabFrm inherited CrossTabFrm: TCrossTabFrm
Left = 459 Left = 459
Height = 347 Height = 358
Top = 230 Top = 230
Width = 421 Width = 879
HelpType = htKeyword HelpType = htKeyword
HelpKeyword = 'html/Cross-tabulation.htm' HelpKeyword = 'html/Cross-tabulation.htm'
AutoSize = True
Caption = 'Cross Tabulation' Caption = 'Cross Tabulation'
ClientHeight = 347 ClientHeight = 358
ClientWidth = 421 ClientWidth = 879
OnActivate = FormActivate OnActivate = FormActivate
OnCreate = FormCreate OnCreate = FormCreate
OnShow = FormShow
Position = poMainFormCenter Position = poMainFormCenter
LCLVersion = '2.1.0.0' object ParamsPanel: TPanel[0]
object Panel2: TPanel
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = Owner
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = Bevel2
Left = 8 Left = 8
Height = 290 Height = 342
Top = 8 Top = 8
Width = 405 Width = 320
Anchors = [akTop, akLeft, akRight, akBottom] Align = alLeft
BorderSpacing.Left = 8 BorderSpacing.Left = 8
BorderSpacing.Top = 8 BorderSpacing.Top = 8
BorderSpacing.Right = 8 BorderSpacing.Right = 4
BorderSpacing.Bottom = 8
BevelOuter = bvNone BevelOuter = bvNone
ClientHeight = 290 ClientHeight = 342
ClientWidth = 405 ClientWidth = 320
Constraints.MinHeight = 200
TabOrder = 0 TabOrder = 0
object Bevel2: TBevel
AnchorSideLeft.Control = ParamsPanel
AnchorSideRight.Control = ParamsPanel
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = CloseBtn
Left = 0
Height = 8
Top = 301
Width = 320
Anchors = [akLeft, akRight, akBottom]
Shape = bsBottomLine
end
object CloseBtn: TButton
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = ParamsPanel
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = ParamsPanel
AnchorSideBottom.Side = asrBottom
Left = 265
Height = 25
Top = 317
Width = 55
Anchors = [akRight, akBottom]
AutoSize = True
BorderSpacing.Top = 8
Caption = 'Close'
ModalResult = 11
OnClick = CloseBtnClick
TabOrder = 0
end
object ResetBtn: TButton
AnchorSideTop.Control = CloseBtn
AnchorSideRight.Control = ComputeBtn
Left = 119
Height = 25
Top = 317
Width = 54
Anchors = [akTop, akRight]
AutoSize = True
BorderSpacing.Right = 8
Caption = 'Reset'
OnClick = ResetBtnClick
TabOrder = 1
end
object HelpBtn: TButton
AnchorSideTop.Control = CloseBtn
AnchorSideRight.Control = ResetBtn
Left = 60
Height = 25
Top = 317
Width = 51
Anchors = [akTop, akRight]
AutoSize = True
BorderSpacing.Right = 8
Caption = 'Help'
OnClick = HelpBtnClick
TabOrder = 2
end
object ComputeBtn: TButton
AnchorSideTop.Control = CloseBtn
AnchorSideRight.Control = CloseBtn
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 181
Height = 25
Top = 317
Width = 76
Anchors = [akTop, akRight]
AutoSize = True
BorderSpacing.Left = 8
BorderSpacing.Right = 8
Caption = 'Compute'
OnClick = ComputeBtnClick
TabOrder = 3
end
object Label1: TLabel object Label1: TLabel
AnchorSideLeft.Control = Panel2 AnchorSideLeft.Control = ParamsPanel
AnchorSideTop.Control = Panel2 AnchorSideTop.Control = ParamsPanel
Left = 0 Left = 0
Height = 15 Height = 15
Top = 0 Top = 0
@ -45,8 +112,7 @@ object CrossTabFrm: TCrossTabFrm
end end
object Label2: TLabel object Label2: TLabel
AnchorSideLeft.Control = SelList AnchorSideLeft.Control = SelList
AnchorSideTop.Control = Panel2 Left = 182
Left = 224
Height = 15 Height = 15
Top = 0 Top = 0
Width = 104 Width = 104
@ -54,76 +120,74 @@ object CrossTabFrm: TCrossTabFrm
ParentColor = False ParentColor = False
end end
object VarList: TListBox object VarList: TListBox
AnchorSideLeft.Control = Panel2 AnchorSideLeft.Control = ParamsPanel
AnchorSideTop.Control = Label1 AnchorSideTop.Control = Label1
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = InBtn AnchorSideRight.Control = InBtn
AnchorSideBottom.Control = Panel2 AnchorSideBottom.Control = Bevel2
AnchorSideBottom.Side = asrBottom
Left = 0 Left = 0
Height = 273 Height = 284
Top = 17 Top = 17
Width = 180 Width = 138
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Top = 2 BorderSpacing.Top = 2
BorderSpacing.Right = 8 BorderSpacing.Right = 8
ItemHeight = 0 ItemHeight = 0
MultiSelect = True MultiSelect = True
OnSelectionChange = VarListSelectionChange OnSelectionChange = VarListSelectionChange
TabOrder = 0 TabOrder = 4
end end
object SelList: TListBox object SelList: TListBox
AnchorSideLeft.Control = InBtn AnchorSideLeft.Control = InBtn
AnchorSideLeft.Side = asrBottom AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = Label2 AnchorSideTop.Control = Label2
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = Panel2 AnchorSideRight.Control = ParamsPanel
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = Panel2
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 224 Left = 182
Height = 273 Height = 281
Top = 17 Top = 17
Width = 181 Width = 138
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Left = 8 BorderSpacing.Left = 8
BorderSpacing.Top = 2 BorderSpacing.Top = 2
ItemHeight = 0 ItemHeight = 0
MultiSelect = True MultiSelect = True
OnSelectionChange = VarListSelectionChange OnSelectionChange = VarListSelectionChange
TabOrder = 3 TabOrder = 5
end end
object InBtn: TBitBtn object InBtn: TBitBtn
AnchorSideLeft.Control = Panel2 AnchorSideLeft.Control = ParamsPanel
AnchorSideLeft.Side = asrCenter AnchorSideLeft.Side = asrCenter
AnchorSideBottom.Control = VertCenterBevel AnchorSideBottom.Control = VertCenterBevel
Left = 188 Left = 146
Height = 28 Height = 28
Top = 119 Top = 125
Width = 28 Width = 28
Anchors = [akLeft, akBottom] Anchors = [akLeft, akBottom]
Images = MainDataModule.ImageList Images = MainDataModule.ImageList
ImageIndex = 1 ImageIndex = 1
OnClick = InBtnClick OnClick = InBtnClick
Spacing = 0 Spacing = 0
TabOrder = 1 TabOrder = 6
end end
object OutBtn: TBitBtn object OutBtn: TBitBtn
AnchorSideLeft.Control = Panel2 AnchorSideLeft.Control = ParamsPanel
AnchorSideLeft.Side = asrCenter AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = VertCenterBevel AnchorSideTop.Control = VertCenterBevel
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
AnchorSideBottom.Control = VertCenterBevel AnchorSideBottom.Control = VertCenterBevel
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 188 Left = 146
Height = 28 Height = 28
Top = 159 Top = 165
Width = 28 Width = 28
Images = MainDataModule.ImageList Images = MainDataModule.ImageList
ImageIndex = 0 ImageIndex = 0
OnClick = OutBtnClick OnClick = OutBtnClick
Spacing = 0 Spacing = 0
TabOrder = 2 TabOrder = 7
end end
object VertCenterBevel: TBevel object VertCenterBevel: TBevel
AnchorSideLeft.Control = InBtn AnchorSideLeft.Control = InBtn
@ -131,90 +195,36 @@ object CrossTabFrm: TCrossTabFrm
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = OutBtn AnchorSideRight.Control = OutBtn
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 188 Left = 146
Height = 12 Height = 12
Top = 147 Top = 153
Width = 28 Width = 28
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
Shape = bsSpacer Shape = bsSpacer
end end
end end
object Bevel2: TBevel object ParamsSplitter: TSplitter[1]
AnchorSideLeft.Control = Owner Left = 332
AnchorSideRight.Control = Owner Height = 358
AnchorSideRight.Side = asrBottom Top = 0
AnchorSideBottom.Control = CloseBtn Width = 5
Left = 0 ResizeStyle = rsPattern
Height = 8
Top = 298
Width = 421
Anchors = [akLeft, akRight, akBottom]
Shape = bsBottomLine
end end
object CloseBtn: TButton object PageControl: TPageControl[2]
AnchorSideTop.Side = asrBottom Left = 341
AnchorSideRight.Control = Owner Height = 342
AnchorSideRight.Side = asrBottom Top = 8
AnchorSideBottom.Control = Owner Width = 530
AnchorSideBottom.Side = asrBottom ActivePage = ReportPage
Left = 354 Align = alClient
Height = 25 BorderSpacing.Left = 4
Top = 314
Width = 55
Anchors = [akRight, akBottom]
AutoSize = True
BorderSpacing.Top = 8 BorderSpacing.Top = 8
BorderSpacing.Right = 12 BorderSpacing.Right = 8
BorderSpacing.Bottom = 8 BorderSpacing.Bottom = 8
Caption = 'Close' TabIndex = 0
ModalResult = 11
TabOrder = 1
end
object ResetBtn: TButton
AnchorSideTop.Control = CloseBtn
AnchorSideRight.Control = ComputeBtn
Left = 200
Height = 25
Top = 314
Width = 54
Anchors = [akTop, akRight]
AutoSize = True
BorderSpacing.Right = 12
Caption = 'Reset'
OnClick = ResetBtnClick
TabOrder = 2 TabOrder = 2
end object ReportPage: TTabSheet
object HelpBtn: TButton Caption = 'Report'
AnchorSideTop.Control = CloseBtn end
AnchorSideRight.Control = ResetBtn
Left = 137
Height = 25
Top = 314
Width = 51
Anchors = [akTop, akRight]
AutoSize = True
BorderSpacing.Left = 12
BorderSpacing.Right = 12
Caption = 'Help'
OnClick = HelpBtnClick
TabOrder = 3
end
object ComputeBtn: TButton
AnchorSideRight.Control = CloseBtn
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 266
Height = 25
Top = 314
Width = 76
Anchors = [akRight, akBottom]
AutoSize = True
BorderSpacing.Left = 12
BorderSpacing.Top = 8
BorderSpacing.Right = 12
BorderSpacing.Bottom = 8
Caption = 'Compute'
OnClick = ComputeBtnClick
TabOrder = 4
end end
end end

View File

@ -7,39 +7,44 @@ unit CrossTabUnit;
interface interface
uses uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
StdCtrls, Buttons, ExtCtrls, StdCtrls, Buttons, ExtCtrls, ComCtrls,
Globals, OutputUnit, MainUnit, DataProcs, MatrixLib, ContextHelpUnit; Globals, MainUnit, DataProcs, MatrixLib, ContextHelpUnit,
BasicStatsFormUnit, ReportFrameUnit;
type type
{ TCrossTabFrm } { TCrossTabFrm }
TCrossTabFrm = class(TForm) TCrossTabFrm = class(TBasicStatsForm)
ComputeBtn: TButton; ComputeBtn: TButton;
PageControl: TPageControl;
ParamsPanel: TPanel;
ParamsSplitter: TSplitter;
ReportPage: TTabSheet;
VertCenterBevel: TBevel; VertCenterBevel: TBevel;
Bevel2: TBevel; Bevel2: TBevel;
HelpBtn: TButton; HelpBtn: TButton;
InBtn: TBitBtn; InBtn: TBitBtn;
OutBtn: TBitBtn; OutBtn: TBitBtn;
Panel2: TPanel;
ResetBtn: TButton; ResetBtn: TButton;
CloseBtn: TButton; CloseBtn: TButton;
Label1: TLabel; Label1: TLabel;
Label2: TLabel; Label2: TLabel;
VarList: TListBox; VarList: TListBox;
SelList: TListBox; SelList: TListBox;
procedure CloseBtnClick(Sender: TObject);
procedure FormActivate(Sender: TObject); procedure FormActivate(Sender: TObject);
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure HelpBtnClick(Sender: TObject); procedure HelpBtnClick(Sender: TObject);
procedure InBtnClick(Sender: TObject); procedure InBtnClick(Sender: TObject);
procedure ComputeBtnClick(Sender: TObject); procedure ComputeBtnClick(Sender: TObject);
procedure OutBtnClick(Sender: TObject); procedure OutBtnClick(Sender: TObject);
procedure ResetBtnClick(Sender: TObject); procedure ResetBtnClick(Sender: TObject);
procedure VarListSelectionChange(Sender: TObject; User: boolean); procedure VarListSelectionChange(Sender: TObject; {%H-}User: boolean);
private private
{ private declarations } { private declarations }
FReportFrame: TReportFrame;
FAutoSized: Boolean; FAutoSized: Boolean;
grandsum, sum, index : integer; grandsum, sum, index : integer;
no_in_list, length_array, ptr1, ptr2 : integer ; no_in_list, length_array, ptr1, ptr2 : integer ;
@ -61,280 +66,24 @@ type
public public
{ public declarations } { public declarations }
procedure Reset; override;
end; end;
var var
CrossTabFrm: TCrossTabFrm; CrossTabFrm: TCrossTabFrm;
implementation implementation
{$R *.lfm}
uses uses
Math; Math,
Utils;
{ TCrossTabFrm } { TCrossTabFrm }
procedure TCrossTabFrm.ResetBtnClick(Sender: TObject);
var
i: integer;
begin
VarList.Clear;
SelList.Clear;
NV := NoVariables;
NC := NoCases;
for i := 1 to NV do
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]);
UpdateBtnStates;
end;
procedure TCrossTabFrm.FormShow(Sender: TObject);
begin
ResetBtnClick(self);
end;
procedure TCrossTabFrm.HelpBtnClick(Sender: TObject);
begin
if ContextHelpForm = nil then
Application.CreateForm(TContextHelpForm, ContextHelpForm);
ContextHelpForm.HelpMessage((Sender as TButton).Tag);
end;
procedure TCrossTabFrm.InBtnClick(Sender: TObject);
var
i: integer;
begin
i := 0;
while i < VarList.Items.Count do
begin
if VarList.Selected[i] then
begin
SelList.Items.Add(VarList.Items[i]);
VarList.Items.Delete(i);
i := 0;
end else
inc(i);
end;
UpdateBtnStates;
end;
procedure TCrossTabFrm.ComputeBtnClick(Sender: TObject);
var
cellvalue: string;
i, j: integer;
lReport: TStrings;
begin
if SelList.Items.Count = 0 then
begin
MessageDlg('No variables selected for analysis.', mtError, [mbOK], 0);
exit;
end;
SetLength(var_list, NV);
SetLength(min_value, NV);
SetLength(max_value, NV);
SetLength(levels, NC);
SetLength(displace, NC);
SetLength(subscript,NC);
SetLength(ColNoSelected, NV);
lReport := TStringList.Create;
try
lReport.Add('CROSSTAB RESULTS');
lReport.Add('');
lReport.Add('Analyzed data is from file ' + OS3MainFrm.FileNameEdit.Text);
lReport.Add('');
Initialize;
NoSelected := 0;
for i := 0 to SelList.Items.Count-1 do
begin
for j := 1 to NV do
begin
cellvalue := OS3MainFrm.DataGrid.Cells[j,0];
if cellvalue = SelList.Items[i] then
begin
var_list[i] := j;
ColNoSelected[i] := j;
NoSelected := NoSelected + 1;
break;
end;
end;
end;
no_in_list := SelList.Items.Count;
GetLevels(lReport);
Tabulate;
BreakDown(lReport);
lReport.Add('');
lReport.Add('Grand sum across all categories = %d', [grandsum]);
DisplayReport(lReport);
finally
lReport.Free;
ColNoSelected := nil;
freq := nil;
collabels := nil;
rowlabels := nil;
outgrid := nil;
subscript := nil;
displace := nil;
levels := nil;
max_value := nil;
min_value := nil;
var_list := nil;
end;
end;
procedure TCrossTabFrm.OutBtnClick(Sender: TObject);
var
i: integer;
begin
i := 0;
while i < SelList.Items.Count do
begin
if SelList.Selected[i] then
begin
VarList.Items.Add(SelList.Items[i]);
SelList.Items.Delete(i);
i := 0;
end else
inc(i);
end;
UpdateBtnStates;
end;
procedure TCrossTabFrm.FormActivate(Sender: TObject);
var
w: Integer;
begin
if FAutoSized then
exit;
w := MaxValue([HelpBtn.Width, ResetBtn.Width, ComputeBtn.Width, CloseBtn.Width]);
HelpBtn.Constraints.MinWidth := w;
ResetBtn.Constraints.MinWidth := w;
ComputeBtn.Constraints.MinWidth := w;
CloseBtn.Constraints.MinWidth := w;
Constraints.MinWidth := Width;
Constraints.MinHeight := Height;
FAutoSized := true;
end;
procedure TCrossTabFrm.FormCreate(Sender: TObject);
begin
Assert(OS3MainFrm <> nil);
end;
procedure TCrossTabFrm.Initialize;
var
i: integer;
begin
no_in_list := 0;
for i := 1 to NV do
begin
var_list[i-1] := 0;
min_value[i-1] := 0;
max_value[i-1] := 0;
levels[i-1] := 0;
displace[i-1] := 0;
subscript[i-1] := 0;
end;
index := 0;
length_array := 0;
grandsum := 0;
end; { initialize procedure }
procedure TCrossTabFrm.GetLevels(AReport: TStrings);
var
i, j, k: integer;
value: double;
begin
for i := 1 to no_in_list do
begin
j := var_list[i-1];
if not GoodRecord(1,NoSelected,ColNoSelected) then continue;
value := StrToFloat(OS3MainFrm.DataGrid.Cells[j,1]);
min_value[i-1] := round(value);
max_value[i-1] := round(value);
for k := 2 to NC do
begin
if not GoodRecord(k,NoSelected,ColNoSelected) then continue;
value := StrToFloat(OS3MainFrm.DataGrid.Cells[j,k]);
if value < min_value[i-1] then
min_value[i-1] := round(value);
if value > max_value[i-1] then
max_value[i-1] := round(value);
end;
end;
for i := 1 to no_in_list do
begin
j := var_list[i-1];
levels[i-1] := max_value[i-1] - min_value[i-1] + 1;
AReport.Add('%s min.=%3d, max.=%3d, no. levels = %3d', [
OS3MainFrm.DataGrid.Cells[j,0],min_value[i-1],max_value[i-1],levels[i-1]
]);
end;
AReport.Add('');
displace[no_in_list-1] := 1;
if no_in_list > 1 then
for i := (no_in_list - 1) downto 1 do
displace[i-1] := levels[i] * displace[i];
end;
function TCrossTabFrm.IndexPosition(x: IntDyneVec): integer;
var
i: integer;
begin
Result := x[no_in_list-1];
if no_in_list > 1 then
begin
for i := 1 to no_in_list - 1 do
Result := Result + (x[i-1] -1) * displace[i-1];
end;
end;
procedure TCrossTabFrm.Tabulate;
var
i, j, k: integer;
value: double;
x: integer;
begin
length_array := 1;
for i := 1 to no_in_list do
length_array := length_array * levels[i-1];
SetLength(freq,length_array+1);
for i := 0 to length_array do
freq[i] := 0;
for i := 1 to NC do
begin
if IsFiltered(i) then
continue;
for j := 1 to no_in_list do
begin
if not GoodRecord(i,NoSelected,ColNoSelected) then continue;
k := var_list[j-1];
value := StrToFloat(OS3MainFrm.DataGrid.Cells[k,i]);
x := round(value);
x := x - min_value[j-1] + 1;
subscript[j-1] := x;
end;
j := IndexPosition(subscript);
if (j < 1) or (j > length_array) then
continue
else
freq[j] := freq[j] + 1;
end;
end; { procedure TABULATE }
procedure TCrossTabFrm.BreakDown(AReport: TStrings); procedure TCrossTabFrm.BreakDown(AReport: TStrings);
label 1,2,3,4, printgrid; label 1,2,3,4, printgrid;
var var
@ -427,6 +176,297 @@ printgrid:
MatPrint(outgrid,row-1,Levels[no_in_list-1],title,rowlabels,collabels,NC, AReport); MatPrint(outgrid,row-1,Levels[no_in_list-1],title,rowlabels,collabels,NC, AReport);
end; { Procedure BREAKDOWN } end; { Procedure BREAKDOWN }
procedure TCrossTabFrm.CloseBtnClick(Sender: TObject);
begin
Close;
end;
procedure TCrossTabFrm.ComputeBtnClick(Sender: TObject);
var
cellvalue: string;
i, j: integer;
lReport: TStrings;
begin
if SelList.Items.Count = 0 then
begin
MessageDlg('No variables selected for analysis.', mtError, [mbOK], 0);
exit;
end;
SetLength(var_list, NV);
SetLength(min_value, NV);
SetLength(max_value, NV);
SetLength(levels, NC);
SetLength(displace, NC);
SetLength(subscript,NC);
SetLength(ColNoSelected, NV);
lReport := TStringList.Create;
try
lReport.Add('CROSSTAB RESULTS');
lReport.Add('');
lReport.Add('Analyzed data is from file ' + OS3MainFrm.FileNameEdit.Text);
lReport.Add('');
Initialize;
NoSelected := 0;
for i := 0 to SelList.Items.Count-1 do
begin
for j := 1 to NV do
begin
cellvalue := OS3MainFrm.DataGrid.Cells[j,0];
if cellvalue = SelList.Items[i] then
begin
var_list[i] := j;
ColNoSelected[i] := j;
NoSelected := NoSelected + 1;
break;
end;
end;
end;
no_in_list := SelList.Items.Count;
GetLevels(lReport);
Tabulate;
BreakDown(lReport);
lReport.Add('');
lReport.Add('Grand sum across all categories = %d', [grandsum]);
FReportFrame.DisplayReport(lReport);
finally
lReport.Free;
end;
end;
procedure TCrossTabFrm.FormActivate(Sender: TObject);
var
w: Integer;
begin
if FAutoSized then
exit;
w := MaxValue([HelpBtn.Width, ResetBtn.Width, ComputeBtn.Width, CloseBtn.Width]);
HelpBtn.Constraints.MinWidth := w;
ResetBtn.Constraints.MinWidth := w;
ComputeBtn.Constraints.MinWidth := w;
CloseBtn.Constraints.MinWidth := w;
ParamsPanel.Constraints.MinWidth := Max(
4*w + 3*CloseBtn.BorderSpacing.Left,
Max(Label1.Width, Label2.Width) + InBtn.Width + VarList.BorderSpacing.Right * 2
);
ParamsPanel.Constraints.MinHeight := 200;
Constraints.MinWidth := ParamsPanel.Constraints.MinWidth + 300;;
Constraints.MinHeight := ParamsPanel.Constraints.MinHeight + 2*ParamsPanel.BorderSpacing.Top;
if Width < Constraints.MinWidth then Width := 1; // enforce constraints
if Height < Constraints.MinHeight then Height := 1;
Position := poDesigned;
FAutoSized := true;
end;
procedure TCrossTabFrm.FormCreate(Sender: TObject);
begin
Assert(OS3MainFrm <> nil);
InitForm(self);
FReportFrame := TReportFrame.Create(self);
with FReportFrame do
begin
Parent := ReportPage;
Align := alClient;
end;
Reset;
end;
procedure TCrossTabFrm.GetLevels(AReport: TStrings);
var
i, j, k: integer;
value: double;
begin
for i := 1 to no_in_list do
begin
j := var_list[i-1];
if not GoodRecord(1,NoSelected,ColNoSelected) then continue;
value := StrToFloat(OS3MainFrm.DataGrid.Cells[j,1]);
min_value[i-1] := round(value);
max_value[i-1] := round(value);
for k := 2 to NC do
begin
if not GoodRecord(k,NoSelected,ColNoSelected) then continue;
value := StrToFloat(OS3MainFrm.DataGrid.Cells[j,k]);
if value < min_value[i-1] then
min_value[i-1] := round(value);
if value > max_value[i-1] then
max_value[i-1] := round(value);
end;
end;
for i := 1 to no_in_list do
begin
j := var_list[i-1];
levels[i-1] := max_value[i-1] - min_value[i-1] + 1;
AReport.Add('%s min.=%3d, max.=%3d, no. levels = %3d', [
OS3MainFrm.DataGrid.Cells[j,0],min_value[i-1],max_value[i-1],levels[i-1]
]);
end;
AReport.Add('');
displace[no_in_list-1] := 1;
if no_in_list > 1 then
for i := (no_in_list - 1) downto 1 do
displace[i-1] := levels[i] * displace[i];
end;
procedure TCrossTabFrm.HelpBtnClick(Sender: TObject);
begin
if ContextHelpForm = nil then
Application.CreateForm(TContextHelpForm, ContextHelpForm);
ContextHelpForm.HelpMessage((Sender as TButton).Tag);
end;
procedure TCrossTabFrm.InBtnClick(Sender: TObject);
var
i: integer;
begin
i := 0;
while i < VarList.Items.Count do
begin
if VarList.Selected[i] then
begin
SelList.Items.Add(VarList.Items[i]);
VarList.Items.Delete(i);
i := 0;
end else
inc(i);
end;
UpdateBtnStates;
end;
function TCrossTabFrm.IndexPosition(x: IntDyneVec): integer;
var
i: integer;
begin
Result := x[no_in_list-1];
if no_in_list > 1 then
begin
for i := 1 to no_in_list - 1 do
Result := Result + (x[i-1] -1) * displace[i-1];
end;
end;
procedure TCrossTabFrm.Initialize;
var
i: integer;
begin
no_in_list := 0;
for i := 1 to NV do
begin
var_list[i-1] := 0;
min_value[i-1] := 0;
max_value[i-1] := 0;
levels[i-1] := 0;
displace[i-1] := 0;
subscript[i-1] := 0;
end;
index := 0;
length_array := 0;
grandsum := 0;
end;
procedure TCrossTabFrm.OutBtnClick(Sender: TObject);
var
i: integer;
begin
i := 0;
while i < SelList.Items.Count do
begin
if SelList.Selected[i] then
begin
VarList.Items.Add(SelList.Items[i]);
SelList.Items.Delete(i);
i := 0;
end else
inc(i);
end;
UpdateBtnStates;
end;
procedure TCrossTabFrm.Reset;
var
i: integer;
begin
VarList.Clear;
SelList.Clear;
NV := NoVariables;
NC := NoCases;
for i := 1 to NV do
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]);
UpdateBtnStates;
FReportFrame.Clear;
end;
procedure TCrossTabFrm.ResetBtnClick(Sender: TObject);
begin
Reset;
end;
procedure TCrossTabFrm.Tabulate;
var
i, j, k: integer;
value: double;
x: integer;
begin
length_array := 1;
for i := 1 to no_in_list do
length_array := length_array * levels[i-1];
SetLength(freq,length_array+1);
for i := 0 to length_array do
freq[i] := 0;
for i := 1 to NC do
begin
if IsFiltered(i) then
continue;
for j := 1 to no_in_list do
begin
if not GoodRecord(i,NoSelected,ColNoSelected) then continue;
k := var_list[j-1];
value := StrToFloat(OS3MainFrm.DataGrid.Cells[k,i]);
x := round(value);
x := x - min_value[j-1] + 1;
subscript[j-1] := x;
end;
j := IndexPosition(subscript);
if (j < 1) or (j > length_array) then
continue
else
freq[j] := freq[j] + 1;
end;
end; { procedure TABULATE }
procedure TCrossTabFrm.UpdateBtnStates; procedure TCrossTabFrm.UpdateBtnStates;
var var
lSelected: Boolean; lSelected: Boolean;
@ -449,16 +489,16 @@ begin
break; break;
end; end;
OutBtn.Enabled := lSelected; OutBtn.Enabled := lSelected;
FReportFrame.UpdateBtnStates;
end; end;
procedure TCrossTabFrm.VarListSelectionChange(Sender: TObject; User: boolean); procedure TCrossTabFrm.VarListSelectionChange(Sender: TObject; User: boolean);
begin begin
UpdateBtnStates; UpdateBtnStates;
end; end;
initialization
{$I crosstabunit.lrs}
end. end.