Bold format and number format not applying to text in range. replace

Hi Team,

I am trying to replace a matching text with another text using range. replace. I am not using any document builder but directly giving the text in the replace method as below

doc_MngLetter.Range.Replace("[Insert Action required from option below]", "I note that the above breach has been rectified, no further action required." + ControlChar.LineBreak + ControlChar.LineBreak + "[Section/Regulation number] – [Description]", false, false);

[Insert Action required from option below] - This is the text which needs to be matched

"I note that the above breach has been rectified, no further action required."
+ ControlChar.LineBreak + ControlChar.LineBreak + "[Section/Regulation number] – [Description]" –** This is the text which will be replacing the above text ([Insert Action required from option below]).

Issue here is i am trying to add bold font to [Section/Regulation number] – [Description] but it is not applying . I tried using " [Section/Regulation number] – [Description] .

Can you provide me the solution for this and also i need to add numbering.

*HarishKumar.A:
Hi Team,

I am trying to replace a matching text with another text using range. replace. I am not using any document builder but directly giving the text in the replace method as below
doc_MngLetter.Range.Replace("[Insert Action required from option below]", "I note that the above breach has been rectified, no further action required."
+ ControlChar.LineBreak + ControlChar.LineBreak + “[Section/Regulation number] – [Description]”, false, false);

[Insert Action required from option below] - This is the text which needs to be matched

"I note that the above breach has been rectified, no further action required."
+ ControlChar.LineBreak + ControlChar.LineBreak + “[Section/Regulation number] – [Description]” – This is the text which will be replacing the above text ([Insert Action required from option below]).

Issue here is i am trying to add bold font to [Section/Regulation number] – [Description] but it is not applying . I tried using " [Section/Regulation number] – [Description] .

Can you provide me the solution for this and also i need to add numbering.*

Hi Harish,

Thanks for your inquiry. The font formatting of text will be applied according to matched node when you use Range.Replace method (String, String, Boolean, Boolean).

You need to implement IReplacingCallback and use DocumentBuilder to insert the contents according to your requirements. Please check example of IReplacingCallback from following documentation link.
How to Find and Highlight Text

Hi Tahir,

The example given in the reply is finding a particular text and just highlighting. But my requirement is different i have a specific text in a template and my code will find it and replace that particular text with original text from database which is happening correctly. I have to bold some text in the replaced text from database which i am not able to do.

your example is like find some text (your document ) and highlight it. But my issue is (your document will be replaced with my document from database and i need to high light the text "database " to bold). please help me on how to achieve this.

Hi Harish,

Thanks for your inquiry. The shared documentation link is just for your reference about using IReplacingCallback. We have modified the code example according to your requirement and have attached input and output documents with this post. Hope this helps you. You may modify the highlighted code snippet according to your requirements.

Document doc = new Document(MyDir + "in.docx");
String[] newcontents = { "New contents ", "Bold contents" };
Regex regex = new Regex("Insert Action required from option below", RegexOptions.IgnoreCase);
doc.Range.Replace(regex, new ReplaceEvaluatorTest001(newcontents), false);
doc.Save(MyDir + "Out.docx");
private class ReplaceEvaluatorTest001 : IReplacingCallback
{
    String[] newcontents;
    public ReplaceEvaluatorTest001(String[] contents)
    {
        newcontents = contents;
    }
    ReplaceAction IReplacingCallback.Replacing(ReplacingArgs e)
    {
        // This is a Run node that contains either the beginning or the complete match.
        Node currentNode = e.MatchNode;
        // The first (and may be the only) run can contain text before the match, 
        // in this case it is necessary to split the run.
        if (e.MatchOffset > 0)
            currentNode = SplitRun((Run)currentNode, e.MatchOffset);
        ArrayList runs = new ArrayList();
        // Find all runs that contain parts of the match string.
        int remainingLength = e.Match.Value.Length;
        while (
        (remainingLength > 0) &&
        (currentNode != null) &&
        (currentNode.GetText().Length <= remainingLength))
        {
            runs.Add(currentNode);
            remainingLength = remainingLength - currentNode.GetText().Length;
            // Select the next Run node. 
            // Have to loop because there could be other nodes such as BookmarkStart etc.
            do
            {
                currentNode = currentNode.NextSibling;
            }
            while ((currentNode != null) && (currentNode.NodeType != NodeType.Run));
        }
        // Split the last run that contains the match if there is any text left.
        if ((currentNode != null) && (remainingLength > 0))
        {
            SplitRun((Run)currentNode, remainingLength);
            runs.Add(currentNode);
        }
        // Create Document Buidler 
        DocumentBuilder builder = new DocumentBuilder(e.MatchNode.Document as Document);
        builder.MoveTo((Run)runs[runs.Count - 1]);
        builder.Write(newcontents[0]);
        builder.Font.Bold = true;
        builder.Write(newcontents[1]);
        builder.Font.Bold = false;
        foreach (Run run in runs)
            run.Remove();
        // Signal to the replace engine to do nothing because we have already done all what we wanted.
        return ReplaceAction.Skip;
    }
    private static Run SplitRun(Run run, int position)
    {
        Run afterRun = (Run)run.Clone(true);
        afterRun.Text = run.Text.Substring(position);
        run.Text = run.Text.Substring(0, position);
        run.ParentNode.InsertAfter(afterRun, run);
        return afterRun;
    }
}

