|
|
Mail Merge with Page Breaks
Last post 09-10-2010, 11:24 AM by AndreyN. 23 replies.
-
09-01-2010, 6:36 PM |
-
regrossman
-
-
-
Joined on 07-19-2010
-
-
Posts 21
-
-
-
-
-
|
Mail Merge with Page Breaks
I'm using the below code to populate a word document. My users have requested that whenever a new city is encountered, to insert a page break. There is bascially 3 contacts per page, but they want it so if here is only 1 or 2 contacts, for the third cell to be skipped and to immediatly goto the next page for the following city. Is this possible?
Dim doc As New Document("d:\hart11\templates\canvassing.doc") Dim adapterTemplate1 As New SQLDataAdapter("SELECT '' AS SalesAmount, CompanyTxt AS Company, '' AS EmploymentThisSite, FaxDirectTxt AS Fax, '' AS Ownership, PhoneDirectTxt AS Phone, '' AS [Plant/FacilitySize], PhoneGeneralTxt AS Phone2, WebURL AS WebAddress, '' AS YearEstablished, '' AS OwnsRents, Address1Txt AS Address1, Address2Txt AS Address2, CityTxt As City, StateCode AS State, PostalCodeTxt As Zip, ShippingAddress1Txt AS AltAddress, ShippingCityTxt As AltCity, ShippingStateCode AS AltState, ShippingPostalCodeTxt AS AltZip, CountyTxt AS County, ContactSIC1Code AS SIC1, '' AS SIC1Description, ContactSIC2Code AS SIC2, '' AS Sic2Description, ContactSIC3Code AS SIC3, '' AS Sic3Description, ContactParentCompanyTxt AS Parent, PrefixTxt AS Prefix, FirstTxt AS First, LastTxt As Last, SuffixTxt AS Suffix, TitleTxt AS Title, DivisionTxt AS Division, ExportNameTxt AS Canvassed, ExportPreparedFor AS Salesperson FROM ViewContact INNER JOIN ExportDetail ON ExportDetail.ExportPrimaryRecordID = ViewContact.ContactID INNER JOIN ExportMaster ON ExportMaster.ExportID = ExportDetail.ExportID WHERE ExportDetail.ExportID='" & Request.QueryString("ID") & "' UNION SELECT [Sales Amount] AS SalesAmount, Company, EmploymentThisSite, REPLACE(Fax, '-', '') AS Fax, Ownership, REPLACE(Phone,'-','') AS Phone, [Plant/FacilitySize], TollFree AS Phone2, WebAddress, YearEstablished, OwnsRents, MailAddress AS Address1, '' AS Address2, MailCity AS City, MailState AS State, MailZipPlusExtension AS Zip, StreetAddress AS AltAddress, StreetCity AS AltCity, StreetState AS AltState, StreetZip AS AltZip, StreetCounty AS County, PrimarySic AS SIC1, PrimarySicDescription AS SIC1Description, Sic2 AS SIC2, Sic2Description, Sic3 AS SIC3, Sic3Description, ParentName AS Parent, RankedExecutive1Prefix AS Prefix, RankedExecutive1FirstName AS First, RankedExecutive1LastName AS Last, RankedExecutive1Suffix AS Suffix, RankedExecutive1TitleDescription AS Title, '' AS Division, ExportNameTxt AS Canvassed, ExportPreparedFor AS Salesperson FROM ContactHarris INNER JOIN ExportMaster ON ExportMaster.ExportID = ContactHarris.ExportID WHERE ContactHarris.ExportID='" & Request.QueryString("ID") & "'", myConnection) Dim dtTemplate1 As New DataTable() adapterTemplate1.Fill(dtTemplate1) doc.MailMerge.Execute(dtTemplate1) doc.MailMerge.DeleteFields() doc.Save(SavePath)
|
|
-
09-01-2010, 8:24 PM |
-
aske012
-
-
-
Joined on 03-30-2010
-
-
Posts 2,642
-
-
-
-
-
|
Re: Mail Merge with Page Breaks
Hi Ryan,
Thanks for your inquiry. This sounds possible, could you please attach your template, a few entires of your datasource and prehaps an example output here for testing and we will give you some suggestions.
Thanks,
Adam Skelton Programming Writer Aspose Auckland Team
|
|
-
09-02-2010, 7:40 AM |
-
regrossman
-
-
-
Joined on 07-19-2010
-
-
Posts 21
-
-
-
-
-
|
Re: Mail Merge with Page Breaks
Attachment: Present (inaccessible)
|
-
09-03-2010, 1:18 AM |
|
|
Re: Mail Merge with Page Breaks
Attachment: Present (inaccessible)
Hi
Thanks for your inquiry. Sure it is possible. To achieve this you should redesign your template a little and using Mail Merge with Regions instead of simple mail merge.
Attached is the modified template and here is the code:
// Get data.
string connectionsString = @"Driver={Microsoft Excel Driver (*.xls)};DriverId=790;Dbq=C:\Temp\datasource.xls;DefaultDir=C:\Temp;";
string queryString = "SELECT * FROM Data";
OdbcConnection connection = new OdbcConnection(connectionsString);
OdbcDataAdapter adapter = new OdbcDataAdapter(queryString, connection);
DataTable data = new DataTable();
adapter.Fill(data);
data.TableName = "Data";
// Open template.
Document doc = new Document(@"Test001\in.doc");
// Add MergeField callback.
doc.MailMerge.FieldMergingCallback = new HandleMergeField();
// Execute mail merge with regions.
doc.MailMerge.ExecuteWithRegions(data);
// Save output.
doc.Save(@"Test001\out.doc");
===================================================================
private class HandleMergeField : IFieldMergingCallback
{
void IFieldMergingCallback.FieldMerging(FieldMergingArgs args)
{
if(args.FieldName == "City")
{
mRecordIndex++;
string currentCity = args.FieldValue.ToString();
if((!string.IsNullOrEmpty(mCity) && mCity!=currentCity) || mRecordIndex>2)
{
mRecordIndex = 0;
// Move to the paragraph where the mergefied is located and set PageBreakBefore property.
DocumentBuilder builder = new DocumentBuilder(args.Document);
builder.MoveToField(args.Field, false);
builder.CurrentParagraph.ParagraphFormat.PageBreakBefore = true;
}
mCity = currentCity;
}
}
void IFieldMergingCallback.ImageFieldMerging(ImageFieldMergingArgs e)
{
// Do nothing.
}
private string mCity;
private int mRecordIndex;
}
Hope this helps.
Best regards.
Alexey Noskov Developer/Technical Support Aspose Auckland Team
|
|
-
09-07-2010, 12:46 PM |
-
regrossman
-
-
-
Joined on 07-19-2010
-
-
Posts 21
-
-
-
-
-
|
Re: Mail Merge with Page Breaks
Thanks for the sample code... My code is in VB so I had to convert it. I get no errors, however no data at all is saved into the template... Does the conversion look correct to you? I feel something in the handler may have gotten converted wrong.
Sub Dim doc As New Document("d:\hart11\templates\canvassing2.doc") Dim adapterTemplate1 As New SQLDataAdapter("SELECT '' AS SalesAmount, CompanyTxt AS Company, '' AS EmploymentThisSite, FaxDirectTxt AS Fax, '' AS Ownership, PhoneDirectTxt AS Phone, '' AS [Plant/FacilitySize], PhoneGeneralTxt AS Phone2, WebURL AS WebAddress, '' AS YearEstablished, '' AS OwnsRents, Address1Txt AS Address1, Address2Txt AS Address2, CityTxt As City, StateCode AS State, PostalCodeTxt As Zip, ShippingAddress1Txt AS AltAddress, ShippingCityTxt As AltCity, ShippingStateCode AS AltState, ShippingPostalCodeTxt AS AltZip, CountyTxt AS County, ContactSIC1Code AS SIC1, '' AS SIC1Description, ContactSIC2Code AS SIC2, '' AS Sic2Description, ContactSIC3Code AS SIC3, '' AS Sic3Description, ContactParentCompanyTxt AS Parent, PrefixTxt AS Prefix, FirstTxt AS First, LastTxt As Last, SuffixTxt AS Suffix, TitleTxt AS Title, DivisionTxt AS Division, ExportNameTxt AS Canvassed, ExportPreparedFor AS Salesperson FROM ViewContact INNER JOIN ExportDetail ON ExportDetail.ExportPrimaryRecordID = ViewContact.ContactID INNER JOIN ExportMaster ON ExportMaster.ExportID = ExportDetail.ExportID WHERE ExportDetail.ExportID='" & Request.QueryString("ID") & "' UNION SELECT [Sales Amount] AS SalesAmount, Company, EmploymentThisSite, REPLACE(Fax, '-', '') AS Fax, Ownership, REPLACE(Phone,'-','') AS Phone, [Plant/FacilitySize], TollFree AS Phone2, WebAddress, YearEstablished, OwnsRents, MailAddress AS Address1, '' AS Address2, MailCity AS City, MailState AS State, MailZipPlusExtension AS Zip, StreetAddress AS AltAddress, StreetCity AS AltCity, StreetState AS AltState, StreetZip AS AltZip, StreetCounty AS County, PrimarySic AS SIC1, PrimarySicDescription AS SIC1Description, Sic2 AS SIC2, Sic2Description, Sic3 AS SIC3, Sic3Description, ParentName AS Parent, RankedExecutive1Prefix AS Prefix, RankedExecutive1FirstName AS First, RankedExecutive1LastName AS Last, RankedExecutive1Suffix AS Suffix, RankedExecutive1TitleDescription AS Title, '' AS Division, ExportNameTxt AS Canvassed, ExportPreparedFor AS Salesperson FROM ContactHarris INNER JOIN ExportMaster ON ExportMaster.ExportID = ContactHarris.ExportID WHERE ContactHarris.ExportID='" & Request.QueryString("ID") & "' AND ContactHarris.Duplicate='' ORDER BY City ASC", myConnection) Dim dtTemplate1 As New DataTable() adapterTemplate1.Fill(dtTemplate1) 'doc.MailMerge.Execute(dtTemplate1) 'doc.MailMerge.DeleteFields() doc.MailMerge.FieldMergingCallback = New HandleMergeField() doc.MailMerge.ExecuteWithRegions(dtTemplate1) doc.Save(SavePath) End Sub
Private Class HandleMergeField Implements IFieldMergingCallback Private Sub FieldMerging(args As FieldMergingArgs) Implements IFieldMergingCallback.FieldMerging If args.FieldName = "City" Then mRecordIndex += 1
Dim currentCity As String = args.FieldValue.ToString() If (Not String.IsNullOrEmpty(mCity) AndAlso mCity <> currentCity) OrElse mRecordIndex > 2 Then mRecordIndex = 0 ' Move to the paragraph where the mergefied is located and set PageBreakBefore property. Dim builder As New DocumentBuilder(args.Document) builder.MoveToField(args.Field, False) builder.CurrentParagraph.ParagraphFormat.PageBreakBefore = True End If mCity = currentCity End If End Sub
Private Sub ImageFieldMerging(e As ImageFieldMergingArgs) Implements IFieldMergingCallback.ImageFieldMerging ' Do nothing. End Sub
Private mCity As String Private mRecordIndex As Integer End Class
|
|
-
09-07-2010, 12:58 PM |
-
regrossman
-
-
-
Joined on 07-19-2010
-
-
Posts 21
-
-
-
-
-
|
Re: Mail Merge with Page Breaks
Sorry, I found my issue. Was missing the TableName definition...
data.TableName = "Data"
What exactly does that line do? Is that the name of something within the template...
|
|
-
09-07-2010, 1:21 PM |
-
regrossman
-
-
-
Joined on 07-19-2010
-
-
Posts 21
-
-
-
-
-
|
Re: Mail Merge with Page Breaks
One thing I noticed is my merge fields in the header section of my document are not getting updated now. Do I have to create another Region area for handle that portion of the document?
|
|
-
09-07-2010, 1:30 PM |
|
|
Re: Mail Merge with Page Breaks
Hi
Thanks for your inquiry.
1. Yes, “Data” in your case is name of region in the document. Regions is part of document between “TableStart:XXX” and “TableEnd:XXX” merge fields, where XXX is name of region.
2. No, you do not need to create a separate region. Just execute simple mail merge after execution Mail Merge With Regions.
Best regards,
Alexey Noskov Developer/Technical Support Aspose Auckland Team
|
|
-
09-07-2010, 1:34 PM |
-
regrossman
-
-
-
Joined on 07-19-2010
-
-
Posts 21
-
-
-
-
-
|
Re: Mail Merge with Page Breaks
I get over 8000 page document when I add the normal mail merge info after the regions code...
Dim dtTemplate1 As New DataTable() adapterTemplate1.Fill(dtTemplate1) dtTemplate1.TableName = "Data" doc.MailMerge.FieldMergingCallback = New HandleMergeField() doc.MailMerge.ExecuteWithRegions(dtTemplate1) doc.MailMerge.Execute(dtTemplate1) 'doc.MailMerge.DeleteFields() doc.Save(SavePath)
|
|
-
09-07-2010, 1:45 PM |
|
|
Re: Mail Merge with Page Breaks
Hi
Thank you for additional information. Actually you do not need to execute simple mail merge with the same data source. As I remember in the header you have only few merge fields. So you need to select data for these merge fields into a separate data source (with only one data row) and execute simple mail merge with this data source.
Best regards.
Alexey Noskov Developer/Technical Support Aspose Auckland Team
|
|
-
09-07-2010, 1:57 PM |
-
09-08-2010, 6:06 PM |
-
regrossman
-
-
-
Joined on 07-19-2010
-
-
Posts 21
-
-
-
-
-
|
Re: Mail Merge with Page Breaks
Attachment: Present (inaccessible)
I've got another request. I now have my document created successfully. My users would like for the a table of contents to be inserted. They simply want the page number where each company is located at for quick reference. How would something like this be accomplished?
I was trying to come up with a way to do in in the SQL query (basically count how many people and estimate which page they should be on but it hasnt worked out yet).
I attached a completed canvassing file for reference.
BTW, still cant get over how amazing this product is!
|
|
-
09-08-2010, 9:28 PM |
-
regrossman
-
-
-
Joined on 07-19-2010
-
-
Posts 21
-
-
-
-
-
|
Re: Mail Merge with Page Breaks
It seems maybe a Table of Contents could solve this for me? I dont know how the table of contents should work though with the merge fields. I would like To have each Company name listed along with the page number...
|
|
-
09-09-2010, 2:43 AM |
|
|
Re: Mail Merge with Page Breaks
Attachment: Present (inaccessible)
Hi
Thanks for your inquiry. I think the best way to achieve what you need it building TOC using TOC entries. You can insert TOC entries (TC fields) from the code during executing mail merge.
The only one thing you need to change in your template is inserting TOC field like the following:
{ TOC \f \h }
Here is the modified code:
// Get data.
string connectionsString = @"Driver={Microsoft Excel Driver (*.xls)};DriverId=790;Dbq=C:\Temp\datasource.xls;DefaultDir=C:\Temp;";
string queryString = "SELECT * FROM Data";
OdbcConnection connection = new OdbcConnection(connectionsString);
OdbcDataAdapter adapter = new OdbcDataAdapter(queryString, connection);
DataTable data = new DataTable();
adapter.Fill(data);
data.TableName = "Data";
// Open template.
Document doc = new Document(@"C:\Temp\in.doc");
// Add MergeField callback.
doc.MailMerge.FieldMergingCallback = new HandleMergeField();
// Execute mail merge with regions.
doc.MailMerge.ExecuteWithRegions(data);
// Execute simple mail merge to fill the header with data.
doc.MailMerge.Execute(new string[] { "Canvassed", "Salesperson" }, new object[] { "test", "James Bond" });
// Update page layout to update page numbers in TOC.
doc.UpdatePageLayout();
// Save output.
doc.Save(@"C:\Temp\out.doc");
==================================================================
private class HandleMergeField : IFieldMergingCallback
{
void IFieldMergingCallback.FieldMerging(FieldMergingArgs args)
{
DocumentBuilder builder = new DocumentBuilder(args.Document);
if(args.FieldName == "City")
{
string currentCity = args.FieldValue.ToString();
// Move to the paragraph where the mergefied is located.
builder.MoveToField(args.Field, false);
mRecordIndex++;
if((!string.IsNullOrEmpty(mCity) && mCity!=currentCity) || mRecordIndex>2)
{
mRecordIndex = 0;
// Set PageBreakBefore property.
builder.CurrentParagraph.ParagraphFormat.PageBreakBefore = true;
}
// Insert TC field to build TOC. Insert TC only if this is the first time when City occur.
if (mCity != currentCity)
{
// Get current cell and move builder to the beginning of it.
Cell cell = (Cell)builder.CurrentParagraph.GetAncestor(NodeType.Cell);
builder.MoveTo(cell.FirstParagraph.FirstChild);
builder.InsertField(string.Format("TC \"{0}\" \\l 1", args.FieldValue));
}
mCity = currentCity;
}
// Also insert TC field for each company.
if(args.FieldName == "Company")
{
// Move to the paragraph where the mergefied is located.
builder.MoveToField(args.Field, false);
// Companies is the second level of TOC.
builder.InsertField(string.Format("TC \"{0}\" \\l 2", args.FieldValue));
}
}
void IFieldMergingCallback.ImageFieldMerging(ImageFieldMergingArgs e)
{
// Do nothing.
}
private string mCity;
private int mRecordIndex;
}
I highlighted my changes in the code and attached the modified template. Hope this helps.
Best regards,
Alexey Noskov Developer/Technical Support Aspose Auckland Team
|
|
-
09-09-2010, 9:42 AM |
-
regrossman
-
-
-
Joined on 07-19-2010
-
-
Posts 21
-
-
-
-
-
|
Re: Mail Merge with Page Breaks
Getting the following error. I assume it has somethign to do with Aspose Cells and Words being on this page?
Compiler Error Message: BC30311: Value of type 'Aspose.Words.Node' cannot be converted to 'Aspose.Cells.Cell'.
Source Error:
| Line 542: If mCity <> currentCity Then
Line 543: ' Get current cell and move builder to the beginning of it.
Line 544: Dim cell As Cell = DirectCast(builder.CurrentParagraph.GetAncestor(NodeType.Cell), Cell)
Line 545: builder.MoveTo(cell.FirstParagraph.FirstChild)
Line 546: builder.InsertField(String.Format("TC ""{0}"" \l 1", args.FieldValue)) |
|
|
Page 1 of 2 (24 items)
1
|
|