Hello,
I am trying to setup a mail merge using the Label examples. However, in the final document I need to be able to have merged fields wrap. I've looked at the different demos and for creating the merge templates I like how the labels work the best.
However I am having trouble deleting the label and replacing it with the text during the merge. Here is what I am trying but I keep ending up with junk in the final document.
procedure TRVViewer.UpdateRVItem(RVData: TCustomRVData; ItemNo: integer; NewData: string);
var
item: TRVTextItemInfo;
x: TRVRawByteString;
begin
case RVData.GetItemStyle(ItemNo) of
rvsLabel:
begin
// Works OK but will not support the NewData being word wrapped.
//TRVLabelItemInfo(RVData.GetItem(ItemNo)).Text := NewData;
item := TRVTextItemInfo.Create(RVData);
item.StyleNo := TRVLabelItemInfo(RVData.GetItem(ItemNo)).TextStyleNo;
item.ParaNo := TRVLabelItemInfo(RVData.GetItem(ItemNo)).ParaNo;
item.ItemOptions := RVData.GetItem(ItemNo).ItemOptions;
RVData.DeleteItems(ItemNo, 1);
// What is the string needed for here? It can't be a string it needs to be TRVRawByteString because it
// is a var paramater.
item.Inserting(RVData, x, False);
RVData.Items.InsertObject(ItemNo, NewData, item);
item.Inserted(RVData, ItemNo);
end;
Replace Label with Text
I've narrowed this down to a problem with setting the StyleNo. I know that labels have a different TextStyleNo property but that does not seem to work correctly.
CurLabelItem := TRVLabelItemInfo(RVData.GetItem(ItemNo));
NewTextItem := TRVTextItemInfo.Create(RVData);
// This shows me my text but does not hold the style applied to the
// label in the template.
NewTextItem.StyleNo := 0;
// Both of these options will end up with garbage in the output (looks like // Asian chars.
// NewTextItem.StyleNo := RVData.GetActualTextStyle(CurLabelItem);
// NewTextItem.StyleNo := CurLabelItem.TextStyleNo;
NewTextItem.ParaNo := CurLabelItem.ParaNo;
// It looks like AssignParaProperties ends up setting most of the
// ItemOptions?
NewTextItem.ItemOptions := CurLabelItem.ItemOptions;
NewTextItem.AssignParaProperties(CurLabelItem);
RVData.DeleteItems(ItemNo, 1);
NewTextItem.Inserting(RVData, x, False);
RVData.Items.InsertObject(ItemNo, NewData, NewTextItem);
NewTextItem.Inserted(RVData, ItemNo);
CurLabelItem := TRVLabelItemInfo(RVData.GetItem(ItemNo));
NewTextItem := TRVTextItemInfo.Create(RVData);
// This shows me my text but does not hold the style applied to the
// label in the template.
NewTextItem.StyleNo := 0;
// Both of these options will end up with garbage in the output (looks like // Asian chars.
// NewTextItem.StyleNo := RVData.GetActualTextStyle(CurLabelItem);
// NewTextItem.StyleNo := CurLabelItem.TextStyleNo;
NewTextItem.ParaNo := CurLabelItem.ParaNo;
// It looks like AssignParaProperties ends up setting most of the
// ItemOptions?
NewTextItem.ItemOptions := CurLabelItem.ItemOptions;
NewTextItem.AssignParaProperties(CurLabelItem);
RVData.DeleteItems(ItemNo, 1);
NewTextItem.Inserting(RVData, x, False);
RVData.Items.InsertObject(ItemNo, NewData, NewTextItem);
NewTextItem.Inserted(RVData, ItemNo);
-
- Site Admin
- Posts: 17569
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
You can use the function from RVInsertItems.pas:
It inserts string in the ItemNo-th position, automatically sets the correct raw-byte string and item options.
To add to the same paragraph, specify ParaNo=-1.
Code: Select all
procedure RVInsertString(RVData: TCustomRVData; ItemNo: Integer;
const s: String; StyleNo, ParaNo: Integer;
const Tag: TRVTag=RVEMPTYTAG);
To add to the same paragraph, specify ParaNo=-1.
That worked great.
I ended up with the following code. Much simpler than before. Posting here in case anyone else is interested.
One other change I had to make was in the main FillFields function from the mail merge examples. The examples use a for loop. Because I am inserting new items I needed to change it to a while loop. Otherwise I ended up stopping before I updated all of the items.
I ended up leaving the label in place. I think in theory I could copy the paragraph attributes to the newly inserted item but this seemed simpler.
One question I still have is am I better off setting the text to an empty string or should I leave the text alone and set CurLabelItem.Hidden := true;? I can't tell if there would really be a difference or not. The one item that worries me about the empty string is I have seen in the help where an empty item is not always valid. Not sure if that applies here or not.
I ended up with the following code. Much simpler than before. Posting here in case anyone else is interested.
One other change I had to make was in the main FillFields function from the mail merge examples. The examples use a for loop. Because I am inserting new items I needed to change it to a while loop. Otherwise I ended up stopping before I updated all of the items.
I ended up leaving the label in place. I think in theory I could copy the paragraph attributes to the newly inserted item but this seemed simpler.
One question I still have is am I better off setting the text to an empty string or should I leave the text alone and set CurLabelItem.Hidden := true;? I can't tell if there would really be a difference or not. The one item that worries me about the empty string is I have seen in the help where an empty item is not always valid. Not sure if that applies here or not.
Code: Select all
// We are going to insert the new data right after this item.
// To ensure that we stay in the same paragraph with the same formatting
// the Label will be left in place but the text set to a blank string.
CurLabelItem := TRVLabelItemInfo(RVData.GetItem(ItemNo));
CurLabelItem.Text := '';
if NewData <> '' then
RVInsertString(RVData, ItemNo + 1, NewData, CurLabelItem.TextStyleNo, -1);
-
- Site Admin
- Posts: 17569
- Joined: Sat Aug 27, 2005 10:28 am
- Contact: