Delete Section of a document

I have a template which I’m attaching for reference. Depending on a value in SQL query, I would like to delete a section of the word document. Is this possible? If not, what I planned to do was to make all the titles merge fields and populate the titles from my query, but when I do so, the table rows where the merge fields are remain. I would like to make the row shrink up in those cases.

In the template there is a section called Transaction Information. In my query there is a field ListingStatus. If this field is equal not equal to available, I want to supress that entire ListingStatus area…

Hi Ryan,
Thanks for your inquiry.
It’s not quite clear exactly what area you want removed from the document as there is no “ListingStatus” fields or rows in the document. You could please clarify this?
Most likely to achieve this you should insert a bookmark into the template which encloses the area you want removed. Then you can check for the appropriate merge field during merging and check it value. If this value does not match you can then remove the content of the bookmark from the document.
Thanks,

Not sure if this will really help you, but I asked a similar question last month:

https://forum.aspose.com/t/filter-within-merge/61802

The solution posted there works for my use, and could be expanded to remove entire table rather than just row, you could then format your document accordingly.

I basically want to remove the Table under the heading Transaction Information if the merge field ProperyInfo which is at the top of the document is not equal to Available.

I have been playing around with placing a bookmark inside the table but I either get region errors or it deletes to much out of the document.

'Dim bk As Aspose.Words.Bookmark = doc.Range.Bookmarks("RIDERPLANS_BOOKMARK")

'If bk IsNot Nothing Then
' Get table, where bookmark is located.
' Dim table As Node = bk.BookmarkStart.GetAncestor(NodeType.Table)

' If table IsNot Nothing Then
' table.Remove()
' End If
'End If

That code above seemed to work but I cannot get it adapted to work within a document builder…

Also tried

builder.MoveToBookmark("test")
Dim table As Node = builder.CurrentParagraph.GetAncestor(NodeType.Table)
table.Remove()

which didnt work.

Hi Ryan,
Thanks for this additional information. I think there may be two methods depending upon if you want the whole Transaction information table removed or just the content below the title (which is contained in sub tables inside this main table).
I have made two sample documents which demonstrate both situations. I have sent them to your inbox.
The code for the first case, removing the entire table:

// Get the bookmark
Bookmark bookmark = doc.Range.Bookmarks["RIDERPLANS_BOOKMARK"];
// Get the table that this bookmark is contained in.
Table tabletest = (Table) bookmark.BookmarkStart.GetAncestor(NodeType.Table);
// Remove the table
tabletest.Remove();

For the second case when removing only the subtables:

// Get the bookmark.
Bookmark bookmark = doc.Range.Bookmarks["RIDERPLANS_BOOKMARK"];
// Get the table which contains this bookmark.
Table parentTable = (Table) bookmark.BookmarkStart.GetAncestor(NodeType.Table);
// Select all table nodes who are descendants of this table.
// Use ToArray so we don't invalidate the enumuator when removing nodes which otherwise will cause the loop to halt
Node[] nodeArray = parentTable.SelectNodes(".//Table").ToArray();
// Remove each sub table.
foreach(Table table in nodeArray)
    table.Remove();

There is really no way to remove the content from a bookmark using DocumentBuilder, this is because as the name suggests, its main use is to build and not to remove content :slight_smile:
Seph, thank you for suggesting this code as well. This may come in handy for him.
Please feel free to ask if you have any further problems.
Thanks,

How do I implement either solution with my current data structure? Some records in the dataset will meet the criteria to remove the area, some won’t and dont need anything removed. Can that code my placed directly in a mergecallback?

Current Code:

Dim dtTemplate1 As New DataTable()
adapterTemplate1.Fill(dtTemplate1)
Dim recordCount As Integer
recordCount = dtTemplate1.Rows.Count
dtTemplate1.TableName = "Summary"
doc.MailMerge.FieldMergingCallback = New HandleMergeFieldSummary1()
doc.MailMerge.FieldMergingCallback = New HandleMergeFieldProfile1()
doc.MailMerge.ExecuteWithRegions(dtTemplate1)
doc.MailMerge.Execute(New String() {"Name", "RecordCount", "PreparedBy", "PreparedFor"}, New Object() {rcbExportNameTxt.Text, recordCount, rcbPreparedBy.Text, rcbPreparedFor.Text})
doc.MailMerge.DeleteFields()

If qExportTemplateID = "33" Or qExportTemplateID = "35" Or qExportTemplateID = "37" Or qExportTemplateID = "39" Or qExportTemplateID = "43" Or qExportTemplateID = "45" Or qExportTemplateID = "47" Or qExportTemplateID = "49" Or qExportTemplateID = "51" Then
    doc.Save(REPLACE(SavePath, "doc", "pdf"))
