Merge ASK field value

Hi, we have a document which contains ASK and Fill-in fields. I figure out how to convert Fill-in fields to merged fields to work during mail-merge process but I cannot figure out how it can work with ASK field.
I have the answers for ASK fields, and I want to replace during the merge process.
Should I convert the ASK field to bookmark? I appreciate any recommendation here

@minaeimi You can use code like the following to work with FieldAsk:

Document doc = new Document(@"C:\Temp\in.docx");
            
// Loop through the fields in the document.
foreach (Field field in doc.Range.Fields)
{
    if (field.Start.FieldType == FieldType.FieldAsk)
    {
        FieldAsk ask = (FieldAsk)field;
                    
        // Get the question.
        Console.WriteLine(ask.PromptText);

        // Set the value.
        doc.Range.Bookmarks[ask.BookmarkName].Text = "Hello, world!!!";
    }
}

doc.Save(@"C:\Temp\out.docx");

Hi Alexey,

Thanks for your reply.
Strangely docOrg.getRange().getBookmarks() doesn’t return back all the bookmarks.
Is there any reason?

@minaeimi Most likely, you are using Aspose.Words in evaluation mode and the document is truncated due to the evaluation version limitation. You can request a temporary license to test Aspose.Words without evaluation version restrictions.

To make it more clear, I have following code in the word file.
{ASK BASS “If the company has employees enter ‘1’ otherwise leave blank”}{IF {REF BASS *MERGEFORMAT}= “1” “the company has employees.” “”}

In our application we know the answer for “If the company has employees enter ‘1’ otherwise leave blank”, and during mail marge based on that answer which is either 1 or blank the correct text should be displayed.

I tried your code, but docOrg.getRange().getBookmarks() function doesn’t return BASS as bookmark.
Any help is appreciated.

thanks for your reply. No we have product family license, we bought it few 2 days ago.

@minaeimi Please attach your document here for testing. We will check the issue and provide you more information.

@alexey.noskov how I can send it to you privately? I am not allowed to share it on public forum.

@minaeimi It is safe to attach documents in the forum. Your attachments can be downloaded only by you and Aspose staff.

Mina_test1.docx (57.4 KB)
@alexey.noskov I attached the word file.

@minaeimi Thank you for additional information. In your document there is an ASK field without bookmark. Here is a part of XML of your document:

<w:r w:rsidRPr="00E3367D">
	<w:fldChar w:fldCharType="begin"/>
</w:r>
<w:r w:rsidRPr="00E3367D">
	<w:instrText xml:space="preserve"> ASK  BOB "If money laundering checks are done electronically, enter '1' otherwise, if you want copies of passports etc, leave blank"</w:instrText>
</w:r>
<w:r w:rsidRPr="00E3367D">
	<w:fldChar w:fldCharType="separate"/>
</w:r>
<w:r w:rsidRPr="00E3367D">
	<w:t>a.m.</w:t>
</w:r>
<w:r w:rsidRPr="00E3367D">
	<w:fldChar w:fldCharType="end"/>
</w:r>

As you can see field value of the ASK field does not have a bookmark. If you update fields in the document using MS Word, it automatically creates a bookmark and in the XML you will see the following:

<w:r w:rsidRPr="00E3367D">
	<w:fldChar w:fldCharType="begin"/>
</w:r>
<w:r w:rsidRPr="00E3367D">
	<w:instrText xml:space="preserve"> ASK  BOB "If money laundering checks are done electronically, enter '1' otherwise, if you want copies of passports etc, leave blank"</w:instrText>
</w:r>
<w:r w:rsidRPr="00E3367D">
	<w:fldChar w:fldCharType="separate"/>
</w:r>
<w:bookmarkStart w:id="0" w:name="BOB"/>
<w:r w:rsidR="00263C94">
	<w:t>a.m.test</w:t>
</w:r>
<w:bookmarkEnd w:id="0"/>
<w:r w:rsidRPr="00E3367D">
	<w:fldChar w:fldCharType="end"/>
</w:r>

As you can see bookmark BOB was created.
You can achieve the same using Aspose.Words. For example see the following code:

Document doc = new Document(@"C:\Temp\in.docx");
DocumentBuilder builder = new DocumentBuilder(doc);

// Loop through the fields in the document.
foreach (Field field in doc.Range.Fields)
{
    if (field.Start.FieldType == FieldType.FieldAsk)
    {
        FieldAsk ask = (FieldAsk)field;

        if (doc.Range.Bookmarks[ask.BookmarkName] == null)
        {
            ask.Result = "";
            builder.MoveTo(ask.End);
            builder.StartBookmark(ask.BookmarkName);
            builder.EndBookmark(ask.BookmarkName);
        }

        // Set the value.
        doc.Range.Bookmarks[ask.BookmarkName].Text = "Hello, world!!!";
    }
}

doc.Save(@"C:\Temp\out.docx");

Many thanks @alexey.noskov it works fine.

