From 788f6feec02182f73cbac6dccb72d697a3376b76 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Mon, 28 Sep 2020 16:24:38 +0000 Subject: [PATCH] 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 --- .../analysis/descriptive/crosstabunit.lfm | 250 ++++---- .../analysis/descriptive/crosstabunit.pas | 586 ++++++++++-------- 2 files changed, 443 insertions(+), 393 deletions(-) diff --git a/applications/lazstats/source/forms/analysis/descriptive/crosstabunit.lfm b/applications/lazstats/source/forms/analysis/descriptive/crosstabunit.lfm index f4ebbc9ae..fda5c2841 100644 --- a/applications/lazstats/source/forms/analysis/descriptive/crosstabunit.lfm +++ b/applications/lazstats/source/forms/analysis/descriptive/crosstabunit.lfm @@ -1,41 +1,108 @@ -object CrossTabFrm: TCrossTabFrm +inherited CrossTabFrm: TCrossTabFrm Left = 459 - Height = 347 + Height = 358 Top = 230 - Width = 421 + Width = 879 HelpType = htKeyword HelpKeyword = 'html/Cross-tabulation.htm' - AutoSize = True Caption = 'Cross Tabulation' - ClientHeight = 347 - ClientWidth = 421 + ClientHeight = 358 + ClientWidth = 879 OnActivate = FormActivate OnCreate = FormCreate - OnShow = FormShow Position = poMainFormCenter - LCLVersion = '2.1.0.0' - object Panel2: TPanel - AnchorSideLeft.Control = Owner - AnchorSideTop.Control = Owner - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = Bevel2 + object ParamsPanel: TPanel[0] Left = 8 - Height = 290 + Height = 342 Top = 8 - Width = 405 - Anchors = [akTop, akLeft, akRight, akBottom] + Width = 320 + Align = alLeft BorderSpacing.Left = 8 BorderSpacing.Top = 8 - BorderSpacing.Right = 8 + BorderSpacing.Right = 4 + BorderSpacing.Bottom = 8 BevelOuter = bvNone - ClientHeight = 290 - ClientWidth = 405 - Constraints.MinHeight = 200 + ClientHeight = 342 + ClientWidth = 320 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 - AnchorSideLeft.Control = Panel2 - AnchorSideTop.Control = Panel2 + AnchorSideLeft.Control = ParamsPanel + AnchorSideTop.Control = ParamsPanel Left = 0 Height = 15 Top = 0 @@ -45,8 +112,7 @@ object CrossTabFrm: TCrossTabFrm end object Label2: TLabel AnchorSideLeft.Control = SelList - AnchorSideTop.Control = Panel2 - Left = 224 + Left = 182 Height = 15 Top = 0 Width = 104 @@ -54,76 +120,74 @@ object CrossTabFrm: TCrossTabFrm ParentColor = False end object VarList: TListBox - AnchorSideLeft.Control = Panel2 + AnchorSideLeft.Control = ParamsPanel AnchorSideTop.Control = Label1 AnchorSideTop.Side = asrBottom AnchorSideRight.Control = InBtn - AnchorSideBottom.Control = Panel2 - AnchorSideBottom.Side = asrBottom + AnchorSideBottom.Control = Bevel2 Left = 0 - Height = 273 + Height = 284 Top = 17 - Width = 180 + Width = 138 Anchors = [akTop, akLeft, akRight, akBottom] BorderSpacing.Top = 2 BorderSpacing.Right = 8 ItemHeight = 0 MultiSelect = True OnSelectionChange = VarListSelectionChange - TabOrder = 0 + TabOrder = 4 end object SelList: TListBox AnchorSideLeft.Control = InBtn AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = Label2 AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = Panel2 + AnchorSideRight.Control = ParamsPanel AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = Panel2 AnchorSideBottom.Side = asrBottom - Left = 224 - Height = 273 + Left = 182 + Height = 281 Top = 17 - Width = 181 + Width = 138 Anchors = [akTop, akLeft, akRight, akBottom] BorderSpacing.Left = 8 BorderSpacing.Top = 2 ItemHeight = 0 MultiSelect = True OnSelectionChange = VarListSelectionChange - TabOrder = 3 + TabOrder = 5 end object InBtn: TBitBtn - AnchorSideLeft.Control = Panel2 + AnchorSideLeft.Control = ParamsPanel AnchorSideLeft.Side = asrCenter AnchorSideBottom.Control = VertCenterBevel - Left = 188 + Left = 146 Height = 28 - Top = 119 + Top = 125 Width = 28 Anchors = [akLeft, akBottom] Images = MainDataModule.ImageList ImageIndex = 1 OnClick = InBtnClick Spacing = 0 - TabOrder = 1 + TabOrder = 6 end object OutBtn: TBitBtn - AnchorSideLeft.Control = Panel2 + AnchorSideLeft.Control = ParamsPanel AnchorSideLeft.Side = asrCenter AnchorSideTop.Control = VertCenterBevel AnchorSideTop.Side = asrBottom AnchorSideBottom.Control = VertCenterBevel AnchorSideBottom.Side = asrBottom - Left = 188 + Left = 146 Height = 28 - Top = 159 + Top = 165 Width = 28 Images = MainDataModule.ImageList ImageIndex = 0 OnClick = OutBtnClick Spacing = 0 - TabOrder = 2 + TabOrder = 7 end object VertCenterBevel: TBevel AnchorSideLeft.Control = InBtn @@ -131,90 +195,36 @@ object CrossTabFrm: TCrossTabFrm AnchorSideTop.Side = asrCenter AnchorSideRight.Control = OutBtn AnchorSideRight.Side = asrBottom - Left = 188 + Left = 146 Height = 12 - Top = 147 + Top = 153 Width = 28 Anchors = [akTop, akLeft, akRight] Shape = bsSpacer end end - object Bevel2: TBevel - AnchorSideLeft.Control = Owner - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = CloseBtn - Left = 0 - Height = 8 - Top = 298 - Width = 421 - Anchors = [akLeft, akRight, akBottom] - Shape = bsBottomLine + object ParamsSplitter: TSplitter[1] + Left = 332 + Height = 358 + Top = 0 + Width = 5 + ResizeStyle = rsPattern end - object CloseBtn: TButton - AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = Owner - AnchorSideBottom.Side = asrBottom - Left = 354 - Height = 25 - Top = 314 - Width = 55 - Anchors = [akRight, akBottom] - AutoSize = True + object PageControl: TPageControl[2] + Left = 341 + Height = 342 + Top = 8 + Width = 530 + ActivePage = ReportPage + Align = alClient + BorderSpacing.Left = 4 BorderSpacing.Top = 8 - BorderSpacing.Right = 12 + BorderSpacing.Right = 8 BorderSpacing.Bottom = 8 - Caption = 'Close' - 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 + TabIndex = 0 TabOrder = 2 - end - object HelpBtn: TButton - AnchorSideTop.Control = CloseBtn - 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 + object ReportPage: TTabSheet + Caption = 'Report' + end end end diff --git a/applications/lazstats/source/forms/analysis/descriptive/crosstabunit.pas b/applications/lazstats/source/forms/analysis/descriptive/crosstabunit.pas index 43798fb91..41cdbb25c 100644 --- a/applications/lazstats/source/forms/analysis/descriptive/crosstabunit.pas +++ b/applications/lazstats/source/forms/analysis/descriptive/crosstabunit.pas @@ -7,39 +7,44 @@ unit CrossTabUnit; interface uses - Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, - StdCtrls, Buttons, ExtCtrls, - Globals, OutputUnit, MainUnit, DataProcs, MatrixLib, ContextHelpUnit; + Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, + StdCtrls, Buttons, ExtCtrls, ComCtrls, + Globals, MainUnit, DataProcs, MatrixLib, ContextHelpUnit, + BasicStatsFormUnit, ReportFrameUnit; type { TCrossTabFrm } - TCrossTabFrm = class(TForm) + TCrossTabFrm = class(TBasicStatsForm) ComputeBtn: TButton; + PageControl: TPageControl; + ParamsPanel: TPanel; + ParamsSplitter: TSplitter; + ReportPage: TTabSheet; VertCenterBevel: TBevel; Bevel2: TBevel; HelpBtn: TButton; InBtn: TBitBtn; OutBtn: TBitBtn; - Panel2: TPanel; ResetBtn: TButton; CloseBtn: TButton; Label1: TLabel; Label2: TLabel; VarList: TListBox; SelList: TListBox; + procedure CloseBtnClick(Sender: TObject); procedure FormActivate(Sender: TObject); procedure FormCreate(Sender: TObject); - procedure FormShow(Sender: TObject); procedure HelpBtnClick(Sender: TObject); procedure InBtnClick(Sender: TObject); procedure ComputeBtnClick(Sender: TObject); procedure OutBtnClick(Sender: TObject); procedure ResetBtnClick(Sender: TObject); - procedure VarListSelectionChange(Sender: TObject; User: boolean); + procedure VarListSelectionChange(Sender: TObject; {%H-}User: boolean); private { private declarations } + FReportFrame: TReportFrame; FAutoSized: Boolean; grandsum, sum, index : integer; no_in_list, length_array, ptr1, ptr2 : integer ; @@ -61,280 +66,24 @@ type public { public declarations } + procedure Reset; override; end; var CrossTabFrm: TCrossTabFrm; + implementation +{$R *.lfm} + uses - Math; + Math, + Utils; + { 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); label 1,2,3,4, printgrid; var @@ -427,6 +176,297 @@ printgrid: MatPrint(outgrid,row-1,Levels[no_in_list-1],title,rowlabels,collabels,NC, AReport); 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; var lSelected: Boolean; @@ -449,16 +489,16 @@ begin break; end; OutBtn.Enabled := lSelected; + + FReportFrame.UpdateBtnStates; end; + procedure TCrossTabFrm.VarListSelectionChange(Sender: TObject; User: boolean); begin UpdateBtnStates; end; -initialization - {$I crosstabunit.lrs} - end.