Else
    doc.Save(SavePath)
End If
Private Class HandleMergeFieldSummary1
    Implements IFieldMergingCallback
    Dim mIsMergeImage As Boolean = False
    Private Sub FieldMerging(args As FieldMergingArgs) Implements IFieldMergingCallback.FieldMerging
        If args.FieldName = "SaleTypeTxt" Then
            If args.FieldValue = "Hart Exclusive Agency" Then

                mIsMergeImage = True
            Else
                mIsMergeImage = False
            End If
        End If
    End Sub

    Private Sub ImageFieldMerging(e As ImageFieldMergingArgs) Implements IFieldMergingCallback.ImageFieldMerging

        If (mIsMergeImage) Then
            e.ImageFileName = System.IO.Path.Combine("d:\hart11\images", "hartlogoxsmall.gif")

        End If
    End Sub
End Class

Private Class HandleMergeFieldProfile1
    Implements IFieldMergingCallback
    Private Sub FieldMerging(args As FieldMergingArgs) Implements IFieldMergingCallback.FieldMerging
        Dim builder As New DocumentBuilder(args.Document)
        If args.FieldName = "P1" Then
            Dim P1s As String = args.FieldValue.ToString()
            If P1s > "" And System.IO.File.Exists(P1s) Then

            Else
                P1s = "D:\hart11\filecabinet\property\default.jpg"

            End If
            Dim img As System.Drawing.Image
            builder.MoveToField(args.Field, True)
            img = System.Drawing.Image.FromFile(P1s)
            Dim shape As Aspose.Words.Drawing.Shape = builder.InsertImage(img, 275, 125)
            shape.WrapType = "5"

        End If

    End Sub

    Private Sub ImageFieldMerging(e As ImageFieldMergingArgs) Implements IFieldMergingCallback.ImageFieldMerging

        ' Do nothing.
    End Sub
End Class

Hi Ryan,
Thanks for this additional information. Yes you can simply insert that logic into your existing handlers. Please note, because the handlers are implementing interfaces now instead of delegates, I don’t believe setting more than one handler will work. I’m pretty sure only HandleMergeFieldProfile1 is being called in your code above.
Below is the code that you can use to implement the logic inside your merging handler. Both code examples go inside the FieldMerging method.
Method one:

' Get the bookmark
Dim bookmark As Bookmark = args.Document.Range.Bookmarks("RIDERPLANS_BOOKMARK")
' Get the table that this bookmark is contained in.
Dim parentTable As Table = CType(bookmark.BookmarkStart.GetAncestor(NodeType.Table), Table)
' Remove the table
parentTable.Remove()

Method two:

If args.FieldName.Equals("SaleActualPriceInt") Then
    ' For this situation the bookmark will be duplicated with each growth of the region. Since the whole table isn't
    ' removed with each merge the original bookmark will remain. We need to look through all bookmarks with the appropriate name
    ' and pick the last bookmark as that will be the one corresponding to
    Dim bookmarks As BookmarkCollection = args.Document.Range.Bookmarks
    Dim targetBookmarks As New ArrayList()

    For Each bookmark As Bookmark In bookmarks
        If bookmark.Name.Equals("RIDERPLANS_BOOKMARK") Then
            targetBookmarks.Add(bookmark)
        End If
    Next bookmark
    ' Get the bookmark
    Dim targetBookmark As Bookmark = CType(targetBookmarks(targetBookmarks.Count - 1), Bookmark)

    ' Get the table which contains this bookmark.
    Dim parentTable As Table = CType(targetBookmark.BookmarkStart.GetAncestor(NodeType.Table), Table)

    ' Select all table nodes who are descendants of this table.
    ' Use ToArray so we don't invalidate the enumuator when removing nodes which otherwise will cause the loop to halt
    Dim nodeArray() As Node = parentTable.SelectNodes(".//Table").ToArray()

    ' Remove each sub table.
    For Each table As Table In nodeArray
        table.Remove()
    Next table
End If

Thanks,

I tried method 1:
I do have a bookmark in my template named: SalePriceTitle
Object reference not set to an instance of an object.

Dim bookmark As Aspose.Words.Bookmark = args.Document.Range.Bookmarks("SalePriceTitle")
Dim parentTable As Aspose.Words.Tables.Table = CType(bookmark.BookmarkStart.GetAncestor(NodeType.Table), Aspose.Words.Tables.Table)
parentTable.Remove()

The code below is working for me:

Dim bk As Aspose.Words.Bookmark = args.Document.Range.Bookmarks("TransDate")

If bk IsNot Nothing Then
    Dim table As Node = bk.BookmarkStart.GetAncestor(NodeType.Table)

    If table IsNot Nothing Then
        table.Remove()
    End If
