diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/sigmachartunit.pas b/applications/lazstats/source/forms/analysis/statistical_process_control/sigmachartunit.pas index 094aaa4f2..18f6cedd4 100644 --- a/applications/lazstats/source/forms/analysis/statistical_process_control/sigmachartunit.pas +++ b/applications/lazstats/source/forms/analysis/statistical_process_control/sigmachartunit.pas @@ -132,15 +132,16 @@ const 1.585,1.575,1.566,1.557,1.548,1.541 ); var - i, j, GrpVar, MeasVar, mingrp, maxgrp, G, range, grpsize : integer; - oldgrpsize : integer; - X, UCL, LCL, UpperSpec, LowerSpec, TargetSpec : double; - xmin, xmax, GrandMean, GrandSD, semean, D3Value, D4Value : double; - GrandSigma, C4, gamma, B : double; + i, j, GrpVar, MeasVar, mingrp, maxgrp, G, range, grpsize: integer; + oldgrpsize: integer; + X, UCL, LCL, UpperSpec, LowerSpec, TargetSpec: double; + xmin, xmax, GrandMean, GrandSD, semean: double; + GrandSigma, C4, gamma, B: double; + D3Value, D4Value: Double; means, stddev: DblDyneVec; - count : IntDyneVec; + count: IntDyneVec; cellstring: string; - sizeerror : boolean; + sizeerror: boolean; lReport: TStrings; procedure CleanUp; @@ -234,14 +235,14 @@ begin if oldgrpsize <> grpsize then sizeerror := true; end; - if (grpsize < 2) or (grpsize > 25) or (sizeerror) then + if (grpsize < 2) or (grpsize > 25) or sizeError then begin MessageDlg('Group sizes error.', mtError, [mbOK], 0); CleanUp; exit; end; - semean := semean - ((GrandMean * GrandMean) / NoCases); + semean := semean - sqr(GrandMean)/NoCases; semean := semean / (NoCases - 1); semean := sqrt(semean); GrandSD := semean; diff --git a/applications/lazstats/source/forms/misc/graphlib.pas b/applications/lazstats/source/forms/misc/graphlib.pas index 76547bc67..6209ed4f6 100644 --- a/applications/lazstats/source/forms/misc/graphlib.pas +++ b/applications/lazstats/source/forms/misc/graphlib.pas @@ -639,11 +639,11 @@ begin x4 := x1 + triwidth; yprop := (YPoints[i-1,j-1] - YMin) / (YMax - YMin); ydist := round(yprop * YAxisLength); - y1 := YStart - yoffset - round(ydist); + y1 := YStart - yoffset - ydist; y2 := y1 - triheight; yprop := (YPoints[i-1,j] - YMin) / (YMax - YMin); ydist := round(yprop * YAxisLength); - y3 := ystart - yoffset {%H-}- round(ydist); + y3 := ystart - yoffset - ydist; y4 := y3 - triheight; points[0] := Point(x1,y1); points[1] := Point(x2,y2); diff --git a/applications/lazstats/source/units/dataprocs.pas b/applications/lazstats/source/units/dataprocs.pas index 35446c1e6..5940e9565 100644 --- a/applications/lazstats/source/units/dataprocs.pas +++ b/applications/lazstats/source/units/dataprocs.pas @@ -27,35 +27,34 @@ procedure CopyRow; procedure PasteRow; procedure PrintDict(AReport: TStrings); procedure PrintData(AReport: TStrings); -procedure OpenTabFile; -procedure SaveTabFile; function ValidValue(row, col : integer) : boolean; function IsFiltered(GridRow : integer) : boolean; + procedure MatRead(const a: DblDyneMat; out NoRows, NoCols: integer; const Means, StdDevs: DblDyneVec; out NCases: integer; - const RowLabels, ColLabels: StrDyneVec; const filename: string); -procedure MATSAVE(VAR a : DblDyneMat; - norows : integer; - nocols : integer; - VAR means : DblDyneVec; - VAR stddevs : DblDyneVec; - NCases : integer; - VAR RowLabels : StrDyneVec; - VAR ColLabels : StrDyneVec; - filename : string); -procedure ReOpen(filename : string); + const RowLabels, ColLabels: StrDyneVec; const AFilename: string); +procedure MATSAVE(const a: DblDyneMat; NoRows, NoCols: Integer; + const Means, StdDevs: DblDyneVec; NCases: integer; + const RowLabels, ColLabels: StrDyneVec; AFileName: String); + +procedure ReOpen(AFilename: string); + +procedure OpenTabFile; procedure OpenCommaFile; -procedure SaveCommaFile; procedure OpenSpaceFile; -procedure SaveSpaceFile; procedure OpenOSData; + +procedure SaveTabFile; +procedure SaveCommaFile; +procedure SaveSpaceFile; + procedure ClearGrid; procedure CopyIt; procedure PasteIt; procedure RowColSwap; procedure MatToGrid(const mat: DblDyneMat; nsize: integer); procedure GetTypes; -function StringsToInt(strcol : integer; VAR newcol : integer; prompt : boolean) : boolean; +function StringsToInt(StrCol: integer; var NewCol: integer; Prompt: boolean): boolean; implementation @@ -149,10 +148,9 @@ begin end; //------------------------------------------------------------------- -function IsNumeric(s : string) : boolean; +function IsNumeric(s: string): boolean; var - i, strlong: integer; - isnumber: boolean; + i, strLen: integer; begin (* Assert(OptionsFrm <> nil); @@ -168,14 +166,16 @@ begin end; *) - isnumber := true; - strlong := length(s); - for i := 1 to strlong do + strLen := Length(s); + for i := 1 to strLen do // if (not(((s[i] >= '0') and (s[i] <= '9')) or (s[i] = DecimalSeparator) or - // (s[i] = '-'))) then isnumber := false; - if (ord(s[i]) < 44) or (ord(s[i]) > 57 ) or (ord(s[i]) = 47) then - isnumber := false; - result := isnumber; + // (s[i] = '-'))) then Result := false; + if (s[i] < ',') or (s[i] > '9') or (s[i] = '/') then + begin + Result := false; + exit; + end; + Result := true; end; //----------------------------------------------------------------------------- @@ -219,15 +219,16 @@ end; procedure SaveOS2File; var - F: TextFile; - filename: string; - s: string; - NRows, NCols: integer; - i, j: integer; + F: TextFile; + filename: string; + s: string; + NRows, NCols: integer; + i, j: integer; begin // check for valid cases - at least one value entered NRows := StrToInt(OS3MainFrm.NoCasesEdit.Text); NCols := StrToInt(OS3MainFrm.NoVarsEdit.Text); + if (NRows = 0) or (NCols = 0) then begin MessageDlg('No data to save.', mtError, [mbOK], 0); @@ -260,10 +261,6 @@ begin Writeln(F, s); end; end; -{ MemLines := DictionaryFrm.DescMemo.Lines.Count; - Writeln(F,MemLines); - for i := 0 to MemLines - 1 do - Writeln(F,DictionaryFrm.DescMemo.Lines[i]); } // now save grid cell values, incl col and row headers. for i := 0 to NRows do @@ -343,15 +340,6 @@ begin end; DictLoaded := true; -{ Readln(F, s); - MemLines := StrToInt(s); - DictionaryFrm.DescMemo.Clear; - for i := 0 to MemLines - 1 do - begin - readln(F, s); - DictionaryFrm.DescMemo.Lines.Add(s); - end; } - // Now read grid data OS3MainFrm.DataGrid.RowCount := NRows + 1; OS3MainFrm.DataGrid.ColCount := NCols + 1; @@ -417,12 +405,12 @@ end; procedure CopyColumn; var - col: integer; - buf : pchar; + col: integer; + buf: pchar; begin - col := OS3MainFrm.DataGrid.Col; - buf := OS3MainFrm.DataGrid.Cols[col].GetText; - ClipBoard.SetTextBuf(buf); + col := OS3MainFrm.DataGrid.Col; + buf := OS3MainFrm.DataGrid.Cols[col].GetText; + ClipBoard.SetTextBuf(buf); // The following code can be used instead of the above if no clipboard available // TempStream.Clear; // OS3MainFrm.DataGrid.Cols[col].SaveToStream(TempStream); @@ -432,61 +420,46 @@ end; procedure InsertCol; var - i, j, col: integer; + i, j, col: integer; begin - // insert a new, blank column into the data grid - col := OS3MainFrm.DataGrid.Col; -// DictionaryFrm.NewVar(col); - NoVariables := NoVariables + 1; - OS3MainFrm.DataGrid.ColCount := NoVariables + 1; - for i := NoVariables downto col do { move to right } - begin - for j := 0 to NoCases do - begin - OS3MainFrm.DataGrid.Cells[i,j] := OS3MainFrm.DataGrid.Cells[i-1,j]; - end; - end; - NoVariables := NoVariables - 1; - DictionaryFrm.NewVar(col); - for i := 1 to NoCases do OS3MainFrm.DataGrid.Cells[col,i] := ''; - OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables); + // insert a new, blank column into the data grid + col := OS3MainFrm.DataGrid.Col; + NoVariables := NoVariables + 1; + OS3MainFrm.DataGrid.ColCount := NoVariables + 1; + for i := NoVariables downto col do { move to right } + for j := 0 to NoCases do + OS3MainFrm.DataGrid.Cells[i,j] := OS3MainFrm.DataGrid.Cells[i-1,j]; + NoVariables := NoVariables - 1; + + DictionaryFrm.NewVar(col); + + for i := 1 to NoCases do OS3MainFrm.DataGrid.Cells[col,i] := ''; + OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables); end; -//------------------------------------------------------------------- procedure PasteColumn; var col, i, j: integer; - //buf: pchar; - //size: integer; s: String; - //strarray : array[0..100000] of char; // wp: Wow! What's this? begin - col := OS3MainFrm.DataGrid.Col; - NoVariables := OS3MainFrm.DataGrid.ColCount-1; - NoCases := OS3MainFrm.DataGrid.RowCount - 1; - if col <= NoVariables then - begin // add a blank column, move current over and update dictionary - OS3MainFrm.DataGrid.ColCount := OS3MainFrm.DataGrid.ColCount + 1; - for i := NoVariables downto col do - for j := 0 to NoCases do - OS3MainFrm.DataGrid.Cells[i+1,j] := OS3MainFrm.DataGrid.Cells[i,j]; - DictionaryFrm.NewVar(col); - VarDefined[col] := true; - OS3MainFrm.ColEdit.Text := IntToStr(OS3MainFrm.DataGrid.ColCount-1); -// NoVariables := NoVariables + 1; - OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables); - end; + col := OS3MainFrm.DataGrid.Col; + NoVariables := OS3MainFrm.DataGrid.ColCount-1; + NoCases := OS3MainFrm.DataGrid.RowCount - 1; + if col <= NoVariables then + begin // add a blank column, move current over and update dictionary + OS3MainFrm.DataGrid.ColCount := OS3MainFrm.DataGrid.ColCount + 1; + for i := NoVariables downto col do + for j := 0 to NoCases do + OS3MainFrm.DataGrid.Cells[i+1,j] := OS3MainFrm.DataGrid.Cells[i,j]; + DictionaryFrm.NewVar(col); + VarDefined[col] := true; + OS3MainFrm.ColEdit.Text := IntToStr(OS3MainFrm.DataGrid.ColCount-1); + OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables); + end; - s := Clipboard.AsText; - OS3MainFrm.DataGrid.Cols[col].Text := s; - { - buf := strarray; // wp: Is this needed? - size := 100000; - ClipBoard.GetTextBuf(buf,size); - OS3MainFrm.DataGrid.Cols[col].SetText(buf); - } + s := Clipboard.AsText; + OS3MainFrm.DataGrid.Cols[col].Text := s; end; -//------------------------------------------------------------------- procedure CutRow; var @@ -497,24 +470,24 @@ begin buf := OS3MainFrm.DataGrid.Rows[row].GetText; ClipBoard.SetTextBuf(buf); - for i := 1 to NoVariables do - OS3MainFrm.DataGrid.Cells[i,row] := ''; - if row < NoCases then - begin // move rows below up 1 - for i := row + 1 to NoCases do - for j := 1 to NoVariables do OS3MainFrm.DataGrid.Cells[j,i-1] := OS3MainFrm.DataGrid.Cells[j,i]; - for j := 1 to NoVariables do OS3MainFrm.DataGrid.Cells[j,NoCases] := ''; - end; + for i := 1 to NoVariables do + OS3MainFrm.DataGrid.Cells[i,row] := ''; - OS3MainFrm.DataGrid.RowCount := OS3MainFrm.DataGrid.RowCount - 1; - OS3MainFrm.RowEdit.Text := IntToStr(OS3MainFrm.DataGrid.RowCount-1); - NoCases := NoCases - 1; - OS3MainFrm.NoCasesEdit.Text := IntToStr(NoCases); + if row < NoCases then + begin // move rows below up 1 + for i := row + 1 to NoCases do + for j := 1 to NoVariables do OS3MainFrm.DataGrid.Cells[j, i-1] := OS3MainFrm.DataGrid.Cells[j, i]; + for j := 1 to NoVariables do OS3MainFrm.DataGrid.Cells[j, NoCases] := ''; + end; - // renumber cases - for i := 1 to NoCases do OS3MainFrm.DataGrid.Cells[0,i] := 'CASE ' + IntToStr(i); + OS3MainFrm.DataGrid.RowCount := OS3MainFrm.DataGrid.RowCount - 1; + OS3MainFrm.RowEdit.Text := IntToStr(OS3MainFrm.DataGrid.RowCount-1); + NoCases := NoCases - 1; + OS3MainFrm.NoCasesEdit.Text := IntToStr(NoCases); + + // renumber cases + for i := 1 to NoCases do OS3MainFrm.DataGrid.Cells[0,i] := 'CASE ' + IntToStr(i); end; -//------------------------------------------------------------------- procedure CopyRow; var @@ -524,19 +497,11 @@ begin row := OS3MainFrm.DataGrid.Row; buf := OS3MainFrm.DataGrid.Rows[row].GetText; ClipBoard.SetTextBuf(buf); -// TempStream.Clear; -// OS3MainFrm.DataGrid.Rows[row].SaveToStream(TempStream); end; -//------------------------------------------------------------------- procedure PasteRow; var row, i, j: integer; - { - buf: pchar; - strarray: array[0..100000] of char; // wp: Like above - size: integer; } - begin row := OS3MainFrm.DataGrid.Row; OS3MainFrm.DataGrid.RowCount := OS3MainFrm.DataGrid.RowCount + 1; @@ -549,24 +514,17 @@ begin end; OS3MainFrm.DataGrid.Row := row; OS3MainFrm.DataGrid.Rows[row].Text := Clipboard.AsText; - - { - buf := strarray; // wp: is this needed? - size := 100000; - ClipBoard.GetTextBuf(buf,size); - OS3MainFrm.DataGrid.Rows[row].SetText(buf); - } -// Use the following instead of the previous 4 if clipboard is unavailable +// Use the following instead of the previous if clipboard is unavailable // TempStream.Position := 0; // OS3MainFrm.DataGrid.Rows[row].LoadFromStream(TempStream); - NoCases := NoCases + 1; - OS3MainFrm.NoCasesEdit.Text := IntToStr(NoCases); + NoCases := NoCases + 1; + OS3MainFrm.NoCasesEdit.Text := IntToStr(NoCases); // renumber cases - for i := 1 to NoCases do OS3MainFrm.DataGrid.Cells[0,i] := 'CASE ' + IntToStr(i); + for i := 1 to NoCases do + OS3MainFrm.DataGrid.Cells[0,i] := 'CASE ' + IntToStr(i); end; -//------------------------------------------------------------------- procedure PrintDict(AReport: TStrings); var @@ -579,18 +537,17 @@ begin for i:= 0 to NoVariables do begin outline := ''; - outline := outline + '| ' + Format('%9s',[DictionaryFrm.DictGrid.Cells[0,i]]); - outline := outline + ' | ' + Format('%10s',[DictionaryFrm.DictGrid.Cells[1,i]]); - outline := outline + ' | ' + Format('%15s',[DictionaryFrm.DictGrid.Cells[2,i]]); - outline := outline + ' | ' + Format('%6s',[DictionaryFrm.DictGrid.Cells[3,i]]); - outline := outline + ' | ' + Format('%6s',[DictionaryFrm.DictGrid.Cells[4,i]]); - outline := outline + ' | ' + Format('%8s',[DictionaryFrm.DictGrid.Cells[5,i]]); - outline := outline + ' | ' + Format('%7s',[DictionaryFrm.DictGrid.Cells[6,i]]); - outline := outline + ' | ' + Format('%6s',[DictionaryFrm.DictGrid.Cells[7,i]]); + outline := outline + '| ' + Format( '%9s', [DictionaryFrm.DictGrid.Cells[0, i]]); + outline := outline + ' | ' + Format('%10s', [DictionaryFrm.DictGrid.Cells[1, i]]); + outline := outline + ' | ' + Format('%15s', [DictionaryFrm.DictGrid.Cells[2, i]]); + outline := outline + ' | ' + Format( '%6s', [DictionaryFrm.DictGrid.Cells[3, i]]); + outline := outline + ' | ' + Format( '%6s', [DictionaryFrm.DictGrid.Cells[4, i]]); + outline := outline + ' | ' + Format( '%8s', [DictionaryFrm.DictGrid.Cells[5, i]]); + outline := outline + ' | ' + Format( '%7s', [DictionaryFrm.DictGrid.Cells[6, i]]); + outline := outline + ' | ' + Format( '%6s', [DictionaryFrm.DictGrid.Cells[7, i]]); AReport.Add(outline); end; end; -//------------------------------------------------------------------- procedure PrintData(AReport: TStrings); var @@ -602,11 +559,7 @@ var begin AReport.Add(OS3MainFrm.FileNameEdit.Text); - outline := IntToStr(NoCases); - outline := 'No. of Cases = ' + outline; - outline := outline + ', No. of Variables = '; - outline := outline + IntToStr(NoVariables); - AReport.Add(outline); + AReport.Add('Number of Cases: %d, Number of Variables: %d', [NoCases, NoVariables]); AReport.Add(''); done := false; @@ -619,7 +572,7 @@ begin for i:= 0 to NoCases do begin outline := ''; - outline := Format('%10s',[Trim(OS3MainFrm.DataGrid.Cells[0,i])]); + outline := Format('%10s', [Trim(OS3MainFrm.DataGrid.Cells[0,i])]); for j := startcol to endcol do outline := outline + Format('%10s', [Trim(OS3MainFrm.DataGrid.Cells[j,i])]); AReport.Add(outline); @@ -629,13 +582,152 @@ begin done := true else begin - startcol := endcol+1; + startcol := endcol + 1; AReport.Add(''); end; end; end; -//------------------------------------------------------------------- +procedure OpenSeparatorFile(ASeparator: Char; AFilter, ADefaultExt: String); +var + F: TextFile; + s: string; + ch: char; + labelsInc: boolean; + row, col: integer; + res: TModalResult; +begin + Assert(OS3MainFrm <> nil); + Assert(OptionsFrm <> nil); + + labelsInc := false; + + // check for a currently open file + if NoVariables > 1 then + begin + MessageDlg('Close (or Save and Close) the current work.', mtWarning, [mbOK], 0); + exit; + end; + + with OS3MainFrm.OpenDialog1 do + begin + Filter := AFilter; + FilterIndex := 1; + DefaultExt := ADefaultExt; + if FileName <> '' then + begin + InitialDir := ExtractFileDir(FileName); + FileName := ChangeFileExt(FileName, ADefaultExt); + end; + end; + if OS3MainFrm.OpenDialog1.Execute then + begin + res := MessageDlg('Are variable labels included?', mtConfirmation, [mbYes, mbNo, mbCancel], 0); + if res = mrCancel then + exit; + labelsInc := (res = mrYes); + NoCases := 0; + NoVariables := 0; + if labelsInc then row := 0 else row := 1; + col := 1; + + AssignFile(F, OS3MainFrm.OpenDialog1.FileName); { File selected in dialog box } + Reset(F); + OS3MainFrm.FileNameEdit.Text := OS3MainFrm.OpenDialog1.FileName; + + s := ''; + while not EOF(F) do + begin + Read(F, ch); + if (ch < #9) or (ch > #127) then + Continue; + if (ch = #13) then + Continue; // line feed character + if (ch <> ASeparator) and (ch <> #10) then // check for Separator or new line + s := s + ch + else if ch = ASeparator then // Separator character found + begin + if (not labelsInc) and (row = 1) then // create a column label + OS3MainFrm.DataGrid.Cells[col, 0] := 'VAR ' + IntToStr(col); + OS3MainFrm.DataGrid.Cells[col, row] := s; + if col > NoVariables then + begin + NoVariables := col; + OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables); + end; + col := col + 1; + s := ''; + if col >= OS3MainFrm.DataGrid.ColCount then + OS3MainFrm.DataGrid.ColCount := OS3MainFrm.DataGrid.ColCount + 1; + end + else //must be new line character + begin + if (not labelsInc) and (row = 1) then // create a col. label + OS3MainFrm.DataGrid.Cells[col, 0] := 'VAR ' + IntToStr(col); + OS3MainFrm.DataGrid.Cells[col, row] := s; + s := ''; + if col > NoVariables then + begin + NoVariables := col; + OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables); + end; + col := 1; + if row > NoCases then NoCases := row; + OS3MainFrm.DataGrid.Cells[0, row] := 'Case ' + IntToStr(row); + row := row + 1; + if row >= OS3MainFrm.DataGrid.RowCount then + OS3MainFrm.DataGrid.RowCount := OS3MainFrm.DataGrid.RowCount + 1; + end; + end; // END OF FILE + + CloseFile(F); + + OS3MainFrm.NoCasesEdit.Text := IntToStr(NoCases); + OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables); + if NoVariables >= OS3MainFrm.DataGrid.ColCount - 1 then + OS3MainFrm.DataGrid.ColCount := OS3MainFrm.DataGrid.ColCount + 1; + + // set up the dictionary + DictionaryFrm.DictGrid.RowCount := NoVariables + 1; + DictionaryFrm.DictGrid.ColCount := 8; + for row := 1 to NoVariables do + begin + DictionaryFrm.DictGrid.Cells[0,row] := IntToStr(row); + DictionaryFrm.DictGrid.Cells[1,row] := 'VAR.' + IntToStr(row); + DictionaryFrm.DictGrid.Cells[2,row] := 'VARIABLE ' + IntToStr(row); + DictionaryFrm.DictGrid.Cells[3,row] := '8'; + DictionaryFrm.DictGrid.Cells[4,row] := 'F'; + DictionaryFrm.DictGrid.Cells[5,row] := '2'; + DictionaryFrm.DictGrid.Cells[6,row] := MissingValueCodes[Options.DefaultMiss]; + DictionaryFrm.DictGrid.Cells[7,row] := 'L'; + end; + for row := 1 to NoVariables do + begin + DictionaryFrm.DictGrid.Cells[1,row] := OS3MainFrm.DataGrid.Cells[row,0]; + VarDefined[row] := true; + end; + OS3MainFrm.DataGrid.RowCount := (NoCases + 1); + OS3MainFrm.DataGrid.ColCount := (NoVariables + 1); + end; + GetTypes; +end; + +procedure OpenTabFile; +begin + OpenSeparatorFile(#9, TAB_FILE_FILTER, 'tab'); +end; + +procedure OpenCommaFile; +begin + OpenSeparatorFile(',', CSV_FILE_FILTER, 'csv'); +end; + +procedure OpenSpacefile; +begin + OpenSeparatorfile(' ', SSV_FILE_FILTER, 'ssv'); +end; + +{ procedure OpenTabFile; var TabFile : TextFile; @@ -669,9 +761,10 @@ begin labelsInc := (res = mrYes); NoCases := 0; NoVariables := 0; - if labelsinc = true then row := 0 else row := 1; + if labelsInc then row := 0 else row := 1; col := 1; - AssignFile(TabFile, OS3MainFrm.OpenDialog1.FileName); { File selected in dialog box } + + AssignFile(TabFile, OS3MainFrm.OpenDialog1.FileName); // File selected in dialog box Reset(tabfile); OS3MainFrm.FileNameEdit.Text := OS3MainFrm.OpenDialog1.FileName; s := ''; @@ -689,9 +782,9 @@ begin if (not labelsinc) and (row = 1) then // create a col. label begin namestr := 'VAR ' + IntToStr(col); - OS3MainFrm.DataGrid.Cells[col,0] := namestr; + OS3MainFrm.DataGrid.Cells[col, 0] := namestr; end; - OS3MainFrm.DataGrid.Cells[col,row] := s; + OS3MainFrm.DataGrid.Cells[col, row] := s; if col > NoVariables then begin NoVariables := col; @@ -724,11 +817,13 @@ begin OS3MainFrm.DataGrid.RowCount := OS3MainFrm.DataGrid.RowCount + 1; end; end; // END OF FILE + OS3MainFrm.NoCasesEdit.Text := IntToStr(NoCases); OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables); CloseFile(TabFile); if NoVariables >= OS3MainFrm.DataGrid.ColCount - 1 then OS3MainFrm.DataGrid.ColCount := OS3MainFrm.DataGrid.ColCount + 1; + // set up the dictionary DictionaryFrm.DictGrid.RowCount := NoVariables + 1; DictionaryFrm.DictGrid.ColCount := 8; @@ -753,8 +848,62 @@ begin end; GetTypes; end; -//------------------------------------------------------------------- +} +procedure SaveSeparatorFile(ASeparator: Char; AFilter, ADefaultExt: String); +var + namestr: string; + cellvalue: string; + F: TextFile; + i, j: integer; +begin + with OS3MainFrm.SaveDialog1 do begin + Filter := AFilter; + FilterIndex := 1; + DefaultExt := ADefaultExt; + if FileName <> '' then + begin + InitialDir := ExtractFileDir(FileName); + FileName := ChangeFileExt(FileName, ADefaultExt); + end; + end; + if OS3MainFrm.SaveDialog1.Execute then + begin + namestr := OS3MainFrm.SaveDialog1.FileName; + Assign(F, namestr); + ReWrite(F); + for i := 0 to NoCases do // wp: why not NoCases-1 ? + begin + for j := 1 to NoVariables do //write all but last with a tab + begin + cellvalue := OS3MainFrm.DataGrid.Cells[j, i]; + if cellvalue = '' then cellvalue := '.'; // wp: why not "missing value"? + cellvalue := Trim(cellvalue); // wp: why not before prev line? + if j < NoVariables then cellvalue := cellvalue + ASeparator; + Write(F, cellvalue); + end; + WriteLn(F); + end; + end; + CloseFile(F); +end; + +procedure SaveTabFile; +begin + SaveSeparatorFile(#9, TAB_FILE_FILTER, 'tab'); +end; + +procedure SaveCommaFile; +begin + SaveSeparatorFile(',', CSV_FILE_FILTER, 'csv'); +end; + +procedure SaveSpaceFile; +begin + SaveSeparatorFile(' ', SSV_FILE_FILTER, 'ssv'); +end; + +{ procedure SaveTabFile; var namestr: string; @@ -762,7 +911,7 @@ var TabFile: TextFile; i, j: integer; begin - OS3MainFrm.SaveDialog1.Filter := 'Tab field files (*.tab)|*.tab;*.TAB|Text files (*.txt)|*.txt;*.TXT|All files (*.*)|*.*'; + OS3MainFrm.SaveDialog1.Filter := TAB_FILE_FILTER; OS3MainFrm.SaveDialog1.FilterIndex := 1; OS3MainFrm.SaveDialog1.DefaultExt := 'tab'; if OS3MainFrm.SaveDialog1.Execute then @@ -785,239 +934,239 @@ begin end; CloseFile(TabFile); end; -//------------------------------------------------------------------- +} function ValidValue(row, col : integer) : boolean; var - valid: boolean; - xvalue: string; - cellstring : string; - + valid: boolean; + xvalue: string; + cellstring: string; begin - valid := true; - if FilterOn = true then - begin - cellstring := Trim(OS3MainFrm.DataGrid.Cells[FilterCol,row]); - if cellstring = 'NO' then valid := false; - ValidValue := valid; - exit; - end; - xvalue := Trim(OS3MainFrm.DataGrid.Cells[col,row]); - if (xvalue = '') and (DictionaryFrm.DictGrid.Cells[4,col] <> 'S') - then valid := false; - if valid then // check for user-defined missing value - begin - if Trim(DictionaryFrm.DictGrid.Cells[6,col]) = xvalue then - valid := false; - end; - ValidValue := valid; + valid := true; + if FilterOn then + begin + cellstring := Trim(OS3MainFrm.DataGrid.Cells[FilterCol, row]); + if cellstring = 'NO' then valid := false; + Result := valid; + exit; + end; + + xvalue := Trim(OS3MainFrm.DataGrid.Cells[col,row]); + if (xvalue = '') and (DictionaryFrm.DictGrid.Cells[4,col] <> 'S') then + valid := false; + if valid then // check for user-defined missing value + begin + if Trim(DictionaryFrm.DictGrid.Cells[6,col]) = xvalue then + valid := false; + end; + Result := valid; end; -//----------------------------------------------------------------------------- -function IsFiltered(GridRow : integer) : boolean; +function IsFiltered(GridRow: integer): boolean; begin - if (FilterOn = true) and (Trim(OS3MainFrm.DataGrid.Cells[FilterCol,GridRow]) = 'NO') then - IsFiltered := true else IsFiltered := false; + Result := FilterOn and (Trim(OS3MainFrm.DataGrid.Cells[FilterCol,GridRow]) = 'NO'); end; -//------------------------------------------------------------------- -procedure MATREAD(const a: DblDyneMat; - out NoRows, NoCols: integer; - const means, stddevs: DblDyneVec; - out NCases: integer; - const RowLabels, ColLabels: StrDyneVec; - const filename: string); -var i, j : integer; - mat_file : TextFile; +procedure MatRead(const a: DblDyneMat; out NoRows, NoCols: integer; + const means, stddevs: DblDyneVec; out NCases: integer; + const RowLabels, ColLabels: StrDyneVec; const AFileName: string); +var + i, j: integer; + mat_file: TextFile; begin - assign(mat_file,filename); - reset(mat_file); - readln(mat_file,norows); - readln(mat_file,nocols); - readln(mat_file,NCases); + Assign(mat_file, AFileName); + Reset(mat_file); + ReadLn(mat_file, norows); + ReadLn(mat_file, nocols); + ReadLn(mat_file, NCases); - // wp: Setlength missing here --> very critical !!!! - // I understand that the calling routine pre-allocates these arrays - // But there should be a check whehter Norows, etc do not go beyond array size. + // wp: Setlength missing here --> very critical !!!! + // I understand that the calling routine pre-allocates these arrays + // But there should be a check whether NoRows, etc do not go beyond array size. - for i := 1 to norows do readln(mat_file,RowLabels[i-1]); - for i := 1 to nocols do readln(mat_file,ColLabels[i-1]); - for i := 1 to nocols do readln(mat_file,means[i-1]); - for i := 1 to nocols do readln(mat_file,stddevs[i-1]); - for i := 1 to norows do - for j := 1 to nocols do - readln(mat_file,a[i-1,j-1]); - CloseFile(mat_file); + for i := 1 to norows do ReadLn(mat_file, RowLabels[i-1]); + for i := 1 to nocols do ReadLn(mat_file, ColLabels[i-1]); + for i := 1 to nocols do ReadLn(mat_file, means[i-1]); + for i := 1 to nocols do ReadLn(mat_file, stddevs[i-1]); + for i := 1 to norows do + for j := 1 to nocols do + ReadLn(mat_file, a[i-1, j-1]); + + CloseFile(mat_file); end; { matrix read routine } -//------------------------------------------------------------------- -procedure MATSAVE(VAR a : DblDyneMat; - norows : integer; - nocols : integer; - VAR means : DblDyneVec; - VAR stddevs : DblDyneVec; - NCases : integer; - VAR RowLabels : StrDyneVec; - VAR ColLabels : StrDyneVec; - filename : string); -var i, j : integer; - mat_file : TextFile; +procedure MatSave(const a: DblDyneMat; NoRows, NoCols: integer; + const Means, StdDevs: DblDyneVec; NCases: integer; + const RowLabels, ColLabels: StrDyneVec; AFileName: String); +var + i, j: integer; + mat_file: TextFile; begin - assign(mat_file,filename); - rewrite(mat_file); - writeln(mat_file,norows); - writeln(mat_file,nocols); - writeln(mat_file,NCases); - for i := 1 to norows do writeln(mat_file,RowLabels[i-1]); - for i := 1 to nocols do writeln(mat_file,ColLabels[i-1]); - for i := 1 to nocols do writeln(mat_file,means[i-1]); - for i := 1 to nocols do writeln(mat_file,stddevs[i-1]); - for i := 1 to norows do - for j := 1 to nocols do - writeln(mat_file,a[i-1,j-1]); - CloseFile(mat_file); + Assign(mat_file, AFilename); + Rewrite(mat_file); + + WriteLn(mat_file, NoRows); + WriteLn(mat_file, NoCols); + WriteLn(mat_file, NCases); + + for i := 1 to NoRows do WriteLn(mat_file, RowLabels[i-1]); + for i := 1 to NoCols do WriteLn(mat_file, ColLabels[i-1]); + for i := 1 to NoCols do WriteLn(mat_file, Means[i-1]); + for i := 1 to NoCols do WriteLn(mat_file, StdDevs[i-1]); + for i := 1 to NoRows do + for j := 1 to NoCols do + WriteLn(mat_file, a[i-1, j-1]); + + CloseFile(mat_file); end; { matrix save routine } -//------------------------------------------------------------------- -procedure ReOpen(filename : string); +procedure ReOpen(AFilename: string); var - fileext : string; - + fileExt: string; begin - DictLoaded := false; + DictLoaded := false; - if FileExists(filename) then - begin - fileext := Uppercase(ExtractFileExt(filename)); - OS3MainFrm.FileNameEdit.Text := filename; - OS3MainFrm.OpenDialog1.FileName := filename; - if fileext = '.CSV' then OpenCommaFile - else if fileext = '.TAB' then OpenTabFile - else if fileext = '.LAZ' then OpenOS2File - else if fileext = '.SSV' then OpenSpaceFile; - end - else begin - MessageDlg(filename + ' not found.', mtError, [mbOK], 0); - exit; + if FileExists(AFilename) then + begin + fileExt := Lowercase(ExtractFileExt(AFilename)); + OS3MainFrm.FileNameEdit.Text := AFilename; + OS3MainFrm.OpenDialog1.FileName := AFilename; + case fileExt of + '.csv': OpenCommaFile; + '.tab': OpenTabFile; + '.laz': OpenOS2File; + '.ssv': OpenSpaceFile; end; + end else + MessageDlg(Format('File "%s" not found.', [AFileName]), mtError, [mbOK], 0); end; -//------------------------------------------------------------------- + { procedure OpenCommaFile; -label getit; +const + COMMA = ','; var - CommaFile : TextFile; - namestr : string; - astr : string; - achar : char; - respval : string; - labelsinc : boolean; - row, col : integer; - commachar : integer; + CommaFile: TextFile; + namestr: string; + s: string; + ch: char; + labelsinc: boolean; + row, col: integer; + res: TModalResult; begin - commachar := ord(','); - labelsinc := false; - // check for a currently open file - if NoVariables > 1 then + Assert(OS3MainFrm <> nil); + Assert(OptionsFrm <> nil); + + labelsInc := false; + + // check for a currently open file + if NoVariables > 1 then + begin + MessageDlg('Close (or Save and Close) the current work.', mtError, [mbOK], 0); + exit; + end; + + OS3MainFrm.OpenDialog1.Filter := 'Comma field files (*.csv)|*.csv;*.CSV|Text files (*.txt)|*.txt;*.TXT|All files (*.*)|*.*'; + OS3MainFrm.OpenDialog1.FilterIndex := 1; + OS3MainFrm.OpenDialog1.DefaultExt := 'csv'; + if OS3MainForm.OpenDialog1.Execute then + begin + res := MessageDlg('Are variable labels included?', mtConfirmation, [mbYes, mbNo, mbCancel], 0); + if res = mrCancel then + exit; + labelsInc := (res = mrYes); + + NoCases := 0; + NoVariables := 0; + if labelsInc then row := 0 else row := 1; + col := 1; + + AssignFile(CommaFile, OS3MainFrm.OpenDialog1.FileName); // File selected in dialog box + Reset(CommaFile); + OS3MainFrm.FileNameEdit.Text := OS3MainFrm.OpenDialog1.FileName; + s := ''; + while not EOF(CommaFile) do begin - ShowMessage('WARNING! Close (or Save and Close) the current work.'); - exit; - end; - respval := InputBox('LABELS?','Are variable labels included?','Y'); - if respval = 'Y' then labelsinc := true; - OS3MainFrm.OpenDialog1.Filter := 'Comma field files (*.CSV)|*.CSV|Text files (*.txt)|*.TXT|All files (*.*)|*.*'; - OS3MainFrm.OpenDialog1.FilterIndex := 1; - OS3MainFrm.OpenDialog1.DefaultExt := 'CSV'; - if OS3MainFrm.OpenDialog1.Execute then - begin - NoCases := 0; - NoVariables := 0; - if labelsinc = true then row := 0 else row := 1; - col := 1; - AssignFile(CommaFile, OS3MainFrm.OpenDialog1.FileName); { File selected in dialog box } - Reset(CommaFile); - OS3MainFrm.FileNameEdit.Text := OS3MainFrm.OpenDialog1.FileName; - astr := ''; - while not EOF(CommaFile) do + Read(CommaFile, ch); + if (ch < #9) or (ch > #127) then + Continue; + if (ch = #13 then // line feed character + Continue; + if (ch <> COMMA) and (ch <> #10) then // check for tab or new line + s := s + ch + else if ch = COMMA then // Comma found + begin + if (not labelsInc) and (row = 1) then // create a col. label begin -getit: read(CommaFile,achar); - if (ord(achar) < 9) or (ord(achar) > 127) then goto getit; - if ord(achar) = 13 then goto getit; // line feed character - if (ord(achar) <> commachar) and (ord(achar) <> 10) then // check for tab or new line - begin - astr := astr + achar; - end - else if ord(achar) = commachar then // tab character found - begin - if (not labelsinc) and (row = 1) then // create a col. label - begin - namestr := 'VAR ' + IntToStr(col); - OS3MainFrm.DataGrid.Cells[col,0] := namestr; - end; - OS3MainFrm.DataGrid.Cells[col,row] := astr; - if col > NoVariables then - begin - NoVariables := col; - OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables); - end; - col := col + 1; - astr := ''; - if col >= OS3MainFrm.DataGrid.ColCount then - OS3MainFrm.DataGrid.ColCount := OS3MainFrm.DataGrid.ColCount + 1; - end - else //must be new line character - begin - if (not labelsinc) and (row = 1) then // create a col. label - begin - namestr := 'VAR ' + IntToStr(col); - OS3MainFrm.DataGrid.Cells[col,0] := namestr; - end; - OS3MainFrm.DataGrid.Cells[col,row] := astr; - astr := ''; - if col > NoVariables then - begin - NoVariables := col; - OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables); - end; - col := 1; - if row > NoCases then NoCases := row; - OS3MainFrm.DataGrid.Cells[0,row] := 'Case ' + IntToStr(row); - row := row + 1; - if row >= OS3MainFrm.DataGrid.RowCount then - OS3MainFrm.DataGrid.RowCount := OS3MainFrm.DataGrid.RowCount + 1; - end; - end; // END OF FILE - OS3MainFrm.NoCasesEdit.Text := IntToStr(NoCases); - OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables); - CloseFile(CommaFile); - if NoVariables > OS3MainFrm.DataGrid.ColCount - 1 then - OS3MainFrm.DataGrid.ColCount := OS3MainFrm.DataGrid.ColCount + 1; - end; - OS3MainFrm.DataGrid.RowCount := (NoCases + 1); - OS3MainFrm.DataGrid.ColCount := (NoVariables + 1); + namestr := 'VAR ' + IntToStr(col); + OS3MainFrm.DataGrid.Cells[col, 0] := namestr; + end; + OS3MainFrm.DataGrid.Cells[col, row] := astr; + if col > NoVariables then + begin + NoVariables := col; + OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables); + end; + col := col + 1; + s := ''; + if col >= OS3MainFrm.DataGrid.ColCount then + OS3MainFrm.DataGrid.ColCount := OS3MainFrm.DataGrid.ColCount + 1; + end + else //must be new line character + begin + if (not labelsInc) and (row = 1) then // create a col. label + begin + namestr := 'VAR ' + IntToStr(col); + OS3MainFrm.DataGrid.Cells[col, 0] := namestr; + end; + OS3MainFrm.DataGrid.Cells[col, row] := s; + s := ''; + if col > NoVariables then + begin + NoVariables := col; + OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables); + end; + col := 1; + if row > NoCases then NoCases := row; + OS3MainFrm.DataGrid.Cells[0, row] := 'Case ' + IntToStr(row); + row := row + 1; + if row >= OS3MainFrm.DataGrid.RowCount then + OS3MainFrm.DataGrid.RowCount := OS3MainFrm.DataGrid.RowCount + 1; + end; + end; // END OF FILE + + OS3MainFrm.NoCasesEdit.Text := IntToStr(NoCases); + OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables); + CloseFile(CommaFile); + if NoVariables > OS3MainFrm.DataGrid.ColCount - 1 then + OS3MainFrm.DataGrid.ColCount := OS3MainFrm.DataGrid.ColCount + 1; + // set up the dictionary DictionaryFrm.DictGrid.RowCount := NoVariables + 1; DictionaryFrm.DictGrid.ColCount := 8; for row := 1 to NoVariables do begin - DictionaryFrm.DictGrid.Cells[0,row] := IntToStr(row); - DictionaryFrm.DictGrid.Cells[1,row] := 'VAR.' + IntToStr(row); - DictionaryFrm.DictGrid.Cells[2,row] := 'VARIABLE ' + IntToStr(row); - DictionaryFrm.DictGrid.Cells[3,row] := '8'; - DictionaryFrm.DictGrid.Cells[4,row] := 'F'; - DictionaryFrm.DictGrid.Cells[5,row] := '2'; - DictionaryFrm.DictGrid.Cells[6,row] := MissingValueCodes[Options.DefaultMiss]; - DictionaryFrm.DictGrid.Cells[7,row] := 'L'; + DictionaryFrm.DictGrid.Cells[0,row] := IntToStr(row); + DictionaryFrm.DictGrid.Cells[1,row] := 'VAR.' + IntToStr(row); + DictionaryFrm.DictGrid.Cells[2,row] := 'VARIABLE ' + IntToStr(row); + DictionaryFrm.DictGrid.Cells[3,row] := '8'; + DictionaryFrm.DictGrid.Cells[4,row] := 'F'; + DictionaryFrm.DictGrid.Cells[5,row] := '2'; + DictionaryFrm.DictGrid.Cells[6,row] := MissingValueCodes[Options.DefaultMiss]; + DictionaryFrm.DictGrid.Cells[7,row] := 'L'; end; for row := 1 to NoVariables do begin - DictionaryFrm.DictGrid.Cells[1,row] := OS3MainFrm.DataGrid.Cells[row,0]; - VarDefined[row] := true; + DictionaryFrm.DictGrid.Cells[1,row] := OS3MainFrm.DataGrid.Cells[row,0]; + VarDefined[row] := true; end; - GetTypes; + OS3MainFrm.DataGrid.RowCount := (NoCases + 1); + OS3MainFrm.DataGrid.ColCount := (NoVariables + 1); + end; + GetTypes; end; -//------------------------------------------------------------------- - +} + { procedure SaveCommaFile; var namestr : string; @@ -1049,8 +1198,8 @@ begin end; CloseFile(CommaFile); end; -//------------------------------------------------------------------- - + } +{ procedure OpenSpaceFile; label getit; var @@ -1087,7 +1236,7 @@ begin NoVariables := 0; if labelsinc = true then row := 0 else row := 1; col := 1; - AssignFile(SpaceFile, OS3MainFrm.OpenDialog1.FileName); { File selected in dialog box } + AssignFile(SpaceFile, OS3MainFrm.OpenDialog1.FileName); // File selected in dialog box Reset(SpaceFile); OS3MainFrm.FileNameEdit.Text := OS3MainFrm.OpenDialog1.FileName; astr := ''; @@ -1174,8 +1323,8 @@ getit: read(SpaceFile,achar); end; GetTypes; end; -//------------------------------------------------------------------- - +} + { procedure SaveSpaceFile; var namestr : string; @@ -1209,7 +1358,7 @@ begin end; CloseFile(SpaceFile); end; -//------------------------------------------------------------------- +} procedure InsertRow; var @@ -1304,18 +1453,15 @@ begin FormatGrid; end; end; -//------------------------------------------------------------------- procedure ClearGrid; var - i, j : integer; + i, j: integer; begin Assert(OS3MainFrm <> nil); for i := 0 to NoCases do - begin - for j := 0 to NoVariables do OS3MainFrm.DataGrid.Cells[j,i] := ''; - end; + for j := 0 to NoVariables do OS3MainFrm.DataGrid.Cells[j, i] := ''; OS3MainFrm.NoVarsEdit.Text := '0'; OS3MainFrm.NoCasesEdit.Text := '0'; @@ -1325,35 +1471,35 @@ begin OS3MainFrm.DataGrid.ColCount := 2; OS3MainFrm.DataGrid.Cells[0,1] := 'CASE 1'; OS3MainFrm.DataGrid.Cells[0,0] := 'CASE/VAR.'; - end; procedure CopyIt; -VAR - rowstart, rowend,colstart, colend, i, j : integer; - buf : string; - bf : pchar; - +var + rowstart, rowend,colstart, colend, i, j: integer; + buf: string; + bf: PChar; begin Assert(OS3MainFrm <> nil); - Clipboard.Clear; - rowstart := OS3MainFrm.DataGrid.Selection.Top; - rowend := OS3MainFrm.DataGrid.Selection.Bottom; - colstart := OS3MainFrm.DataGrid.Selection.Left; - colend := OS3MainFrm.DataGrid.Selection.Right; - buf := ''; - for i := rowstart to rowend do - begin - for j := colstart to colend do - begin - buf := buf + OS3MainFrm.DataGrid.Cells[j,i]; - buf := buf + chr(9); // add a tab - end; - buf := buf + chr(13); // add a newline - end; - bf := PChar(buf); - Clipboard.SetTextBuf(bf); + Clipboard.Clear; + + rowstart := OS3MainFrm.DataGrid.Selection.Top; + rowend := OS3MainFrm.DataGrid.Selection.Bottom; + colstart := OS3MainFrm.DataGrid.Selection.Left; + colend := OS3MainFrm.DataGrid.Selection.Right; + + buf := ''; + for i := rowstart to rowend do + begin + for j := colstart to colend do + begin + buf := buf + OS3MainFrm.DataGrid.Cells[j,i]; + buf := buf + chr(9); // add a tab + end; + buf := buf + chr(13); // add a newline + end; + bf := PChar(buf); + Clipboard.SetTextBuf(bf); end; procedure PasteIt; @@ -1534,8 +1680,8 @@ begin end; procedure MatToGrid(const mat: DblDyneMat; nsize: integer); -VAR - i, j : integer; +var + i, j: integer; Begin Assert(OS3MainFrm <> nil); Assert(DictionaryFrm <> nil); @@ -1578,189 +1724,163 @@ Begin end; procedure GetTypes; -VAR - row,col,pos,i,strlong,intplaces,decplaces : integer; - cellstr: string; - strtype, inttype, floattype,isnumber : boolean; - comma, period, achar : char; +const + COMMA = ','; + PERIOD = '.'; +var + row, col, pos, i, strLen, decPlaces: integer; + cellstr: string; + strType, intType, floatType, isNumber: boolean; + ch: char; begin Assert(OS3MainFrm <> nil); Assert(DictionaryFrm <> nil); - isnumber := false; - strtype := false; - inttype := false; - floattype := false; - comma := ','; - period := '.'; + for col := 1 to NoVariables do + begin + isNumber := false; + strType := false; + intType := false; + floatType := false; + for row := 1 to NoCases do + begin + cellstr := trim(OS3MainFrm.DataGrid.Cells[col, row]); + strLen := length(cellstr); - for col := 1 to NoVariables do - begin - for row := 1 to NoCases do + // check for a number type + isNumber := true; + for i := 1 to strLen do + if (cellstr[i] < ',') or (cellstr[i] > '9') or (cellstr[i] = '/') then + begin + isNumber := false; + break; + end; + if not isNumber = false then + strType := true; + if isNumber then + begin // determine if an integer or float number + for i := 1 to strLen do + begin + ch := cellstr[i]; + if (ch = PERIOD) or (ch = COMMA) then begin - cellstr := trim(OS3MainFrm.DataGrid.Cells[col,row]); - strlong := length(cellstr); - // check for a number type - for i := 1 to strlong do - if (ord(cellstr[i]) < 44) or (ord(cellstr[i]) > 57 ) or (ord(cellstr[i]) = 47 ) then - begin - isnumber := false; - break; - end - else isnumber := true; - if isnumber = false then strtype := true; - if isnumber = true then - begin // determine if an integer or float number - for i := 1 to strlong do - begin - achar := cellstr[i]; - if achar = period then floattype := true; - if achar = comma then floattype := true; - if floattype = true then - begin - pos := i; - break; - end; - end; - if floattype = false then inttype := true; - if floattype = true then - begin // get no. of decimal positions - intplaces := pos - 1; - decplaces := strlong - pos - 1; - end; - end; // end if it is a number - end; // end of row search - // set dictionary values - if strtype = true then - begin - DictionaryFrm.DictGrid.Cells[4,col] := 'S'; - DictionaryFrm.DictGrid.Cells[3,col] := IntToStr(strlong); - DictionaryFrm.DictGrid.Cells[5,col] := '0'; + floatType := true; + pos := i; + break; end; - if inttype = true then - begin - DictionaryFrm.DictGrid.Cells[4,col] := 'I'; - DictionaryFrm.DictGrid.Cells[3,col] := IntToStr(strlong); - DictionaryFrm.DictGrid.Cells[5,col] := '0'; - end; - if floattype = true then - begin - DictionaryFrm.DictGrid.Cells[4,col] := 'F'; - DictionaryFrm.DictGrid.Cells[3,col] := IntToStr(strlong); - DictionaryFrm.DictGrid.Cells[5,col] := IntToStr(decplaces); - end; - isnumber := false; - strtype := false; - inttype := false; - floattype := false; - end; // end of column loop + end; + if not floatType then + intType := true; + if floatType then // get no. of decimal positions + decPlaces := strLen - pos - 1; + end; // end if it is a number + end; // end of row search + + // set dictionary values + DictionaryFrm.DictGrid.Cells[3, col] := IntToStr(strLen); + if strType then + begin + DictionaryFrm.DictGrid.Cells[4, col] := 'S'; + DictionaryFrm.DictGrid.Cells[5, col] := '0'; + end; + if intType then + begin + DictionaryFrm.DictGrid.Cells[4, col] := 'I'; + DictionaryFrm.DictGrid.Cells[5, col] := '0'; + end; + if floatType then + begin + DictionaryFrm.DictGrid.Cells[4, col] := 'F'; + DictionaryFrm.DictGrid.Cells[5, col] := IntToStr(decPlaces); + end; + end; // end of column loop end; -function StringsToInt(strcol: integer; VAR newcol : integer; prompt : boolean) : boolean; +{ Procedure to convert group strings into group integers with the option + to save the integers in the grid } +function StringsToInt(StrCol: integer; var newcol: integer; Prompt: boolean): boolean; var - i, j, k, NoStrings: integer; - TempString, response : string; - dup, savenewcol, strtype : boolean; - StrGrps, OneString : StrDyneVec; - + i, j, k, NoStrings: integer; + TempString: string; + dup: boolean; + StrGrps, OneString : StrDyneVec; + res: TModalResult; begin + Result := true; + Assert(OS3MainFrm <> nil); Assert(DictionaryFrm <> nil); - { Procedure to convert group strings into group integers with the option - to save the integers in the grid } - strtype := false; - savenewcol := true; + // Get memory for arrays + SetLength(StrGrps, NoCases+1); + SetLength(OneString, NoCases+1); - // Get memory for arrays - SetLength(StrGrps,NoCases+1); - SetLength(OneString,NoCases+1); + // check to see if strcol is a string variable + if DictionaryFrm.DictGrid.Cells[4,strcol] <> 'S' then + begin + ErrorMsg('Column selected is not defined as a string variable'); + exit; + end; - // check to see if strcol is a string variable - if DictionaryFrm.DictGrid.Cells[4,strcol] = 'S' then - strtype :=true - else begin - MessageDlg('Column selected is not defined as a string variable', mtError, [mbOK], 0); - exit; - end; + // read the strings into the StrGrps array + for i := 1 to NoCases do + StrGrps[i-1] := trim(OS3MainFrm.DataGrid.Cells[strcol, i]); - // read the strings into the StrGrps array - for i := 1 to NoCases do - StrGrps[i-1] := trim(OS3MainFrm.DataGrid.Cells[strcol,i]); + // sort the StrGrps array + for i := 0 to NoCases - 1 do + for j := i + 1 to NoCases - 1 do + if (StrGrps[i] > StrGrps[j]) then // swap + Exchange(StrGrps[i], StrGrps[j]); - // sort the StrGrps array - for i := 0 to NoCases - 1 do - begin - for j := i + 1 to NoCases - 1 do - begin - if (StrGrps[i] > StrGrps[j]) then // swap - begin - TempString := StrGrps[i]; - StrGrps[i] := StrGrps[j]; - StrGrps[j] := TempString; - end; - end; - end; + // copy unique strings into the OneString array + TempString := StrGrps[0]; + OneString[0] := TempString; + NoStrings := 0; + for i := 1 to NoCases do + begin + if (StrGrps[i] <> TempString) then // a new string found + begin + for k := 0 to NoCases - 1 do // check for existing + dup := (TempString = OneString[k]); + if not dup then + begin + NoStrings := NoStrings + 1; + OneString[NoStrings] := StrGrps[i]; + TempString := StrGrps[i]; + end; + end; + end; - // copy unique strings into the OneString array - TempString := StrGrps[0]; - OneString[0] := TempString; - NoStrings := 0; - for i := 1 to NoCases do - begin - if (StrGrps[i] <> TempString) then // a new string found - begin - for k := 0 to NoCases - 1 do // check for existing - begin - if (TempString = OneString[k]) then dup := true - else dup := false; - end; - if (dup = false) then - begin - NoStrings := NoStrings + 1; - OneString[NoStrings] := StrGrps[i]; - TempString := StrGrps[i]; - end; - end; - end; + // make a new variable in the grid for the group integers + DictionaryFrm.NewVar(NoVariables+1); + DictionaryFrm.DictGrid.Cells[1,NoVariables] := 'GroupCode'; + OS3MainFrm.DataGrid.Cells[NoVariables,0] := 'GroupCode'; + OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables); - // make a new variable in the grid for the group integers - DictionaryFrm.NewVar(NoVariables+1); - DictionaryFrm.DictGrid.Cells[1,NoVariables] := 'GroupCode'; - OS3MainFrm.DataGrid.Cells[NoVariables,0] := 'GroupCode'; - OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables); + DictionaryFrm.DictGrid.Cells[4,NoVariables] := 'I'; + DictionaryFrm.DictGrid.Cells[5,NoVariables] := '0'; + OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables); + newcol := NoVariables; - DictionaryFrm.DictGrid.Cells[4,NoVariables] := 'I'; - DictionaryFrm.DictGrid.Cells[5,NoVariables] := '0'; - OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables); - newcol := NoVariables; + // oompare case strings with OneString values and use index+1 for the group code in the data grid + for i := 1 to NoCases do + begin + TempString := OS3MainFrm.DataGrid.Cells[strcol,i]; + for j := 0 to NoCases-1 do + if (TempString = OneString[j]) then + OS3MainFrm.DataGrid.Cells[NoVariables,i] := IntToStr(j+1); + end; - // oompare case strings with OneString values and use index + 1 - // for the group code in the data grid - for i := 1 to NoCases do - begin - TempString := OS3MainFrm.DataGrid.Cells[strcol,i]; - for j := 0 to NoCases-1 do - begin - if (TempString = OneString[j]) then - OS3MainFrm.DataGrid.Cells[NoVariables,i] := IntToStr(j+1); - end; - end; + // see if user wants to save the generated group codes + if Prompt then + begin + res := MessageDlg('Save Code in Grid?', mtConfirmation, [mbYes, mbNo], 0); + if res <> mrYes then Result := false; + end; - // see if user wants to save the generated group codes - if (prompt = true) then - begin - response := InputBox('Save Code in Grid?','Y or N','Y'); - if ((response = 'n') or (response = 'N')) then - savenewcol := false; - end; - - // clean up memory - OneString := nil; - StrGrps := nil; - - // return results - Result := savenewcol; + // clean up memory + OneString := nil; + StrGrps := nil; end; diff --git a/applications/lazstats/source/units/globals.pas b/applications/lazstats/source/units/globals.pas index 3a63e3e72..56254ad28 100644 --- a/applications/lazstats/source/units/globals.pas +++ b/applications/lazstats/source/units/globals.pas @@ -97,6 +97,10 @@ const TWO_PI = 2.0 * PI; + TAB_FILE_FILTER = 'Tab field files (*.tab)|*.tab;*.TAB|Text files (*.txt)|*.txt;*.TXT|All files (*.*)|*.*'; + CSV_FILE_FILTER = 'Comma field files (*.csv)|*.csv;*.CSV|Text files (*.txt)|*.txt;*.TXT|All files (*.*)|*.*'; + SSV_FILE_FILTER = 'Space field files (*.ssv)|*.ssv;*.SSV|Text files (*.txt)|*.txt;*.TXT|All files (*.*)|*.*'; + implementation end.