Hi @alexey.noskov, I spotted another issue in our word file. After merging there is an error " Error! Bookmark not defined". But the bookmark is define.
image.png (7.5 KB)
I 'll attach the word file DWMergeTest.docx (12.3 KB)

@minaeimi The problem is that the bookmark is in incorrect place.

<w:r>
	<w:fldChar w:fldCharType="begin"/>
</w:r>
<w:r>
	<w:instrText xml:space="preserve"> </w:instrText>
</w:r>
<w:bookmarkStart w:id="0" w:name="Q1"/>
<w:bookmarkEnd w:id="0"/>
<w:r>
	<w:instrText xml:space="preserve">ASK  Q1 "Enter ask answer"  \* MERGEFORMAT </w:instrText>
</w:r>
<w:r w:rsidR="00C635D5">
	<w:fldChar w:fldCharType="separate"/>
</w:r>
<w:r w:rsidR="00C635D5">
	<w:t>hi</w:t>
</w:r>
<w:r>
	<w:fldChar w:fldCharType="end"/>
</w:r>

The bookmark is between ASK field start and separator, i.e. in the field code, but it is expected that the bookmark is in the field result - between field separator and field end.
If update fields in MS Word, it fixes this and puts the bookmark in the correct place:

<w:r>
	<w:fldChar w:fldCharType="begin"/>
</w:r>
<w:r>
	<w:instrText xml:space="preserve"> ASK  Q1 "Enter ask answer"  \* MERGEFORMAT </w:instrText>
</w:r>
<w:r>
	<w:fldChar w:fldCharType="separate"/>
</w:r>
<w:bookmarkStart w:id="0" w:name="Q1"/>
<w:r w:rsidR="007B62E2">
	<w:t>test</w:t>
</w:r>
<w:bookmarkEnd w:id="0"/>
<w:r>
	<w:fldChar w:fldCharType="end"/>
</w:r>

@alexey.noskov thanks. but how the end-user knows that the word file is not correct. is there any way for validating the word file before merging to inform the user?

@minaeimi I think, to make sure the bookmark is in the correct place, you can simply remove the bookmark and insert it using the same code as you use when there is no bookmark. Please see the following modified code:

Document doc = new Document(@"C:\Temp\in.docx");
DocumentBuilder builder = new DocumentBuilder(doc);

// Loop through the fields in the document.
foreach (Field field in doc.Range.Fields)
{
    if (field.Start.FieldType == FieldType.FieldAsk)
    {
        FieldAsk ask = (FieldAsk)field;

        // Remove and then recreate bookmark to make sure it is in the correct place.
        if (doc.Range.Bookmarks[ask.BookmarkName] != null)
            doc.Range.Bookmarks[ask.BookmarkName].Remove();

        ask.Result = "";
        builder.MoveTo(ask.End);
        builder.StartBookmark(ask.BookmarkName);
        builder.EndBookmark(ask.BookmarkName);

        // Set the value.
        doc.Range.Bookmarks[ask.BookmarkName].Text = "Hello, world!!!";
    }
}

doc.UpdateFields();
doc.Save(@"C:\Temp\out.docx");

@alexey.noskov we checked Word native merging and we found that actually it doesn’t require to add bookmark and we believe it is aspose regression. can you please confirm that?

@minaeimi MS Word always creates a bookmark for ASK field when you update the field. Later this bookmark is used to reference the answer of ASK field. Here is how MS Word inserts ASK field:

<w:r>
	<w:fldChar w:fldCharType="begin"/>
</w:r>
<w:r>
	<w:instrText xml:space="preserve"> ASK  name "What is your name"  \* MERGEFORMAT </w:instrText>
</w:r>
<w:r>
	<w:fldChar w:fldCharType="separate"/>
</w:r>
<w:bookmarkStart w:id="0" w:name="name"/>
<w:r>
	<w:t>Alexey</w:t>
</w:r>
<w:bookmarkEnd w:id="0"/>
<w:r>
	<w:fldChar w:fldCharType="end"/>
</w:r>

As you can see the field result is surrounded with bookmark. If you manually remove this bookmark and try to update fields in MS Word, it will recreate the bookmark again since it is used to store the answer.
https://support.microsoft.com/en-us/office/field-codes-ask-field-31b8d920-978c-4aba-9dd7-68dd81ffd943
So to properly work with ASK field the bookmark is required and MS Word always create it if it does not exist - the same as the suggested code does.

@alexey.noskov thanks for the information. The problem is we have more lots of word file(for example 1000) and we cannot ask the customer to go through all of them and create bookmarks if there is not any.
I think the solution for us is before merge we scan the document, and if the bookmark doesn’t exist, we create it in the code.

@minaeimi Thank you for additional information. The suggested code works correctly with FILLIN fields in all cases: if there is a bookmark, if there is no bookmark and if there is a bookmark in incorrect location. So you can use this code to fill the FILLIN fields in all these cases.
The idea of the code is to remove bookmark from FILLIN field and then create it again in the correct place. Please let us know if the code does not work as expected in your scenarios.