Hi Tahir,

I tried implementing based on the given code, but still i am not able to generate the file. Instead the code is not returning any generated file and the code is iterating.
Attached my template. Can you help me what is the issue in this.Below is the code

var MngLetter_Issues = Server.MapPath("~/App_Data/Template/Management Letter.docx");
Document doc_MngLetter = new Document(MngLetter_Issues);

doc_MngLetter.Range.Replace("[Matters Inclusion]", "Summary for year ended " + DateTime.Now.ToShortDateString() + ".", false, false);
int issueCounter = 0;
foreach (var issue in selectedFundIssues)
{
    doc_MngLetter.Range.Replace("[Section/Regulation number] – [Description]", issue.Issue.SISSection.SISSection + "-" + issue.Issue.IssueName, false, false);

    doc_MngLetter.Range.Replace("[Insert succinct summary of matter]", issue.Issue.ManagementDescription, false, false);

    // rule set to Insert conclusion of impact on audit opinion from below list:
    doc_MngLetter.Range.Replace("[Insert conclusion of impact on audit opinion from below list:]", "This event has not resulted in a qualified audit opinion and is not reportable under the ATO reporting guidelines.", false, false);

    // rule set to Insert Action required from option below
    if (issueCounter < (selectedFundIssues.Count - 1))
    {
        String[] newcontents = { issue.Issue.Mgmt_ActionRequired, "[Section/Regulation number] – [Description]", "[Insert succinct summary of matter]", "[Insert conclusion of impact on audit opinion from below list:]", "Action Required", "[Insert Action required from option below]" };
        Regex regex = new Regex("[Insert Action required from option below]", RegexOptions.IgnoreCase);
        doc_MngLetter.Range.Replace(regex, new ReplaceEvaluator(newcontents), false);
    }
}
else
{
    if (issue.IsManagement && (issue.IsAuditOpinion_PartA || issue.IsAuditOpinion_PartB || (issue.IsAuditOpinion_PartA && issue.IsAuditOpinion_PartB)) && !issue.IsRestricted)
        doc_MngLetter.Range.Replace("[Insert Action required from option below]", issue.Issue.Mgmt_ActionRequired, false, false);
}

issueCounter++;
}
}
else
{
    // doc_MngLetter.Range.Replace("This sentence only applies if there are no issues. Default.", "", false, false);
    doc_MngLetter.Range.Replace("[Matters Inclusion]", "End" + DateTime.Now.ToShortDateString() + ".", false, false);
    doc_MngLetter.Range.Replace("[Section/Regulation number] – [Description]", string.Empty, false, false);
    doc_MngLetter.Range.Replace("[Insert succinct summary of matter]", string.Empty, false, false);
    // rule 1
    doc_MngLetter.Range.Replace("[Insert conclusion of impact on audit opinion from below list:]", string.Empty, false, false);
    doc_MngLetter.Range.Replace("Action Required", string.Empty, false, false);
    doc_MngLetter.Range.Replace("[Insert from option below]", string.Empty, false, false);
}
MemoryStream outStream = new MemoryStream();
doc_MngLetter.Save(outStream, SaveFormat.Docx);

public class ReplaceEvaluator : IReplacingCallback
{

    String[] newcontents;
    public ReplaceEvaluator(String[] contents)
    {
        newcontents = contents;
    }

    ReplaceAction IReplacingCallback.Replacing(ReplacingArgs e)
    {
        // This is a Run node that contains either the beginning or the complete match.
        Node currentNode = e.MatchNode;

        // The first (and may be the only) run can contain text before the match,
        // in this case it is necessary to split the run.
        if (e.MatchOffset > 0)
            currentNode = SplitRun((Run)currentNode, e.MatchOffset);

        ArrayList runs = new ArrayList();

        // Find all runs that contain parts of the match string.
        int remainingLength = e.Match.Value.Length;
        while (
        (remainingLength > 0) &&
        (currentNode != null) &&
        (currentNode.GetText().Length <= remainingLength))
        {
            runs.Add(currentNode);
            remainingLength = remainingLength - currentNode.GetText().Length;

            // Select the next Run node.
            // Have to loop because there could be other nodes such as BookmarkStart etc.
            do
            {
                currentNode = currentNode.NextSibling;
            }
            while ((currentNode != null) && (currentNode.NodeType != NodeType.Run));
        }

        // Split the last run that contains the match if there is any text left.
        if ((currentNode != null) && (remainingLength > 0))
        {
            SplitRun((Run)currentNode, remainingLength);
            runs.Add(currentNode);
        }

        // Create Document Buidler
        DocumentBuilder builder = new DocumentBuilder(e.MatchNode.Document as Document);

        builder.MoveTo((Run)runs[runs.Count - 1]);
        builder.Write(newcontents[0]);
        builder.Font.Bold = true;
        builder.Write(ControlChar.LineBreak + ControlChar.LineBreak + newcontents[1]);
        builder.Font.Bold = false;
        builder.Writeln(newcontents[2]);
        builder.Writeln(newcontents[3]);
        builder.Font.Italic = true;
        builder.Writeln(newcontents[4]);
        builder.Font.Italic = false;
        builder.Writeln(newcontents[5]);

        foreach (Run run in runs)
            run.Remove();

        // Signal to the replace engine to do nothing because we have already done all what we wanted.
        return ReplaceAction.Skip;
    }

    private static Run SplitRun(Run run, int position)
    {
        Run afterRun = (Run)run.Clone(true);
        afterRun.Text = run.Text.Substring(position);
        run.Text = run.Text.Substring(0, position);
        run.ParentNode.InsertAfter(afterRun, run);
        return afterRun;
    }
}

Hi Tahir,

I tried the same example that u have given but with a different template which contains more paragraphs. When i executed this it is replacing the given text and formating but it is removing all the data that was there on the file and just adding these 2 lines repeatedly on the word document . Attached the file.

Hi Harish,

Thanks for your inquiry. To ensure a timely and accurate response, please attach the following resources here for testing:

  • Your input Word document. If Management Letter.docx is your input document, no need to share it.
  • Please attach the output Word file that shows the undesired behavior.
  • Please attach your target Word document showing the desired behavior. You can use Microsoft Word to create your target Word document. We will investigate as to how you are expecting your final document be generated like.
  • Please create a standalone console application (source code without compilation errors) that helps us reproduce your problem on our end and attach it here for testing.

As soon as you get these pieces of information ready, we’ll start investigation into your issue and provide you more information. Thanks for your cooperation.

PS: To attach these resources, please zip them and Click ‘Reply’ button that will bring you to the ‘reply page’ and there at the bottom you can include any attachments with that post by clicking the ‘Add/Update’ button.

Hi

Attached the required input template and desired output documents along with the code that i am working. Help me to achieve this. I have got the bold highlighting now by doing some manipulations to your find and highlight code, but couldnt achieve the list numbering in roman numbers.

Hi Harish,

Thanks for sharing the document. Your code contains compile time errors. Please share the console application without compilations errors.

Regarding replacing text with list items, you need to use the same code example shared here. Please write your new code at the place of highlighted code snippet.

Please share the text from your template document (Management Letter.docx) which you want to replace with list items having multiple paragraphs. We will then provide you more information on this along with code example.