Sign UpSign Up   Sign InSign In Welcome Guest,
Live Chat Live Chat

Mail Merge with Page Breaks

Last post 09-10-2010, 11:24 AM by AndreyN. 23 replies.
Page 1 of 2 (24 items)   1 2 Next >
Sort Posts: Previous Next
  •  09-01-2010, 6:36 PM 256687

    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 256702 in reply to 256687

    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 256817 in reply to 256702

    Re: Mail Merge with Page Breaks

    Attachment: Present (inaccessible)
    Attached...
     
  •  09-03-2010, 1:18 AM 256911 in reply to 256817

    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 257422 in reply to 256911

    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 257425 in reply to 257422

    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 257430 in reply to 257425

    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 257433 in reply to 257430

    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 257434 in reply to 257430

    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 257437 in reply to 257434

    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 257439 in reply to 257437

    Re: Mail Merge with Page Breaks

    Got it... Thanks!
     
  •  09-08-2010, 6:06 PM 257690 in reply to 257439

    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 257706 in reply to 257690

    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 257735 in reply to 257706

    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 257839 in reply to 257735

    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 2 Next >
View as RSS news feed in XML