End If

Can you alter this to show me how to just remove the row where the bookmark is located?

Hi

Thanks for your inquiry. The code is the same:

Dim bk As Aspose.Words.Bookmark = args.Document.Range.Bookmarks("TransDate")

If bk IsNot Nothing Then
    Dim row As Node = bk.BookmarkStart.GetAncestor(NodeType.Row)

    If row IsNot Nothing Then
        row.Remove()
    End If
End If

Best regards,

Something isnt right… Maybe its the bookmarks causing the issue. I’m attaching my template and output so you can see. In the code I tell it to locate the bookmark and remove, only if the merge field PropertyInfo which is at the top of the document is LIKE “Available*”. The first property is correct, but the second property is Sold and the row is removed, as is the third property which is leased and it stripped, then after that, the last 2 properties look like they were ignored completely. The bookmark remains.

Dim dtTemplate1 As New DataTable()
adapterTemplate1.Fill(dtTemplate1)
Dim recordCount As Integer
recordCount = dtTemplate1.Rows.Count
dtTemplate1.TableName = "Summary"
doc.MailMerge.FieldMergingCallback = New HandleMergeFieldSummary()
doc.MailMerge.ExecuteWithRegions(dtTemplate1)
doc.MailMerge.Execute(New String() {"Name", "RecordCount", "PreparedBy", "PreparedFor"}, New Object() {rcbExportNameTxt.Text, recordCount, rcbPreparedBy.Text, rcbPreparedFor.Text})
doc.MailMerge.DeleteFields()
doc.Save(SavePath)
Private Class HandleMergeFieldSummary
    Implements IFieldMergingCallback
    Dim mIsMergeImage As Boolean = False
    Private Sub FieldMerging(args As FieldMergingArgs) Implements IFieldMergingCallback.FieldMerging
        If args.FieldName = "SaleTypeTxt" Then
            If args.FieldValue = "Hart Exclusive Agency" Then

                mIsMergeImage = True
            Else
                mIsMergeImage = False
            End If
        End If
        Dim builder As New DocumentBuilder(args.Document)
        If args.FieldName = "P1" Then
            Dim P1s As String = args.FieldValue.ToString()
            If P1s > "" And System.IO.File.Exists(P1s) Then

            Else
                P1s = "D:\hart11\filecabinet\property\default.gif"

            End If
            Dim img As System.Drawing.Image
            builder.MoveToField(args.Field, True)
            img = System.Drawing.Image.FromFile(P1s)
            Dim shape As Aspose.Words.Drawing.Shape = builder.InsertImage(img, 275, 125)
            shape.WrapType = "5"

        End If
        If args.FieldName = "PropertyInfo" Then
            If args.FieldValue Like "Available*" Then
                Dim bk3 As Aspose.Words.Bookmark = args.Document.Range.Bookmarks("bkTransactionInformation")

                If bk3 IsNot Nothing Then
                    Dim row As Node = bk3.BookmarkStart.GetAncestor(NodeType.Row)

                    If row IsNot Nothing Then
                        row.Remove()
                    End If

                End If
            End If
        End If

    End Sub

    Private Sub ImageFieldMerging(e As ImageFieldMergingArgs) Implements IFieldMergingCallback.ImageFieldMerging

        If (mIsMergeImage) Then
            e.ImageFileName = System.IO.Path.Combine("d:\hart11\images", "hartlogoxsmall.gif")

        End If
    End Sub
End Class

In the output file, you will see the red bar titled Transaction Information should be missing on any properties that have Available in the PropertyInfo field (the text in small caps in the upper right hand corner of the page).

Hi Ryan,
Thanks for the additonal information.
I’m afraid it appears that you have attached the wrong template, as it does not look anything like the output and does not have the appropriate bookmark or field in it.
Please post your template and I will be glad to assist further.
Thanks,

Here it is…

Hi Ryan,
Thanks for posting your template here.
This is happening because if the row is not removed (PropertyInfo is “Sold”) then the bookmark remains and is then retrieved as the bookmark for the next merge which causes the wrong row to be removed.
Please use the code below:

If args.FieldName.Equals("PropertyInfo") Then
    Dim bk3 As Bookmark = args.Document.Range.Bookmarks("bkTransactionInformation")
    Dim row As Row = CType(bk3.BookmarkStart.GetAncestor(NodeType.Row), Row)
    If args.FieldValue Like "Available*" Then

        If row IsNot Nothing Then
            row.Remove()
        End If
    Else
        row.Range.Bookmarks(0).Remove()
    End If
End If
End If

Thanks,

This is working well for me so far… Thanks for the solution.