MainAppFrm.pas
上传用户:daoqigc
上传日期:2021-04-20
资源大小:2795k
文件大小:4k
- {==============================================================================}
- {
- 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.