📄 unit1.pas
字号:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, RVScroll, RichView, RVEdit, RVStyle, ExtCtrls, RVTable, StdCtrls, Clipbrd;
{------------------------------------------------------------------------------}
{
Notes:
1. Making sure that all cells contain one item (and only one)
- adding rvpaoDoNotWantReturns in Options of all paragraph styles
- allowing to paste only one line of plain text (see OnPaste)
2. Protecting autocalculated text
- the 1st paragraph style ("Read-Only") has rvpaoReadOnly
- RichView allows to delete read-only paragraphs when they are parts
of lager selection (for example, multicell selection)
An event, allowing to avoid this problem, was added in version 1.6.11
(OnCellEditing)
3. Table cannot be deleted because it is added in read-only paragraph.
4. EConvertError exception occurs if Income column contains non numeric data.
If running in Delphi IDE, Delphi stops on exception. Just click OK and
press F9 to continue.
5. AcceptDragDropFormats is set to []
}
{------------------------------------------------------------------------------}
type
TForm1 = class(TForm)
RVStyle1: TRVStyle;
rve: TRichViewEdit;
Panel1: TPanel;
Button1: TButton;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure rveChange(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure rvePaste(Sender: TCustomRichViewEdit;
var DoDefault: Boolean);
private
{ Private declarations }
procedure Calculate;
procedure OnCellEditing(Sender: TRVTableItemInfo;
Row, Col : Integer;
Automatic: Boolean;
var AllowEdit: Boolean);
public
{ Public declarations }
table: TRVTableItemInfo;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var r,c: Integer;
begin
table := TRVTableItemInfo.CreateEx(5,4, rve.RVData);
table.BorderWidth := 1;
table.CellBorderWidth := 1;
table.CellBorderStyle := rvtbColor;
table.CellBorderColor := clBtnFace;
table.BorderStyle := rvtbColor;
table.OnCellEditing := OnCellEditing;
// Each cell initially contains one empty text item. Deleting it
for r := 0 to table.Rows.Count-1 do
for c := 0 to table.Rows[r].Count-1 do
table.Cells[r,c].Clear;
// First Row
table.Cells[0,0].AddNL('Name',1,1);
table.Cells[0,1].AddNL('Income',1,1);
table.Cells[0,2].AddNL('Tax Rate',1,1);
table.Cells[0,3].AddNL('Tax',1,1);
// Last Row
r := table.Rows.Count-1;
table.Cells[r,0].AddNL('TOTAL:',1,1);
table.Cells[r,1].AddNL('',1,1);
table.Cells[r,2].AddNL('',1,1);
table.Cells[r,3].AddNL('',1,1);
// First Column
table.Cells[1,0].AddNL('John Smith', 0, 0);
table.Cells[2,0].AddNL('John Brown', 0, 0);
table.Cells[3,0].AddNL('Phil Forest', 0, 0);
// Second Column
table.Cells[1,1].AddNL('2000', 0, 0);
table.Cells[2,1].AddNL('2500', 0, 0);
table.Cells[3,1].AddNL('1000', 0, 0);
for r := 1 to table.Rows.Count-2 do begin
table.Cells[r,2].Color := clSilver;
table.Cells[r,3].Color := clSilver;
table.Cells[r,2].AddNL('0.20',0,1);
table.Cells[r,3].AddNL('',0,1);
end;
for c := 0 to table.Rows[0].Count-1 do begin
table.Cells[0,c].Color := clSilver;
table.Cells[table.Rows.Count-1,c].Color := clSilver;
end;
DecimalSeparator := '.';
Calculate;
rve.InsertItem('Spreadsheet', table);
rve.ApplyParaStyle(1); // read-only style;
end;
procedure TForm1.Calculate;
var r: Integer;
s: String;
total, totaltax, val, valtax: Double;
totalOK: Boolean;
begin
// Last Column
totalOK := True;
total := 0.0;
totaltax := 0.0;
for r := 1 to table.Rows.Count-2 do begin
try
// val <- income
val := StrToFloat(table.Cells[r,1].GetRVData.GetItemText(0));
// valtax <- income * tax rate
valtax := val*StrToFloat(table.Cells[r,2].GetRVData.GetItemText(0));
s := FloatToStr(valtax);
total := total + val;
totaltax := totaltax + valtax;
except
s := '?';
totalOK := False;
end;
table.Cells[r,3].GetRVData.SetItemText(0,s);
end;
if totalOK then begin
table.Cells[table.Rows.Count-1,3].GetRVData.SetItemText(0, FloatToStr(totaltax));
table.Cells[table.Rows.Count-1,1].GetRVData.SetItemText(0, FloatToStr(total));
end
else begin
table.Cells[table.Rows.Count-1,3].GetRVData.SetItemText(0, '?');
table.Cells[table.Rows.Count-1,1].GetRVData.SetItemText(0, '?');
end;
table.Changed;
end;
// OnChange: recalculating
procedure TForm1.rveChange(Sender: TObject);
begin
Calculate;
rve.Reformat;
if rve.InplaceEditor<>nil then
rve.InplaceEditor.Invalidate;
// Some ideas:
// - you can use table.GetEditedCell to get a cell which was changed
end;
// Adding a new row
procedure TForm1.Button1Click(Sender: TObject);
var ItemNo, Data, r,c: Integer;
begin
ItemNo := rve.GetItemNo(table);
rve.BeginItemModify(ItemNo, Data);
r := table.Rows.Count-1;
table.InsertRows(r, 1, -1);
for c := 1 to table.Rows[r].Count-1 do
table.Cells[r,c].Clear;
table.Cells[r,1].AddNL('0', 0,0);
table.Cells[r,2].AddNL('0.20', 0,1);
table.Cells[r,3].AddNL('', 0,1);
table.Cells[r,2].Color := clSilver;
table.Cells[r,3].Color := clSilver;
rve.EndItemModify(ItemNo, Data);
rve.Change;
end;
// Deleting a row with caret
procedure TForm1.Button2Click(Sender: TObject);
var ItemNo, Data, r,c: Integer;
begin
if (table.GetEditedCell(r,c)<>nil) and (r<>0) and (r<>table.Rows.Count-1) then begin
ItemNo := rve.GetItemNo(table);
rve.BeginItemModify(ItemNo, Data);
table.DeleteRows(r,1,False);
rve.EndItemModify(ItemNo, Data);
rve.Change;
end
else
Beep;
end;
// OnPaste: allowing to paste only one line of text
procedure TForm1.rvePaste(Sender: TCustomRichViewEdit;
var DoDefault: Boolean);
var s: String;
begin
if Clipboard.HasFormat(CF_TEXT) then begin
s := Clipboard.AsText;
if (Pos(#13,s)=0) and (Pos(#10,s)=0) then
rve.InsertText(s, False);
end;
DoDefault := False;
end;
procedure TForm1.OnCellEditing(Sender: TRVTableItemInfo; Row, Col: Integer;
Automatic: Boolean; var AllowEdit: Boolean);
begin
if Automatic then
AllowEdit := (Row<>0) and (Row<>table.Rows.Count-1) and (Col<2);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -