📄 rm_cross.pas
字号:
finally
FFlag_Insert := False;
FreeAndNil(sl1);
FreeAndNil(sl2);
end;
end;
procedure MakeTotals(sl: TStringList; Direction: Boolean); // Direction=True sl=Columns else sl=Rows
var
i: Integer;
s, Old: string;
begin
Old := sl[0];
i := 0;
FInsertPos := 0;
while i < sl.Count do
begin
s := sl[i];
if (s <> Old) and (Pos('+', s) = 0) then
begin
FormGroup(s, Old, Direction, i - 1);
Old := s;
end;
Inc(i);
end;
FormGroup('', sl[sl.Count - 1], Direction, sl.Count);
end;
procedure CalcTotals(FieldsSl, RowsSl, ColumnsSl: TStringList);
var
i, j, k, i1: Integer;
lList: TList;
cg: TRMCrossGroupItem;
begin
lList := TList.Create;
lList.Add(TRMCrossGroupItem.Create(Self, '', FieldsSl.Count, FCellItemsCount)); // grand total
for i := 0 to FieldsSl.Count - 1 do
lList.Add(TRMCrossGroupItem.Create(Self, ColumnsSl[0], i, FCellItemsCount));
for i := 0 to RowsSl.Count - 1 do
begin
for k := 0 to FieldsSl.Count do
TRMCrossGroupItem(lList[k]).Reset(ColumnsSl[0], 0);
for j := 0 to ColumnsSl.Count - 1 do
begin
for k := 0 to FieldsSl.Count do
begin
cg := TRMCrossGroupItem(lList[k]);
if cg.IsBreak(ColumnsSl[j]) or ((k = 0) and (j = ColumnsSl.Count - 1)) then
begin
if (k = 0) or HasTotal(FieldsSl[k - 1]) then
begin
cg.CheckAvg;
if RowsSl = Rows then
begin
CellArray[i, j] := cg.Value;
Cell[Rows[0], Columns[j], -1] := cg.FStartFrom;
end
else
begin
CellArray[j, i] := cg.Value;
Cell[Rows[j], Columns[0], -1] := cg.FStartFrom;
end;
end;
i1 := j;
while i1 < ColumnsSl.Count do
begin
if Pos('+;+', ColumnsSl[i1]) = 0 then
break;
Inc(i1);
end;
if i1 < ColumnsSl.Count then
cg.Reset(ColumnsSl[i1], j);
break;
end
else if Pos('+;+', ColumnsSl[j]) = 0 then
begin
if RowsSl = Rows then
cg.AddValue(CellArray[i, j])
else
cg.AddValue(CellArray[j, i]);
end;
end;
end;
end;
for i := 0 to FieldsSl.Count do
TRMCrossGroupItem(lList[i]).Free;
FreeAndNil(lList);
end;
procedure CheckAvg;
var
i, j: Integer;
v: Variant;
n: TRMQuickIntArray;
Check: Boolean;
procedure CalcAvg(i1, j1: Integer);
var
i, j, k: Integer;
v1: Variant;
begin
for i := 0 to FCellFields.Count - 1 do
begin
v[i] := 0;
n[i] := 0;
end;
for i := CellByIndex[i1, 0, -1] to i1 - 1 do
begin
for j := CellByIndex[0, j1, -1] to j1 - 1 do
begin
if (not IsTotalRow[i]) and (not IsTotalColumn[j]) then
begin
for k := 0 to FCellFields.Count - 1 do
begin
if FuncName(FCellFields[k]) = 'avg' then
begin
v1 := CellByIndex[i, j, k];
if v1 <> Null then
begin
n[k] := n[k] + 1;
v[k] := v[k] + v1;
end;
end;
end;
end;
end;
end;
for i := 0 to FCellFields.Count - 1 do
begin
if FuncName(FCellFields[i]) = 'avg' then
begin
if n[i] <> 0 then
Cell[Rows[i1], Columns[j1], i] := v[i] / n[i]
else
Cell[Rows[i1], Columns[j1], i] := Null;
end;
end;
end;
begin
v := VarArrayCreate([0, FCellFields.Count - 1], varVariant);
n := TRMQuickIntArray.Create(FCellFields.Count);
Check := False;
for i := 0 to FCellFields.Count - 1 do
begin
if FuncName(FCellFields[i]) = 'avg' then
begin
Check := True;
break;
end;
end;
if Check then
begin
for i := 0 to Rows.Count - 1 do
begin
if IsTotalRow[i] or (i = Rows.Count - 1) then
begin
for j := 0 to Columns.Count - 1 do
begin
if IsTotalColumn[j] or (j = Columns.Count - 1) then
CalcAvg(i, j);
end;
end;
end;
end;
for i := 0 to Rows.Count - 1 do
Cell[Rows[i], Columns[0], -1] := Null;
for i := 0 to Columns.Count - 1 do
Cell[Rows[0], Columns[i], -1] := Null;
VarClear(v);
n.Free;
end;
procedure _MakeColumnHeader;
var
i, j, n, cn: Integer;
s: string;
sl, sl1: TStringList;
Flag: Boolean;
d: Double;
lValue: Variant;
function _CompareSl(Index: Integer): Boolean;
begin
Result := (sl.Count > Index) and (sl1.Count > Index) and (sl[Index] = sl1[Index]);
end;
begin
sl := TStringList.Create;
sl1 := TStringList.Create;
cn := CharCount(';', Columns[0]) + 1; // height of header
FTopLeftSize.cy := cn;
FFlag_Insert := True;
for i := 0 to cn do
begin
FInsertPos := i;
Cell[Chr(i), Columns[0], 0] := '';
end;
FFlag_Insert := False;
for i := 0 to Columns.Count - 1 do
Cell[#0, Columns[i], -1] := rmftTop or rmftBottom;
Cell[#0, Columns[0], 0] := FHeaderString;
Cell[#0, Columns[0], -1] := rmftLeft or rmftTop or rmftBottom;
Cell[#0, Columns[Columns.Count - 1], -1] := rmftTop or rmftRight;
for i := 1 to FAddColumnsHeader.Count do
Cell[#0, Columns[Columns.Count - 1 - i], -1] := rmftTop or rmftRight;
for i := 1 to cn do
begin
Cell[Chr(i), Columns[Columns.Count - 1], -1] := rmftLeft or rmftRight;
for j := 1 to FAddColumnsHeader.Count do
Cell[Chr(i), Columns[Columns.Count - 1 - j], -1] := rmftLeft or rmftRight;
end;
Cell[#1, Columns[Columns.Count - 1 - FAddColumnsHeader.Count], 0] := FColumnGrandTotalString;
Cell[#1, Columns[Columns.Count - 1 - FAddColumnsHeader.Count], -1] := rmftLeft or rmftTop or rmftRight;
for i := 0 to FAddColumnsHeader.Count - 1 do
begin
Cell[#1, Columns[Columns.Count - 1 - i], 0] := FAddColumnsHeader[FAddColumnsHeader.Count - 1 - i];
Cell[#1, Columns[Columns.Count - 1 - i], -1] := rmftLeft or rmftTop or rmftRight;
end;
for i := 0 to Columns.Count - 2 - FAddColumnsHeader.Count do
begin
s := Columns[i];
RMSetCommaText(s, sl);
if Pos('+;+', s) <> 0 then
begin
n := CharCount(';', s);
for j := 1 to n - 1 do
Cell[Chr(j), s, -1] := rmftTop;
for j := n to cn do
begin
if j = n then
begin
Cell[Chr(j), s, 0] := FColumnTotalString;
Cell[Chr(j), s, -1] := rmftRight or rmftLeft or rmftTop;
end
else
Cell[Chr(j), s, -1] := rmftRight or rmftLeft;
end;
end
else
begin
Flag := False;
for j := 0 to cn - 1 do
begin
if (not Flag) and _CompareSl(j) then
Cell[Chr(j + 1), s, -1] := rmftTop
else
begin
if TVarData(FColTypes[j]).VType = varDate then
begin
d := StrToFloat(Trim(sl[j]));
TVarData(FColTypes[j]).VDate := d;
lValue := FColTypes[j];
end
else if (TVarData(FColTypes[j]).VType = varString) or
(TVarData(FColTypes[j]).VType = varOleStr) or
(TVarData(FColTypes[j]).VType = varEmpty) or
(TVarData(FColTypes[j]).VType = varNull) then
begin
lValue := '';
if j < sl.Count then
lValue := Trim(sl[j])
end
else
begin
lValue := '';
if j < sl.Count then
begin
d := StrToFloat(Trim(sl[j]));
lValue := FloatToStr(d);
end;
end;
Cell[Chr(j + 1), s, 0] := lValue;
Cell[Chr(j + 1), s, -1] := rmftTop or rmftLeft or rmftRight;
Flag := True;
end;
end;
end;
sl1.Assign(sl);
end;
FreeAndNil(sl);
FreeAndNil(sl1);
end;
procedure _MakeRowHeader;
var
i, j, n, cn: Integer;
s: string;
sl, sl1: TStringList;
Flag: Boolean;
d: Double;
v: Variant;
lNowRowNo: Integer;
function CompareSl(Index: Integer): Boolean;
begin
Result := (sl.Count > Index) and (sl1.Count > Index) and (sl[Index] = sl1[Index]);
end;
procedure CellOr(Index1, Index2: string; Value: Integer);
var
v: Variant;
begin
v := Cell[Index1, Index2, -1];
if v = Null then
v := 0;
v := v or Value;
Cell[Index1, Index2, -1] := v;
end;
begin
sl := TStringList.Create;
sl1 := TStringList.Create;
cn := CharCount(';', Rows[FTopLeftSize.cy + 1]) + 1 + Ord(DoDataCol) + Ord(ShowRowNo); // width of header
FTopLeftSize.cx := cn;
FFlag_Insert := True;
for i := 0 to cn - 1 do
begin
FInsertPos := i;
Cell[Rows[0], Chr(i), 0] := '';
end;
FFlag_Insert := False;
Cell[Rows[Rows.Count - 1], #0, 0] := FRowGrandTotalString;
Cell[Rows[Rows.Count - 1], #0, -1] := rmftTop or rmftBottom or rmftLeft;
for i := 1 to cn - 1 do
Cell[Rows[Rows.Count - 1], Chr(i), -1] := rmftTop or rmftBottom;
if DoDataCol then
begin
for i := FTopLeftSize.cy + 1 to Rows.Count - 1 do
begin
Cell[Rows[i], Chr(cn - 1), 0] := DataStr;
Cell[Rows[i], Chr(cn - 1), -1] := 15;
end;
end;
for i := 0 to FTopLeftSize.cy do
begin
for j := 0 to cn - 1 do
Cell[Chr(i), Chr(j), -1] := 0;
end;
lNowRowNo := 1;
for i := FTopLeftSize.cy + 1 to Rows.Count - 2 do
begin
s := Rows[i];
RMSetCommaText(s, sl);
if Pos('+;+', s) <> 0 then
begin
n := CharCount(';', s);
for j := 1 to n - 1 + Ord(ShowRowNo) do
Cell[s, Chr(j - 1), -1] := rmftLeft;
for j := n + Ord(ShowRowNo) to cn - Ord(DoDataCol) do
begin
if (j = n + Ord(ShowRowNo)) then
begin
Cell[s, Chr(j - 1), 0] := FRowTotalString;
Cell[s, Chr(j - 1), -1] := rmftLeft or rmftTop;
end
else
begin
Cell[s, Chr(j - 1), -1] := rmftTop or rmftBottom;
end;
end;
end
else
begin
Flag := False;
for j := Ord(ShowRowNo) to cn - 1 - Ord(DoDataCol) do
begin
if (not Flag) and CompareSl(j - Ord(ShowRowNo)) then
begin
Cell[s, Chr(j), 0] := Null; // whf add, 2005/11/28
Cell[s, Chr(j), -1] := rmftLeft;
if ShowRowNo and (j = 1) then
Cell[s, Chr(0), -1] := rmftLeft;
end
else
begin
if TVarData(FRowTypes[j - Ord(ShowRowNo)]).VType = varDate then
begin
d := StrToFloat(Trim(sl[j - Ord(ShowRowNo)]));
TVarData(FRowTypes[j]).VDate := d;
v := FRowTypes[j];
end
else if (TVarData(FRowTypes[j - Ord(ShowRowNo)]).VType = varString) or
(TVarData(FRowTypes[j - Ord(ShowRowNo)]).VType = varOleStr) or
(TVarData(FRowTypes[j - Ord(ShowRowNo)]).VType = varEmpty) or
(TVarData(FRowTypes[j - Ord(ShowRowNo)]).VType = varNull) then
v := Trim(sl[j - Ord(ShowRowNo)])
else
begin
d := StrToFloat(Trim(sl[j - Ord(ShowRowNo)]));
v := FloatToStr(d);
end;
Cell[s, Chr(j), 0] := v;
Cell[s, Chr(j), -1] := rmftTop or rmftLeft;
if ShowRowNo and (j = 1) then
begin
Cell[s, Chr(0), 0] := lNowRowNo;
Cell[s, Chr(0), -1] := rmftTop or rmftLeft;
Inc(lNowRowNo);
end;
Flag := True;
end;
end;
end;
sl1.Assign(sl);
end;
FreeAndNil(sl);
FreeAndNil(sl1);
for i := cn to Columns.Count - 1 do
CellOr(Rows[Rows.Count - 1], Columns[i], 15);
for i := cn to Columns.Count - 1 do
CellOr(Rows[FTopLeftSize.cy], Columns[i], rmftBottom);
for i := 0 to cn - 1 - ord(DoDataCol) do
CellOr(Rows[Rows.Count - 2], Columns[i], rmftBottom);
end;
begin
FDataSet.Open;
FDataSet.First;
while not FDataSet.EOF do
begin
Application.ProcessMessages;
for i := 0 to FCellFields.Count - 1 do
begin
lField := FDataSet.FindField(FReport.Dictionary.RealFieldName[nil, _PureName(FCellFields[i])]);
if FuncName(FCellFields[i]) = 'count' then
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -