Search code examples
c#replacems-wordoffice-interopoffice-automation

microsoft.office.interop.word replace table text inside shape


I'm using microsoft.office.interop.word to replace( table cells text ) and I'm keeping this table inside shape, I'm trying to replace the text which is inside this table but the Problem when replacing is done the Table Format is removing and rows is merging like photo below. Please I need to fix my code somehow to keep formatting after replacing text

original doc enter image description here

output doc enter image description here

I'm using this code:

    private void FindAndReplace(Word.Application wordApp, object ToFindText, object replaceWithText)
    {

        object matchCase = true;
        object matchWholeWord = true;
        object matchWildCards = false;
        object matchSoundLike = false;
        object nmatchAllforms = false;
        object forward = true;
        object format = false;
        object matchKashida = false;
        object matchDiactitics = false;
        object matchAlefHamza = false;
        object matchControl = false;
        object read_only = false;
        object visible = true;
        object replace = 2;
        object wrap = 1;
        int x = 0;
        var shapes = myWordDoc.Shapes;
        foreach (Microsoft.Office.Interop.Word.Shape shape in shapes)
        {
            if (shape.TextFrame.HasText != 0)
            {
                var initialText = shape.TextFrame.TextRange.Text;
                var resultingText = initialText.Replace(ToFindText.ToString(), replaceWithText.ToString());
                if (initialText != resultingText)
                {
                    shape.TextFrame.TextRange.Text = resultingText;
                }
            }
        }
        wordApp.Selection.Find.Execute(ref ToFindText,
           ref matchCase, ref matchWholeWord,
           ref matchWildCards, ref matchSoundLike,
           ref nmatchAllforms, ref forward,
           ref wrap, ref format, ref replaceWithText,
           ref replace, ref matchKashida,
           ref matchDiactitics, ref matchAlefHamza,
           ref matchControl);
    }
    private void CreateWordDocument(object filename, object SaveAs)
    {
        try
        {

            Word.Application wordApp = new Word.Application();
            object missing = Missing.Value;
            if (File.Exists((string)filename))
            {
                object readOnly = false;
                object isVisible = false;
                wordApp.Visible = false;
                myWordDoc = wordApp.Documents.Open(ref filename, ref missing, ref readOnly,
                                        ref missing, ref missing, ref missing,
                                        ref missing, ref missing, ref missing,
                                        ref missing, ref missing, ref missing,
                                        ref missing, ref missing, ref missing, ref missing);

                myWordDoc.Activate();

                wordApp.Application.Documents.Open(filename, ReadOnly: true, Visible: false);


                DataTable dtfees = DB.GetData("select fees from fees where feesid='" + 1 + "'");
                if (dtfees.Rows.Count > 1)
                {
                    string fees1 = dtfees.Rows[0][0].ToString();
                    string fees2 = dtfees.Rows[1][0].ToString();
                    string fees3 = dtfees.Rows[2][0].ToString();
                    string fees4 = dtfees.Rows[3][0].ToString();
                    this.FindAndReplace(wordApp, "tyfes1", fees1);
                    this.FindAndReplace(wordApp, "Tyfes2", fees2);
                    this.FindAndReplace(wordApp, "Tyfes3", fees3);


                }
                myWordDoc.SaveAs2(ref SaveAs, ref missing, ref missing, ref missing,
                  ref missing, ref missing, ref missing,
                  ref missing, ref missing, ref missing,
                  ref missing, ref missing, ref missing,
                  ref missing, ref missing, ref missing);

                myWordDoc.Close(Word.WdSaveOptions.wdDoNotSaveChanges);
            }
        }
        catch (Exception ex)
        {

        }


    }

Solution

  • The main thing wrong with your code is that whatever material (text/tables etc.) is in your shape, if the findText is in it and the replacement text is different from the find text, the entire content of the shape's TexTObject will be replaced by a string with no table, in this line

    shape.TextFrame.TextRange.Text = resultingText;
    

    Judging from the Find.Execute that's still in your code, I'm guessing that you tried to use the Find object to do the replace but couldn't work out how to get it to work just in the Shapes.

    If I have understood what you're doing, I think the following fairly simple change will work, but you will need to check the C# and test it.

    foreach (Microsoft.Office.Interop.Word.Shape shape in shapes)
            {
                if (shape.TextFrame.HasText != 0)
                {
                    shape.TextFrame.TextRange.Find.Execute(ref ToFindText,
                        ref matchCase, ref matchWholeWord,
                        ref matchWildCards, ref matchSoundLike,
                        ref nmatchAllforms, ref forward,
                        ref wrap, ref format, ref replaceWithText,
                        ref replace, ref matchKashida,
                        ref matchDiactitics, ref matchAlefHamza,
                        ref matchControl);
                }
            }