📄 mainappfrm.pas
字号:
{==============================================================================}
{
Mail merge application: part 2 - displaying processed template.
How it works:
- RVStyle2 has two predefined styles (the same as in the template editor;
1th text style is reserved for fields).
- RichView1 and RichView2 are linked to the same RVStyle (RVStyle2)
- Template is loaded in RichView1 (styles can be added dynamically in RVStyle2)
- RichView1 is scanned for fields. When field is found, it is deleted,
and its value is inserted in its place:
* field value is loaded in invisible RichView2 (styles can be added in RVStyle2)
* contents of RichView2 is inserted in the proper place of RichView1.
}
{==============================================================================}
unit MainAppFrm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, RVScroll, RichView, RVStyle, DB, DBTables, CRVFData, RVTable;
type
TForm1 = class(TForm)
RichView1: TRichView;
RichView2: TRichView;
Table1: TTable;
RVStyle2: TRVStyle;
procedure FormCreate(Sender: TObject);
private
procedure ReplaceFields(RVData: TCustomRVFormattedData);
{ Private declarations }
public
{ Public declarations }
function LoadData(const Code: String): TMemoryStream;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
// Loading template with fields
RichView1.LoadRVF(ExtractFilePath(Application.ExeName)+'Template.rvf');
// RVData.InsertFromStream (we will call it later) does not support
// style merging. So changing mode to style ignoring:
RichView1.RVFParaStylesReadMode := rvf_sIgnore;
RichView1.RVFTextStylesReadMode := rvf_sIgnore;
// Replace styles with values
ReplaceFields(RichView1.RVData);
RichView1.Format;
end;
procedure TForm1.ReplaceFields(RVData: TCustomRVFormattedData);
var i,j: Integer;
Stream: TMemoryStream;
Dummy1: TColor;
Dummy2, Dummy3: Pointer;
ParaNo: Integer;
BR, ContinuePara: Boolean;
table: TRVTableItemInfo;
r,c: Integer;
begin
Dummy1 := clNone;
Dummy2 := nil;
Dummy3 := nil;
for i := RVData.ItemCount-1 downto 0 do
case RVData.GetItemStyle(i) of
1: // the first text style is used for fields
begin
// storing parameters of deleted items
ParaNo := RVData.GetItemPara(i);
BR := RVData.GetItem(i).BR;
ContinuePara := RVData.GetItem(i).SameAsPrev;
// loading field value in the stream
Stream := LoadData(RVData.GetItemTextA(i));
if Stream<>nil then begin
// deleting the field code
RVData.DeleteItems(i,1);
// inserting the field value
RVData.InsertRVFFromStream(Stream, i, Dummy1, Dummy2, Dummy3, False);
// applying stored parameters to the inserted items
for j := i to RVData.ItemCount-1 do begin
if (i=j) then begin
RVData.GetItem(j).SameAsPrev := ContinuePara;
if BR then
RVData.GetItem(j).BR := True;
end;
if (j>i) and RVData.IsParaStart(j) then
break;
RVData.GetItem(j).ParaNo := ParaNo;
end;
Stream.Free;
end;
end;
rvsTable:
begin
// recursive call for table cells
table := TRVTableItemInfo(RVData.GetItem(i));
for r := 0 to table.Rows.Count-1 do
for c := 0 to table.Rows[r].Count-1 do
if table.Cells[r,c]<>nil then
ReplaceFields(table.Cells[r,c]);
end;
end;
RVData.Normalize;
end;
// Loading field code
function TForm1.LoadData(const Code: String): TMemoryStream;
begin
Result := nil;
if not Table1.Locate('Code', Code, []) then
exit;
Result := TMemoryStream.Create;
TBlobField(Table1.FieldByName('Data')).SaveToStream(Result);
Result.Position := 0;
RichView2.Clear;
RichView2.InsertRVFFromStream(Result, 0); // inserting will merge styles;
// RichView1 and RichView2 have the same collections of styles
Result.Clear;
RichView2.SaveRVFToStream(Result, False);
Result.Position := 0;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -